* libhppa.h (HPPA_R_ARG_RELOC): Delete.
[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 #define HPPA_WIDE              (0) /* PSW W-bit, need to check! FIXME */
181
182 /* These macros get bit fields using HP's numbering (MSB = 0),
183  * but note that "MASK" assumes that the LSB bits are what's
184  * wanted.
185  */
186 #ifndef GET_FIELD
187 #define GET_FIELD(X, FROM, TO) \
188   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
189 #endif  
190 #define GET_BIT(X, WHICH) \
191   GET_FIELD (X, WHICH, WHICH)
192
193 #define MASK(SIZE) \
194   (~((-1) << SIZE))
195   
196 #define CATENATE(X, XSIZE, Y, YSIZE) \
197   (((X & MASK (XSIZE)) << YSIZE) | (Y & MASK (YSIZE)))
198
199 #define ELEVEN(X) \
200   CATENATE (GET_BIT (X, 10), 1, GET_FIELD (X, 0, 9), 10)
201   
202 /* Some functions to manipulate PA instructions.  */
203
204 /* NOTE: these use the HP convention that f{1} is the _left_ most
205  *       bit (MSB) of f; they sometimes have to impose an assumption
206  *       about the size of a field; and as far as I can tell, most
207  *       aren't used.
208  */
209
210 static INLINE unsigned long
211 sign_extend (x, len)
212      unsigned int x, len;
213 {
214   return (int)(x >> (len - 1) ? (-1 << len) | x : x);
215 }
216
217 static INLINE unsigned int
218 assemble_3 (x)
219      unsigned int x;
220 {
221   return CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2);
222 }
223
224 static INLINE void
225 dis_assemble_3 (x, r)
226      unsigned int x;
227      unsigned int *r;
228 {
229   *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
230 }
231
232 static INLINE unsigned int
233 assemble_6 (x, y)
234      unsigned int x, y;
235 {
236   return (((x & 0x1) << 5) + (32 - (y & 0x1f)));
237 }
238
239 static INLINE unsigned int
240 assemble_12 (x, y)
241      unsigned int x, y;
242 {
243   return CATENATE (CATENATE (y, 1, GET_BIT (x, 10), 1), 2,
244                    GET_FIELD (x, 0, 9), 9);
245 }
246
247 static INLINE void
248 dis_assemble_12 (as12, x, y)
249      unsigned int as12;
250      unsigned int *x, *y;
251 {
252   *y = (as12 & 0x800) >> 11;
253   *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
254 }
255
256 static INLINE unsigned long
257 assemble_16 (x, y)
258      unsigned int x, y;
259 {
260   /* Depends on PSW W-bit !*/
261   unsigned int temp;
262
263   if (HPPA_WIDE)
264     temp = CATENATE (CATENATE (GET_BIT (y, 13), 1,
265                                (GET_BIT (y, 13) ^ GET_BIT (x, 0)), 1), 2,
266                      CATENATE ((GET_BIT (y, 13) ^ GET_BIT (x, 1)), 1,
267                                GET_FIELD (y, 0, 12), 13), 14);
268   else
269     temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, GET_BIT (y, 13), 1), 2,
270                      CATENATE (GET_BIT (y, 13), 1, GET_FIELD (y, 0, 12), 13), 14);
271
272   return sign_extend (temp, 16);
273 }
274
275
276 static INLINE unsigned long
277 assemble_16a (x, y, z)
278      unsigned int x, y, z;
279 {
280   /* Depends on PSW W-bit !*/
281   unsigned int temp;
282
283   if (HPPA_WIDE)
284     temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2,
285                      CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12);
286   else 
287       temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12);
288
289   return sign_extend ((temp << 2), 16);
290 }
291
292 static INLINE unsigned long
293 assemble_17 (x, y, z)
294      unsigned int x, y, z;
295 {
296   unsigned long temp;
297
298   temp = CATENATE (CATENATE (z, 1, x, 5), 6,
299                    CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11);
300   
301   return temp;
302 }
303
304 static INLINE void
305 dis_assemble_17 (as17, x, y, z)
306      unsigned int as17;
307      unsigned int *x, *y, *z;
308 {
309
310   *z = (as17 & 0x10000) >> 16;
311   *x = (as17 & 0x0f800) >> 11;
312   *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
313 }
314
315 static INLINE unsigned long
316 assemble_21 (x)
317      unsigned int x;
318 {
319   unsigned long temp;
320
321   temp = ((x & 1) << 20) |
322     ((x & 0xffe) << 8) |
323     ((x & 0xc000) >> 7) |
324     ((x & 0x1f0000) >> 14) |
325     ((x & 0x003000) >> 12);
326   return temp & 0x1fffff;
327 }
328
329 static INLINE unsigned long
330 assemble_22 (a,b,c,d)
331      unsigned int a,b,c,d;
332 {
333   unsigned long temp;
334   
335   temp = CATENATE (CATENATE (d, 1, a, 5), 6,
336                    CATENATE (b, 5, ELEVEN (c), 11), 16);
337
338   return sign_extend (temp, 22);
339 }
340
341 static INLINE void
342 dis_assemble_21 (as21, x)
343      unsigned int as21, *x;
344 {
345   unsigned long temp;
346
347
348   temp = (as21 & 0x100000) >> 20;
349   temp |= (as21 & 0x0ffe00) >> 8;
350   temp |= (as21 & 0x000180) << 7;
351   temp |= (as21 & 0x00007c) << 14;
352   temp |= (as21 & 0x000003) << 12;
353   *x = temp;
354 }
355
356 static INLINE unsigned int
357 ones (n)
358      int n;
359 {
360   unsigned int len_ones;
361   int i;
362
363   i = 0;
364   len_ones = 0;
365   while (i < n)
366     {
367       len_ones = (len_ones << 1) | 1;
368       i++;
369     }
370
371   return len_ones;
372 }
373
374 static INLINE void
375 sign_unext (x, len, result)
376      unsigned int x, len;
377      unsigned int *result;
378 {
379   unsigned int len_ones;
380
381   len_ones = ones (len);
382
383   *result = x & len_ones;
384 }
385
386 static INLINE unsigned long
387 low_sign_extend (x, len)
388      unsigned int x, len;
389 {
390   return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
391 }
392
393 static INLINE void
394 low_sign_unext (x, len, result)
395      unsigned int x, len;
396      unsigned int *result;
397 {
398   unsigned int temp;
399   unsigned int sign;
400   unsigned int rest;
401   unsigned int one_bit_at_len;
402   unsigned int len_ones;
403
404   len_ones = ones (len);
405   one_bit_at_len = 1 << (len - 1);
406
407   sign_unext (x, len, &temp);
408   sign = temp & one_bit_at_len;
409   sign >>= (len - 1);
410
411   rest = temp & (len_ones ^ one_bit_at_len);
412   rest <<= 1;
413
414   *result = rest | sign;
415 }
416
417 /* Handle field selectors for PA instructions.  */
418
419 static INLINE unsigned long
420 hppa_field_adjust (value, constant_value, r_field)
421      unsigned long value;
422      unsigned long constant_value;
423      unsigned short r_field;
424 {
425   switch (r_field)
426     {
427     case e_fsel:                /* F  : no change                     */
428     case e_nsel:                /* N  : no change                      */
429       value += constant_value;
430       break;
431
432     case e_lssel:               /* LS : if (bit 21) then add 0x800
433                                    arithmetic shift right 11 bits */
434       value += constant_value;
435       if (value & 0x00000400)
436         value += 0x800;
437       value = (value & 0xfffff800) >> 11;
438       break;
439
440     case e_rssel:               /* RS : Sign extend from bit 21 */
441       value += constant_value;
442       if (value & 0x00000400)
443         value |= 0xfffff800;
444       else
445         value &= 0x7ff;
446       break;
447
448     case e_lsel:                /* L  : Arithmetic shift right 11 bits */
449     case e_nlsel:               /* NL  : Arithmetic shift right 11 bits */
450       value += constant_value;
451       value = (value & 0xfffff800) >> 11;
452       break;
453
454     case e_rsel:                /* R  : Set bits 0-20 to zero     */
455       value += constant_value;
456       value = value & 0x7ff;
457       break;
458
459     case e_ldsel:               /* LD : Add 0x800, arithmetic shift
460                                    right 11 bits                  */
461       value += constant_value;
462       value += 0x800;
463       value = (value & 0xfffff800) >> 11;
464       break;
465
466     case e_rdsel:               /* RD : Set bits 0-20 to one       */
467       value += constant_value;
468       value |= 0xfffff800;
469       break;
470
471     case e_lrsel:               /* LR : L with "rounded" constant      */
472     case e_nlrsel:              /* NLR : NL with "rounded" constant      */
473       value = value + ((constant_value + 0x1000) & 0xffffe000);
474       value = (value & 0xfffff800) >> 11;
475       break;
476
477     case e_rrsel:               /* RR : R with "rounded" constant      */
478       value = value + ((constant_value + 0x1000) & 0xffffe000);
479       value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
480       break;
481
482     default:
483       abort ();
484     }
485   return value;
486
487 }
488
489 /* PA-RISC OPCODES */
490 #define get_opcode(insn)        ((insn) & 0xfc000000) >> 26
491
492 /* FIXME: this list is incomplete.  It should also be an enumerated
493    type rather than #defines.  */
494
495 #define LDO     0x0d
496 #define LDB     0x10
497 #define LDH     0x11
498 #define LDW     0x12
499 #define LDWM    0x13
500 #define STB     0x18
501 #define STH     0x19
502 #define STW     0x1a
503 #define STWM    0x1b
504 #define COMICLR 0x24
505 #define SUBI    0x25
506 #define SUBIO   0x25
507 #define ADDIT   0x2c
508 #define ADDITO  0x2c
509 #define ADDI    0x2d
510 #define ADDIO   0x2d
511 #define LDIL    0x08
512 #define ADDIL   0x0a
513
514 #define MOVB    0x32
515 #define MOVIB   0x33
516 #define COMBT   0x20
517 #define COMBF   0x22
518 #define COMIBT  0x21
519 #define COMIBF  0x23
520 #define ADDBT   0x28
521 #define ADDBF   0x2a
522 #define ADDIBT  0x29
523 #define ADDIBF  0x2b
524 #define BVB     0x30
525 #define BB      0x31
526
527 #define BL      0x3a
528 #define BLE     0x39
529 #define BE      0x38
530
531   
532 /* Given a machine instruction, return its format.
533
534    FIXME:  opcodes which do not map to a known format
535    should return an error of some sort.  */
536
537 static INLINE char
538 bfd_hppa_insn2fmt (insn)
539      unsigned long insn;
540 {
541   char fmt = -1;
542   unsigned char op = get_opcode (insn);
543   
544   switch (op)
545     {
546     case ADDI:
547     case ADDIT:
548     case SUBI:
549       fmt = 11;
550       break;
551     case MOVB:
552     case MOVIB:
553     case COMBT:
554     case COMBF:
555     case COMIBT:
556     case COMIBF:
557     case ADDBT:
558     case ADDBF:
559     case ADDIBT:
560     case ADDIBF:
561     case BVB:
562     case BB:
563       fmt = 12;
564       break;
565     case LDO:
566     case LDB:
567     case LDH:
568     case LDW:
569     case LDWM:
570     case STB:
571     case STH:
572     case STW:
573     case STWM:
574       fmt = 14;
575       break;
576     case BL:
577     case BE:
578     case BLE:
579       fmt = 17;
580       break;
581     case LDIL:
582     case ADDIL:
583       fmt = 21;
584       break;
585     default:
586       fmt = 32;
587       break;
588     }
589   return fmt;
590 }
591
592
593 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
594    bits to change.  */
595    
596 static INLINE unsigned long
597 hppa_rebuild_insn (abfd, insn, value, r_format)
598      bfd *abfd;
599      unsigned long insn;
600      unsigned long value;
601      unsigned long r_format;
602 {
603   unsigned long const_part;
604   unsigned long rebuilt_part;
605
606   switch (r_format)
607     {
608     case 11:
609       {
610         unsigned w1, w;
611
612         const_part = insn & 0xffffe002;
613         dis_assemble_12 (value, &w1, &w);
614         rebuilt_part = (w1 << 2) | w;
615         return const_part | rebuilt_part;
616       }
617
618     case 12:
619       {
620         unsigned w1, w;
621
622         const_part = insn & 0xffffe002;
623         dis_assemble_12 (value, &w1, &w);
624         rebuilt_part = (w1 << 2) | w;
625         return const_part | rebuilt_part;
626       }
627
628     case 14:
629       {
630         unsigned int ext;
631         
632         const_part = insn & 0xffffc000;
633         low_sign_unext (value, 14, &ext);
634         return const_part | ext;
635       }
636
637     case 17:
638       {
639         unsigned w1, w2, w;
640
641         const_part = insn & 0xffe0e002;
642         dis_assemble_17 (value, &w1, &w2, &w);
643         rebuilt_part = (w2 << 2) | (w1 << 16) | w;
644         return const_part | rebuilt_part;
645       }
646
647     case 21:
648       {
649         unsigned int w;
650
651         const_part = insn & 0xffe00000;
652         dis_assemble_21 (value, &w);
653         return const_part | w;
654       }
655
656     case 32:
657       const_part = 0;
658       return value;
659
660     default:
661       abort ();
662     }
663   return insn;
664 }
665
666 #endif /* _HPPA_H */