Automatic date update in version.in
[external/binutils.git] / bfd / libhppa.h
1 /* HP PA-RISC SOM object file format:  definitions internal to BFD.
2    Copyright (C) 1990-2019 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.  */
31 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
32
33 /* HP PA-RISC relocation types */
34
35 enum 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 */
90 enum 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
114 enum 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 */
125 enum 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.  */
159 static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
160 static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
161 static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
162 static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
163 static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
164 static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
165 static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
166 static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
167 static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
168 static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
169 static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
170 static inline bfd_signed_vma hppa_field_adjust
171   (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
172   ATTRIBUTE_UNUSED;
173 static inline int bfd_hppa_insn2fmt (bfd *, int) ATTRIBUTE_UNUSED;
174 static 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
181 static inline int
182 sign_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
189 static inline int
190 low_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
200 static inline int
201 sign_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
210 static inline int
211 low_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
223 static inline int
224 re_assemble_3 (int as3)
225 {
226   return ((  (as3 & 4) << (13-2))
227           | ((as3 & 3) << (13+1)));
228 }
229
230 static inline int
231 re_assemble_12 (int as12)
232 {
233   return ((  (as12 & 0x800) >> 11)
234           | ((as12 & 0x400) >> (10 - 2))
235           | ((as12 & 0x3ff) << (1 + 2)));
236 }
237
238 static inline int
239 re_assemble_14 (int as14)
240 {
241   return ((  (as14 & 0x1fff) << 1)
242           | ((as14 & 0x2000) >> 13));
243 }
244
245 static inline int
246 re_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
256 static inline int
257 re_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
265 static inline int
266 re_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
275 static inline int
276 re_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
296 static inline bfd_signed_vma
297 hppa_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
382 enum 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
462 static inline int
463 bfd_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
544 static inline int
545 hppa_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 */