1/* HP PA-RISC SOM object file format:  definitions internal to BFD.
2   Copyright (C) 1990-2017 Free Software Foundation, Inc.
3
4   Contributed by the Center for Software Science at the
5   University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7   This file is part of BFD, the Binary File Descriptor library.
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22   MA 02110-1301, USA.  */
23
24#ifndef _LIBHPPA_H
25#define _LIBHPPA_H
26
27#define BYTES_IN_WORD 4
28#define PA_PAGESIZE 0x1000
29
30/* The PA instruction set variants.  */
31enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
32
33/* HP PA-RISC relocation types */
34
35enum hppa_reloc_field_selector_type
36  {
37    R_HPPA_FSEL = 0x0,
38    R_HPPA_LSSEL = 0x1,
39    R_HPPA_RSSEL = 0x2,
40    R_HPPA_LSEL = 0x3,
41    R_HPPA_RSEL = 0x4,
42    R_HPPA_LDSEL = 0x5,
43    R_HPPA_RDSEL = 0x6,
44    R_HPPA_LRSEL = 0x7,
45    R_HPPA_RRSEL = 0x8,
46    R_HPPA_NSEL  = 0x9,
47    R_HPPA_NLSEL  = 0xa,
48    R_HPPA_NLRSEL  = 0xb,
49    R_HPPA_PSEL = 0xc,
50    R_HPPA_LPSEL = 0xd,
51    R_HPPA_RPSEL = 0xe,
52    R_HPPA_TSEL = 0xf,
53    R_HPPA_LTSEL = 0x10,
54    R_HPPA_RTSEL = 0x11,
55    R_HPPA_LTPSEL = 0x12,
56    R_HPPA_RTPSEL = 0x13
57  };
58
59/* /usr/include/reloc.h defines these to constants.  We want to use
60   them in enums, so #undef them before we start using them.  We might
61   be able to fix this another way by simply managing not to include
62   /usr/include/reloc.h, but currently GDB picks up these defines
63   somewhere.  */
64#undef e_fsel
65#undef e_lssel
66#undef e_rssel
67#undef e_lsel
68#undef e_rsel
69#undef e_ldsel
70#undef e_rdsel
71#undef e_lrsel
72#undef e_rrsel
73#undef e_nsel
74#undef e_nlsel
75#undef e_nlrsel
76#undef e_psel
77#undef e_lpsel
78#undef e_rpsel
79#undef e_tsel
80#undef e_ltsel
81#undef e_rtsel
82#undef e_one
83#undef e_two
84#undef e_pcrel
85#undef e_con
86#undef e_plabel
87#undef e_abs
88
89/* for compatibility */
90enum hppa_reloc_field_selector_type_alt
91  {
92    e_fsel = R_HPPA_FSEL,
93    e_lssel = R_HPPA_LSSEL,
94    e_rssel = R_HPPA_RSSEL,
95    e_lsel = R_HPPA_LSEL,
96    e_rsel = R_HPPA_RSEL,
97    e_ldsel = R_HPPA_LDSEL,
98    e_rdsel = R_HPPA_RDSEL,
99    e_lrsel = R_HPPA_LRSEL,
100    e_rrsel = R_HPPA_RRSEL,
101    e_nsel = R_HPPA_NSEL,
102    e_nlsel = R_HPPA_NLSEL,
103    e_nlrsel = R_HPPA_NLRSEL,
104    e_psel = R_HPPA_PSEL,
105    e_lpsel = R_HPPA_LPSEL,
106    e_rpsel = R_HPPA_RPSEL,
107    e_tsel = R_HPPA_TSEL,
108    e_ltsel = R_HPPA_LTSEL,
109    e_rtsel = R_HPPA_RTSEL,
110    e_ltpsel = R_HPPA_LTPSEL,
111    e_rtpsel = R_HPPA_RTPSEL
112  };
113
114enum hppa_reloc_expr_type
115  {
116    R_HPPA_E_ONE = 0,
117    R_HPPA_E_TWO = 1,
118    R_HPPA_E_PCREL = 2,
119    R_HPPA_E_CON = 3,
120    R_HPPA_E_PLABEL = 7,
121    R_HPPA_E_ABS = 18
122  };
123
124/* for compatibility */
125enum hppa_reloc_expr_type_alt
126  {
127    e_one = R_HPPA_E_ONE,
128    e_two = R_HPPA_E_TWO,
129    e_pcrel = R_HPPA_E_PCREL,
130    e_con = R_HPPA_E_CON,
131    e_plabel = R_HPPA_E_PLABEL,
132    e_abs = R_HPPA_E_ABS
133  };
134
135
136/* Relocations for function calls must be accompanied by parameter
137   relocation bits.  These bits describe exactly where the caller has
138   placed the function's arguments and where it expects to find a return
139   value.
140
141   Both ELF and SOM encode this information within the addend field
142   of the call relocation.  (Note this could break very badly if one
143   was to make a call like bl foo + 0x12345678).
144
145   The high order 10 bits contain parameter relocation information,
146   the low order 22 bits contain the constant offset.  */
147
148#define HPPA_R_ARG_RELOC(a)	\
149  (((a) >> 22) & 0x3ff)
150#define HPPA_R_CONSTANT(a)	\
151  ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
152#define HPPA_R_ADDEND(r, c)	\
153  (((r) << 22) + ((c) & 0x3fffff))
154
155
156/* Some functions to manipulate PA instructions.  */
157
158/* Declare the functions with the unused attribute to avoid warnings.  */
159static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
160static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
161static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
162static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
163static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
164static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
165static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
166static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
167static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
168static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
169static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
170static inline bfd_signed_vma hppa_field_adjust
171  (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
172  ATTRIBUTE_UNUSED;
173static inline int bfd_hppa_insn2fmt (bfd *, int) ATTRIBUTE_UNUSED;
174static inline int hppa_rebuild_insn (int, int, int) ATTRIBUTE_UNUSED;
175
176
177/* The *sign_extend functions are used to assemble various bitfields
178   taken from an instruction and return the resulting immediate
179   value.  */
180
181static inline int
182sign_extend (int x, int len)
183{
184  int signbit = (1 << (len - 1));
185  int mask = (signbit << 1) - 1;
186  return ((x & mask) ^ signbit) - signbit;
187}
188
189static inline int
190low_sign_extend (int x, int len)
191{
192  return (x >> 1) - ((x & 1) << (len - 1));
193}
194
195
196/* The re_assemble_* functions prepare an immediate value for
197   insertion into an opcode. pa-risc uses all sorts of weird bitfields
198   in the instruction to hold the value.  */
199
200static inline int
201sign_unext (int x, int len)
202{
203  int len_ones;
204
205  len_ones = (1 << len) - 1;
206
207  return x & len_ones;
208}
209
210static inline int
211low_sign_unext (int x, int len)
212{
213  int temp;
214  int sign;
215
216  sign = (x >> (len-1)) & 1;
217
218  temp = sign_unext (x, len-1);
219
220  return (temp << 1) | sign;
221}
222
223static inline int
224re_assemble_3 (int as3)
225{
226  return ((  (as3 & 4) << (13-2))
227	  | ((as3 & 3) << (13+1)));
228}
229
230static inline int
231re_assemble_12 (int as12)
232{
233  return ((  (as12 & 0x800) >> 11)
234	  | ((as12 & 0x400) >> (10 - 2))
235	  | ((as12 & 0x3ff) << (1 + 2)));
236}
237
238static inline int
239re_assemble_14 (int as14)
240{
241  return ((  (as14 & 0x1fff) << 1)
242	  | ((as14 & 0x2000) >> 13));
243}
244
245static inline int
246re_assemble_16 (int as16)
247{
248  int s, t;
249
250  /* Unusual 16-bit encoding, for wide mode only.  */
251  t = (as16 << 1) & 0xffff;
252  s = (as16 & 0x8000);
253  return (t ^ s ^ (s >> 1)) | (s >> 15);
254}
255
256static inline int
257re_assemble_17 (int as17)
258{
259  return ((  (as17 & 0x10000) >> 16)
260	  | ((as17 & 0x0f800) << (16 - 11))
261	  | ((as17 & 0x00400) >> (10 - 2))
262	  | ((as17 & 0x003ff) << (1 + 2)));
263}
264
265static inline int
266re_assemble_21 (int as21)
267{
268  return ((  (as21 & 0x100000) >> 20)
269	  | ((as21 & 0x0ffe00) >> 8)
270	  | ((as21 & 0x000180) << 7)
271	  | ((as21 & 0x00007c) << 14)
272	  | ((as21 & 0x000003) << 12));
273}
274
275static inline int
276re_assemble_22 (int as22)
277{
278  return ((  (as22 & 0x200000) >> 21)
279	  | ((as22 & 0x1f0000) << (21 - 16))
280	  | ((as22 & 0x00f800) << (16 - 11))
281	  | ((as22 & 0x000400) >> (10 - 2))
282	  | ((as22 & 0x0003ff) << (1 + 2)));
283}
284
285
286/* Handle field selectors for PA instructions.
287   The L and R (and LS, RS etc.) selectors are used in pairs to form a
288   full 32 bit address.  eg.
289
290   LDIL	L'start,%r1		; put left part into r1
291   LDW	R'start(%r1),%r2	; add r1 and right part to form address
292
293   This function returns sign extended values in all cases.
294*/
295
296static inline bfd_signed_vma
297hppa_field_adjust (bfd_vma sym_val,
298		   bfd_signed_vma addend,
299		   enum hppa_reloc_field_selector_type_alt r_field)
300{
301  bfd_signed_vma value;
302
303  value = sym_val + addend;
304  switch (r_field)
305    {
306    case e_fsel:
307      /* F: No change.  */
308      break;
309
310    case e_nsel:
311      /* N: null selector.  I don't really understand what this is all
312	 about, but HP's documentation says "this indicates that zero
313	 bits are to be used for the displacement on the instruction.
314	 This fixup is used to identify three-instruction sequences to
315	 access data (for importing shared library data)."  */
316      value = 0;
317      break;
318
319    case e_lsel:
320    case e_nlsel:
321      /* L:  Select top 21 bits.  */
322      value = value >> 11;
323      break;
324
325    case e_rsel:
326      /* R:  Select bottom 11 bits.  */
327      value = value & 0x7ff;
328      break;
329
330    case e_lssel:
331      /* LS:  Round to nearest multiple of 2048 then select top 21 bits.  */
332      value = value + 0x400;
333      value = value >> 11;
334      break;
335
336    case e_rssel:
337      /* RS:  Select bottom 11 bits for LS.
338	 We need to return a value such that 2048 * LS'x + RS'x == x.
339	 ie. RS'x = x - ((x + 0x400) & -0x800)
340	 this is just a sign extension from bit 21.  */
341      value = ((value & 0x7ff) ^ 0x400) - 0x400;
342      break;
343
344    case e_ldsel:
345      /* LD:  Round to next multiple of 2048 then select top 21 bits.
346	 Yes, if we are already on a multiple of 2048, we go up to the
347	 next one.  RD in this case will be -2048.  */
348      value = value + 0x800;
349      value = value >> 11;
350      break;
351
352    case e_rdsel:
353      /* RD:  Set bits 0-20 to one.  */
354      value = value | -0x800;
355      break;
356
357    case e_lrsel:
358    case e_nlrsel:
359      /* LR:  L with rounding of the addend to nearest 8k.  */
360      value = sym_val + ((addend + 0x1000) & -0x2000);
361      value = value >> 11;
362      break;
363
364    case e_rrsel:
365      /* RR:  R with rounding of the addend to nearest 8k.
366	 We need to return a value such that 2048 * LR'x + RR'x == x
367	 ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
368	 .	  = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
369	 .	  = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000)  */
370      value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
371      break;
372
373    default:
374      abort ();
375    }
376  return value;
377}
378
379/* PA-RISC OPCODES */
380#define get_opcode(insn)	(((insn) >> 26) & 0x3f)
381
382enum hppa_opcode_type
383{
384  /* None of the opcodes in the first group generate relocs, so we
385     aren't too concerned about them.  */
386  OP_SYSOP   = 0x00,
387  OP_MEMMNG  = 0x01,
388  OP_ALU     = 0x02,
389  OP_NDXMEM  = 0x03,
390  OP_SPOP    = 0x04,
391  OP_DIAG    = 0x05,
392  OP_FMPYADD = 0x06,
393  OP_UNDEF07 = 0x07,
394  OP_COPRW   = 0x09,
395  OP_COPRDW  = 0x0b,
396  OP_COPR    = 0x0c,
397  OP_FLOAT   = 0x0e,
398  OP_PRDSPEC = 0x0f,
399  OP_UNDEF15 = 0x15,
400  OP_UNDEF1d = 0x1d,
401  OP_FMPYSUB = 0x26,
402  OP_FPFUSED = 0x2e,
403  OP_SHEXDP0 = 0x34,
404  OP_SHEXDP1 = 0x35,
405  OP_SHEXDP2 = 0x36,
406  OP_UNDEF37 = 0x37,
407  OP_SHEXDP3 = 0x3c,
408  OP_SHEXDP4 = 0x3d,
409  OP_MULTMED = 0x3e,
410  OP_UNDEF3f = 0x3f,
411
412  OP_LDIL    = 0x08,
413  OP_ADDIL   = 0x0a,
414
415  OP_LDO     = 0x0d,
416  OP_LDB     = 0x10,
417  OP_LDH     = 0x11,
418  OP_LDW     = 0x12,
419  OP_LDWM    = 0x13,
420  OP_STB     = 0x18,
421  OP_STH     = 0x19,
422  OP_STW     = 0x1a,
423  OP_STWM    = 0x1b,
424
425  OP_LDD     = 0x14,
426  OP_STD     = 0x1c,
427
428  OP_FLDW    = 0x16,
429  OP_LDWL    = 0x17,
430  OP_FSTW    = 0x1e,
431  OP_STWL    = 0x1f,
432
433  OP_COMBT   = 0x20,
434  OP_COMIBT  = 0x21,
435  OP_COMBF   = 0x22,
436  OP_COMIBF  = 0x23,
437  OP_CMPBDT  = 0x27,
438  OP_ADDBT   = 0x28,
439  OP_ADDIBT  = 0x29,
440  OP_ADDBF   = 0x2a,
441  OP_ADDIBF  = 0x2b,
442  OP_CMPBDF  = 0x2f,
443  OP_BVB     = 0x30,
444  OP_BB      = 0x31,
445  OP_MOVB    = 0x32,
446  OP_MOVIB   = 0x33,
447  OP_CMPIBD  = 0x3b,
448
449  OP_COMICLR = 0x24,
450  OP_SUBI    = 0x25,
451  OP_ADDIT   = 0x2c,
452  OP_ADDI    = 0x2d,
453
454  OP_BE      = 0x38,
455  OP_BLE     = 0x39,
456  OP_BL      = 0x3a
457};
458
459
460/* Given a machine instruction, return its format.  */
461
462static inline int
463bfd_hppa_insn2fmt (bfd *abfd, int insn)
464{
465  enum hppa_opcode_type op = (enum hppa_opcode_type) get_opcode (insn);
466
467  switch (op)
468    {
469    case OP_COMICLR:
470    case OP_SUBI:
471    case OP_ADDIT:
472    case OP_ADDI:
473      return 11;
474
475    case OP_COMBT:
476    case OP_COMIBT:
477    case OP_COMBF:
478    case OP_COMIBF:
479    case OP_CMPBDT:
480    case OP_ADDBT:
481    case OP_ADDIBT:
482    case OP_ADDBF:
483    case OP_ADDIBF:
484    case OP_CMPBDF:
485    case OP_BVB:
486    case OP_BB:
487    case OP_MOVB:
488    case OP_MOVIB:
489    case OP_CMPIBD:
490      return 12;
491
492    case OP_LDO:
493    case OP_LDB:
494    case OP_LDH:
495    case OP_LDW:
496    case OP_LDWM:
497    case OP_STB:
498    case OP_STH:
499    case OP_STW:
500    case OP_STWM:
501      if (abfd->arch_info->mach >= 25)
502	return 16;	/* Wide mode, format 16.  */
503      return 14;
504
505    case OP_FLDW:
506    case OP_LDWL:
507    case OP_FSTW:
508    case OP_STWL:
509      /* This is a hack.  Unfortunately, format 11 is already taken
510	 and we're using integers rather than an enum, so it's hard
511	 to describe the 11a format.  */
512      if (abfd->arch_info->mach >= 25)
513	return -16;	/* Wide mode, format 16a.  */
514      return -11;
515
516    case OP_LDD:
517    case OP_STD:
518      if (abfd->arch_info->mach >= 25)
519	return -10;	/* Wide mode, format 10a.  */
520      return 10;
521
522    case OP_BL:
523      if ((insn & 0x8000) != 0)
524	return 22;
525      /* fall thru */
526    case OP_BE:
527    case OP_BLE:
528      return 17;
529
530    case OP_LDIL:
531    case OP_ADDIL:
532      return 21;
533
534    default:
535      break;
536    }
537  return 32;
538}
539
540
541/* Insert VALUE into INSN using R_FORMAT to determine exactly what
542   bits to change.  */
543
544static inline int
545hppa_rebuild_insn (int insn, int value, int r_format)
546{
547  switch (r_format)
548    {
549    case 11:
550      return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
551
552    case 12:
553      return (insn & ~ 0x1ffd) | re_assemble_12 (value);
554
555
556    case 10:
557      return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
558
559    case -11:
560      return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
561
562    case 14:
563      return (insn & ~ 0x3fff) | re_assemble_14 (value);
564
565
566    case -10:
567      return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
568
569    case -16:
570      return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
571
572    case 16:
573      return (insn & ~ 0xffff) | re_assemble_16 (value);
574
575
576    case 17:
577      return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
578
579    case 21:
580      return (insn & ~ 0x1fffff) | re_assemble_21 (value);
581
582    case 22:
583      return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
584
585    case 32:
586      return value;
587
588    default:
589      abort ();
590    }
591  return insn;
592}
593
594#endif /* _LIBHPPA_H */
595