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