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 (C) 1990, 91, 92, 93, 94, 95, 96, 98, 1999
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 _HPPA_H
25 #define _HPPA_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 #if __GNUC__ >= 2 && __GNUC_MINOR__ >= 7
39 /* Declare the functions with the unused attribute to avoid warnings.  */
40 static INLINE unsigned int assemble_3 (unsigned int)
41      __attribute__ ((__unused__));
42 static INLINE void dis_assemble_3 (unsigned int, unsigned int *)
43      __attribute__ ((__unused__));
44 static INLINE unsigned int assemble_12 (unsigned int, unsigned int)
45      __attribute__ ((__unused__));
46 static INLINE void dis_assemble_12 (unsigned int, unsigned int *,
47                                     unsigned int *)
48      __attribute__ ((__unused__));
49 static INLINE unsigned long assemble_17 (unsigned int, unsigned int,
50                                          unsigned int)
51      __attribute__ ((__unused__));
52 static INLINE void dis_assemble_17 (unsigned int, unsigned int *,
53                                     unsigned int *, unsigned int *)
54      __attribute__ ((__unused__));
55 static INLINE void dis_assemble_22 (unsigned int, unsigned int *,
56                                     unsigned int *, unsigned int *,
57                                     unsigned int *)
58      __attribute__ ((__unused__));
59 static INLINE unsigned long assemble_21 (unsigned int)
60      __attribute ((__unused__));
61 static INLINE void dis_assemble_21 (unsigned int, unsigned int *)
62      __attribute__ ((__unused__));
63 static INLINE unsigned long sign_extend (unsigned int, unsigned int)
64      __attribute__ ((__unused__));
65 static INLINE unsigned int ones (int) __attribute ((__unused__));
66 static INLINE void sign_unext (unsigned int, unsigned int, unsigned int *)
67      __attribute__ ((__unused__));
68 static INLINE unsigned long low_sign_extend (unsigned int, unsigned int)
69      __attribute__ ((__unused__));
70 static INLINE void low_sign_unext (unsigned int, unsigned int, unsigned int *)
71      __attribute__ ((__unused__));
72 static INLINE unsigned long hppa_field_adjust (unsigned long, unsigned long,
73                                                unsigned short)
74      __attribute__ ((__unused__));
75 static INLINE int bfd_hppa_insn2fmt (unsigned long)
76      __attribute__ ((__unused__));
77 static INLINE  unsigned long hppa_rebuild_insn (bfd *, unsigned long,
78                                                 unsigned long, unsigned long)
79      __attribute__ ((__unused__));
80 #endif /* gcc 2.7 or higher */
81
82
83 /* The PA instruction set variants.  */
84 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20};
85
86 /* HP PA-RISC relocation types */
87
88 enum hppa_reloc_field_selector_type
89   {
90     R_HPPA_FSEL = 0x0,
91     R_HPPA_LSSEL = 0x1,
92     R_HPPA_RSSEL = 0x2,
93     R_HPPA_LSEL = 0x3,
94     R_HPPA_RSEL = 0x4,
95     R_HPPA_LDSEL = 0x5,
96     R_HPPA_RDSEL = 0x6,
97     R_HPPA_LRSEL = 0x7,
98     R_HPPA_RRSEL = 0x8,
99     R_HPPA_NSEL  = 0x9,
100     R_HPPA_NLSEL  = 0xa,
101     R_HPPA_NLRSEL  = 0xb,
102     R_HPPA_PSEL = 0xc,
103     R_HPPA_LPSEL = 0xd,
104     R_HPPA_RPSEL = 0xe,
105     R_HPPA_TSEL = 0xf,
106     R_HPPA_LTSEL = 0x10,
107     R_HPPA_RTSEL = 0x11,
108     R_HPPA_LTPSEL = 0x12,
109     R_HPPA_RTPSEL = 0x13
110   };
111
112 /* /usr/include/reloc.h defines these to constants.  We want to use
113    them in enums, so #undef them before we start using them.  We might
114    be able to fix this another way by simply managing not to include
115    /usr/include/reloc.h, but currently GDB picks up these defines
116    somewhere.  */
117 #undef e_fsel
118 #undef e_lssel
119 #undef e_rssel
120 #undef e_lsel
121 #undef e_rsel
122 #undef e_ldsel
123 #undef e_rdsel
124 #undef e_lrsel
125 #undef e_rrsel
126 #undef e_nsel
127 #undef e_nlsel
128 #undef e_nlrsel
129 #undef e_psel
130 #undef e_lpsel
131 #undef e_rpsel
132 #undef e_tsel
133 #undef e_ltsel
134 #undef e_rtsel
135 #undef e_one
136 #undef e_two
137 #undef e_pcrel
138 #undef e_con
139 #undef e_plabel
140 #undef e_abs
141
142 /* for compatibility */
143 enum hppa_reloc_field_selector_type_alt
144   {
145     e_fsel = R_HPPA_FSEL,
146     e_lssel = R_HPPA_LSSEL,
147     e_rssel = R_HPPA_RSSEL,
148     e_lsel = R_HPPA_LSEL,
149     e_rsel = R_HPPA_RSEL,
150     e_ldsel = R_HPPA_LDSEL,
151     e_rdsel = R_HPPA_RDSEL,
152     e_lrsel = R_HPPA_LRSEL,
153     e_rrsel = R_HPPA_RRSEL,
154     e_nsel = R_HPPA_NSEL,
155     e_nlsel = R_HPPA_NLSEL,
156     e_nlrsel = R_HPPA_NLRSEL,
157     e_psel = R_HPPA_PSEL,
158     e_lpsel = R_HPPA_LPSEL,
159     e_rpsel = R_HPPA_RPSEL,
160     e_tsel = R_HPPA_TSEL,
161     e_ltsel = R_HPPA_LTSEL,
162     e_rtsel = R_HPPA_RTSEL,
163     e_ltpsel = R_HPPA_LTPSEL,
164     e_rtpsel = R_HPPA_RTPSEL
165   };
166
167 enum hppa_reloc_expr_type
168   {
169     R_HPPA_E_ONE = 0,
170     R_HPPA_E_TWO = 1,
171     R_HPPA_E_PCREL = 2,
172     R_HPPA_E_CON = 3,
173     R_HPPA_E_PLABEL = 7,
174     R_HPPA_E_ABS = 18
175   };
176
177 /* for compatibility */
178 enum hppa_reloc_expr_type_alt
179   {
180     e_one = R_HPPA_E_ONE,
181     e_two = R_HPPA_E_TWO,
182     e_pcrel = R_HPPA_E_PCREL,
183     e_con = R_HPPA_E_CON,
184     e_plabel = R_HPPA_E_PLABEL,
185     e_abs = R_HPPA_E_ABS
186   };
187
188
189 /* Relocations for function calls must be accompanied by parameter
190    relocation bits.  These bits describe exactly where the caller has
191    placed the function's arguments and where it expects to find a return
192    value.
193
194    Both ELF and SOM encode this information within the addend field
195    of the call relocation.  (Note this could break very badly if one
196    was to make a call like bl foo + 0x12345678).
197
198    The high order 10 bits contain parameter relocation information,
199    the low order 22 bits contain the constant offset.  */
200    
201 #define HPPA_R_ARG_RELOC(a)     (((a) >> 22) & 0x3FF)
202 #define HPPA_R_CONSTANT(a)      ((((int)(a)) << 10) >> 10)
203 #define HPPA_R_ADDEND(r,c)      (((r) << 22) + ((c) & 0x3FFFFF))
204 #define HPPA_WIDE              (0) /* PSW W-bit, need to check! FIXME */
205
206 /* These macros get bit fields using HP's numbering (MSB = 0),
207  * but note that "MASK" assumes that the LSB bits are what's
208  * wanted.
209  */
210 #ifndef GET_FIELD
211 #define GET_FIELD(X, FROM, TO) \
212   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
213 #endif  
214 #define GET_BIT(X, WHICH) \
215   GET_FIELD (X, WHICH, WHICH)
216
217 #define MASK(SIZE) \
218   (~((-1) << SIZE))
219   
220 #define CATENATE(X, XSIZE, Y, YSIZE) \
221   (((X & MASK (XSIZE)) << YSIZE) | (Y & MASK (YSIZE)))
222
223 #define ELEVEN(X) \
224   CATENATE (GET_BIT (X, 10), 1, GET_FIELD (X, 0, 9), 10)
225   
226 /* Some functions to manipulate PA instructions.  */
227
228 /* NOTE: these use the HP convention that f{1} is the _left_ most
229  *       bit (MSB) of f; they sometimes have to impose an assumption
230  *       about the size of a field; and as far as I can tell, most
231  *       aren't used.
232  */
233
234 static INLINE unsigned long
235 sign_extend (x, len)
236      unsigned int x, len;
237 {
238   return (int)(x >> (len - 1) ? (-1 << len) | x : x);
239 }
240
241 static INLINE unsigned int
242 assemble_3 (x)
243      unsigned int x;
244 {
245   return CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2);
246 }
247
248 static INLINE void
249 dis_assemble_3 (x, r)
250      unsigned int x;
251      unsigned int *r;
252 {
253   *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
254 }
255
256 static INLINE unsigned int
257 assemble_6 (x, y)
258      unsigned int x, y;
259 {
260   return (((x & 0x1) << 5) + (32 - (y & 0x1f)));
261 }
262
263 static INLINE unsigned int
264 assemble_12 (x, y)
265      unsigned int x, y;
266 {
267   return CATENATE (CATENATE (y, 1, GET_BIT (x, 10), 1), 2,
268                    GET_FIELD (x, 0, 9), 9);
269 }
270
271 static INLINE void
272 dis_assemble_12 (as12, x, y)
273      unsigned int as12;
274      unsigned int *x, *y;
275 {
276   *y = (as12 & 0x800) >> 11;
277   *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
278 }
279
280 static INLINE unsigned long
281 assemble_16 (x, y)
282      unsigned int x, y;
283 {
284   /* Depends on PSW W-bit !*/
285   unsigned int temp;
286
287   if (HPPA_WIDE)
288     temp = CATENATE (CATENATE (GET_BIT (y, 13), 1,
289                                (GET_BIT (y, 13) ^ GET_BIT (x, 0)), 1), 2,
290                      CATENATE ((GET_BIT (y, 13) ^ GET_BIT (x, 1)), 1,
291                                GET_FIELD (y, 0, 12), 13), 14);
292   else
293     temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, GET_BIT (y, 13), 1), 2,
294                      CATENATE (GET_BIT (y, 13), 1, GET_FIELD (y, 0, 12), 13), 14);
295
296   return sign_extend (temp, 16);
297 }
298
299
300 static INLINE unsigned long
301 assemble_16a (x, y, z)
302      unsigned int x, y, z;
303 {
304   /* Depends on PSW W-bit !*/
305   unsigned int temp;
306
307   if (HPPA_WIDE)
308     temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2,
309                      CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12);
310   else 
311       temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12);
312
313   return sign_extend ((temp << 2), 16);
314 }
315
316 static INLINE unsigned long
317 assemble_17 (x, y, z)
318      unsigned int x, y, z;
319 {
320   unsigned long temp;
321
322   temp = CATENATE (CATENATE (z, 1, x, 5), 6,
323                    CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11);
324   
325   return temp;
326 }
327
328 static INLINE void
329 dis_assemble_17 (as17, x, y, z)
330      unsigned int as17;
331      unsigned int *x, *y, *z;
332 {
333
334   *z = (as17 & 0x10000) >> 16;
335   *x = (as17 & 0x0f800) >> 11;
336   *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
337 }
338
339 static INLINE void
340 dis_assemble_22 (as22, a, b, c, d)
341      unsigned int as22;
342      unsigned int *a, *b, *c, *d;
343 {
344
345   *d = (as22 & 0x200000) >> 21;
346   *a = (as22 & 0x1f0000) >> 16;
347   *b = (as22 & 0x0f800) >> 11;
348   *c = (((as22 & 0x00400) >> 10) | ((as22 & 0x3ff) << 1)) & 0x7ff;
349 }
350
351 static INLINE unsigned long
352 assemble_21 (x)
353      unsigned int x;
354 {
355   unsigned long temp;
356
357   temp = ((x & 1) << 20) |
358     ((x & 0xffe) << 8) |
359     ((x & 0xc000) >> 7) |
360     ((x & 0x1f0000) >> 14) |
361     ((x & 0x003000) >> 12);
362   return temp & 0x1fffff;
363 }
364
365 static INLINE unsigned long
366 assemble_22 (a,b,c,d)
367      unsigned int a,b,c,d;
368 {
369   unsigned long temp;
370   
371   temp = CATENATE (CATENATE (d, 1, a, 5), 6,
372                    CATENATE (b, 5, ELEVEN (c), 11), 16);
373
374   return sign_extend (temp, 22);
375 }
376
377 static INLINE void
378 dis_assemble_21 (as21, x)
379      unsigned int as21, *x;
380 {
381   unsigned long temp;
382
383
384   temp = (as21 & 0x100000) >> 20;
385   temp |= (as21 & 0x0ffe00) >> 8;
386   temp |= (as21 & 0x000180) << 7;
387   temp |= (as21 & 0x00007c) << 14;
388   temp |= (as21 & 0x000003) << 12;
389   *x = temp;
390 }
391
392 static INLINE unsigned int
393 ones (n)
394      int n;
395 {
396   unsigned int len_ones;
397   int i;
398
399   i = 0;
400   len_ones = 0;
401   while (i < n)
402     {
403       len_ones = (len_ones << 1) | 1;
404       i++;
405     }
406
407   return len_ones;
408 }
409
410 static INLINE void
411 sign_unext (x, len, result)
412      unsigned int x, len;
413      unsigned int *result;
414 {
415   unsigned int len_ones;
416
417   len_ones = ones (len);
418
419   *result = x & len_ones;
420 }
421
422 static INLINE unsigned long
423 low_sign_extend (x, len)
424      unsigned int x, len;
425 {
426   return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
427 }
428
429 static INLINE void
430 low_sign_unext (x, len, result)
431      unsigned int x, len;
432      unsigned int *result;
433 {
434   unsigned int temp;
435   unsigned int sign;
436   unsigned int rest;
437   unsigned int one_bit_at_len;
438   unsigned int len_ones;
439
440   len_ones = ones (len);
441   one_bit_at_len = 1 << (len - 1);
442
443   sign_unext (x, len, &temp);
444   sign = temp & one_bit_at_len;
445   sign >>= (len - 1);
446
447   rest = temp & (len_ones ^ one_bit_at_len);
448   rest <<= 1;
449
450   *result = rest | sign;
451 }
452
453 /* Handle field selectors for PA instructions.  */
454
455 static INLINE unsigned long
456 hppa_field_adjust (value, constant_value, r_field)
457      unsigned long value;
458      unsigned long constant_value;
459      unsigned short r_field;
460 {
461   switch (r_field)
462     {
463     case e_fsel:                /* F  : no change                     */
464     case e_nsel:                /* N  : no change                      */
465       value += constant_value;
466       break;
467
468     case e_lssel:               /* LS : if (bit 21) then add 0x800
469                                    arithmetic shift right 11 bits */
470       value += constant_value;
471       if (value & 0x00000400)
472         value += 0x800;
473       value = (value & 0xfffff800) >> 11;
474       break;
475
476     case e_rssel:               /* RS : Sign extend from bit 21 */
477       value += constant_value;
478       if (value & 0x00000400)
479         value |= 0xfffff800;
480       else
481         value &= 0x7ff;
482       break;
483
484     case e_lsel:                /* L  : Arithmetic shift right 11 bits */
485     case e_nlsel:               /* NL  : Arithmetic shift right 11 bits */
486       value += constant_value;
487       value = (value & 0xfffff800) >> 11;
488       break;
489
490     case e_rsel:                /* R  : Set bits 0-20 to zero     */
491       value += constant_value;
492       value = value & 0x7ff;
493       break;
494
495     case e_ldsel:               /* LD : Add 0x800, arithmetic shift
496                                    right 11 bits                  */
497       value += constant_value;
498       value += 0x800;
499       value = (value & 0xfffff800) >> 11;
500       break;
501
502     case e_rdsel:               /* RD : Set bits 0-20 to one       */
503       value += constant_value;
504       value |= 0xfffff800;
505       break;
506
507     case e_lrsel:               /* LR : L with "rounded" constant      */
508     case e_nlrsel:              /* NLR : NL with "rounded" constant      */
509       value = value + ((constant_value + 0x1000) & 0xffffe000);
510       value = (value & 0xfffff800) >> 11;
511       break;
512
513     case e_rrsel:               /* RR : R with "rounded" constant      */
514       value = value + ((constant_value + 0x1000) & 0xffffe000);
515       value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
516       break;
517
518     default:
519       abort ();
520     }
521   return value;
522
523 }
524
525 /* PA-RISC OPCODES */
526 #define get_opcode(insn)        ((insn) & 0xfc000000) >> 26
527
528 /* FIXME: this list is incomplete.  It should also be an enumerated
529    type rather than #defines.  */
530
531 #define LDO     0x0d
532 #define LDB     0x10
533 #define LDH     0x11
534 #define LDW     0x12
535 #define LDWM    0x13
536 #define STB     0x18
537 #define STH     0x19
538 #define STW     0x1a
539 #define STWM    0x1b
540 #define COMICLR 0x24
541 #define SUBI    0x25
542 #define SUBIO   0x25
543 #define ADDIT   0x2c
544 #define ADDITO  0x2c
545 #define ADDI    0x2d
546 #define ADDIO   0x2d
547 #define LDIL    0x08
548 #define ADDIL   0x0a
549
550 #define MOVB    0x32
551 #define MOVIB   0x33
552 #define COMBT   0x20
553 #define COMBF   0x22
554 #define COMIBT  0x21
555 #define COMIBF  0x23
556 #define ADDBT   0x28
557 #define ADDBF   0x2a
558 #define ADDIBT  0x29
559 #define ADDIBF  0x2b
560 #define BVB     0x30
561 #define BB      0x31
562
563 #define BL      0x3a
564 #define BLE     0x39
565 #define BE      0x38
566
567 #define CMPBDT  0x27
568 #define CMPBDF  0x2f
569 #define CMPIBD  0x3b
570 #define LDD     0x14
571 #define STD     0x1c
572 #define LDWL    0x17
573 #define STWL    0x1f
574 #define FDLW    0x16
575 #define FSTW    0x1e
576   
577 /* Given a machine instruction, return its format.
578
579    FIXME:  opcodes which do not map to a known format
580    should return an error of some sort.  */
581
582 static INLINE int
583 bfd_hppa_insn2fmt (insn)
584      unsigned long insn;
585 {
586   int fmt = -1;
587   unsigned char op = get_opcode (insn);
588   
589   switch (op)
590     {
591     case ADDI:
592     case ADDIT:
593     case SUBI:
594       fmt = 11;
595       break;
596     case MOVB:
597     case MOVIB:
598     case COMBT:
599     case COMBF:
600     case COMIBT:
601     case COMIBF:
602     case ADDBT:
603     case ADDBF:
604     case ADDIBT:
605     case ADDIBF:
606     case BVB:
607     case BB:
608     case CMPBDT:
609     case CMPBDF:
610     case CMPIBD:
611       fmt = 12;
612       break;
613     case LDO:
614     case LDB:
615     case LDH:
616     case LDW:
617     case LDWM:
618     case STB:
619     case STH:
620     case STW:
621     case STWM:
622       fmt = 14;
623       break;
624     case LDWL:
625     case STWL:
626     case FDLW:
627     case FSTW:
628       /* This is a hack.  Unfortunately, format 11 is already taken
629          and we're using integers rather than an enum, so it's hard
630          to describe the 10a format.  */
631       fmt = -11;
632       break;
633     case LDD:
634     case STD:
635       fmt = 10;
636       break;
637     case BL:
638     case BE:
639     case BLE:
640       if ((insn & 0x00008000) == 0x00008000)
641         return 22;
642       fmt = 17;
643       break;
644     case LDIL:
645     case ADDIL:
646       fmt = 21;
647       break;
648     default:
649       fmt = 32;
650       break;
651     }
652   return fmt;
653 }
654
655
656 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
657    bits to change.  */
658    
659 static INLINE unsigned long
660 hppa_rebuild_insn (abfd, insn, value, r_format)
661      bfd *abfd ATTRIBUTE_UNUSED;
662      unsigned long insn;
663      unsigned long value;
664      unsigned long r_format;
665 {
666   unsigned long const_part;
667   unsigned long rebuilt_part;
668
669   switch (r_format)
670     {
671     case 11:
672       {
673         unsigned w1, w;
674
675         const_part = insn & 0xffffe002;
676         dis_assemble_12 (value, &w1, &w);
677         rebuilt_part = (w1 << 2) | w;
678         return const_part | rebuilt_part;
679       }
680
681     case 12:
682       {
683         unsigned w1, w;
684
685         const_part = insn & 0xffffe002;
686         dis_assemble_12 (value, &w1, &w);
687         rebuilt_part = (w1 << 2) | w;
688         return const_part | rebuilt_part;
689       }
690
691     case 14:
692       {
693         unsigned int ext;
694         
695         const_part = insn & 0xffffc000;
696         low_sign_unext (value, 14, &ext);
697         return const_part | ext;
698       }
699
700     case 17:
701       {
702         unsigned w1, w2, w;
703
704         const_part = insn & 0xffe0e002;
705         dis_assemble_17 (value, &w1, &w2, &w);
706         rebuilt_part = (w2 << 2) | (w1 << 16) | w;
707         return const_part | rebuilt_part;
708       }
709
710     case 21:
711       {
712         unsigned int w;
713
714         const_part = insn & 0xffe00000;
715         dis_assemble_21 (value, &w);
716         return const_part | w;
717       }
718
719     case 32:
720       const_part = 0;
721       return value;
722
723     default:
724       abort ();
725     }
726   return insn;
727 }
728
729 #endif /* _HPPA_H */