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