1999-06-27 H.J. Lu <hjl@gnu.org>
[deliverable/binutils-gdb.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 CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2);
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
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, GET_BIT (x, 10), 1), 2,
259 GET_FIELD (x, 0, 9), 9);
260 }
261
262 static INLINE void
263 dis_assemble_12 (as12, x, y)
264 unsigned int as12;
265 unsigned int *x, *y;
266 {
267 *y = (as12 & 0x800) >> 11;
268 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
269 }
270
271 static INLINE unsigned long
272 assemble_16 (x, y)
273 unsigned int x, y;
274 {
275 /* Depends on PSW W-bit !*/
276 unsigned int temp;
277
278 if (HPPA_WIDE)
279 temp = CATENATE (CATENATE (GET_BIT (y, 13), 1,
280 (GET_BIT (y, 13) ^ GET_BIT (x, 0)), 1), 2,
281 CATENATE ((GET_BIT (y, 13) ^ GET_BIT (x, 1)), 1,
282 GET_FIELD (y, 0, 12), 13), 14);
283 else
284 temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, GET_BIT (y, 13), 1), 2,
285 CATENATE (GET_BIT (y, 13), 1, GET_FIELD (y, 0, 12), 13), 14);
286
287 return sign_extend (temp, 16);
288 }
289
290
291 static INLINE unsigned long
292 assemble_16a (x, y, z)
293 unsigned int x, y, z;
294 {
295 /* Depends on PSW W-bit !*/
296 unsigned int temp;
297
298 if (HPPA_WIDE)
299 temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2,
300 CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12);
301 else
302 temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12);
303
304 return sign_extend ((temp << 2), 16);
305 }
306
307 static INLINE unsigned long
308 assemble_17 (x, y, z)
309 unsigned int x, y, z;
310 {
311 unsigned long temp;
312
313 temp = CATENATE (CATENATE (z, 1, x, 5), 6,
314 CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11);
315
316 return temp;
317 }
318
319 static INLINE void
320 dis_assemble_17 (as17, x, y, z)
321 unsigned int as17;
322 unsigned int *x, *y, *z;
323 {
324
325 *z = (as17 & 0x10000) >> 16;
326 *x = (as17 & 0x0f800) >> 11;
327 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
328 }
329
330 static INLINE unsigned long
331 assemble_21 (x)
332 unsigned int x;
333 {
334 unsigned long temp;
335
336 temp = ((x & 1) << 20) |
337 ((x & 0xffe) << 8) |
338 ((x & 0xc000) >> 7) |
339 ((x & 0x1f0000) >> 14) |
340 ((x & 0x003000) >> 12);
341 return temp & 0x1fffff;
342 }
343
344 static INLINE unsigned long
345 assemble_22 (a,b,c,d)
346 unsigned int a,b,c,d;
347 {
348 unsigned long temp;
349
350 temp = CATENATE (CATENATE (d, 1, a, 5), 6,
351 CATENATE (b, 5, ELEVEN (c), 11), 16);
352
353 return sign_extend (temp, 22);
354 }
355
356 static INLINE void
357 dis_assemble_21 (as21, x)
358 unsigned int as21, *x;
359 {
360 unsigned long temp;
361
362
363 temp = (as21 & 0x100000) >> 20;
364 temp |= (as21 & 0x0ffe00) >> 8;
365 temp |= (as21 & 0x000180) << 7;
366 temp |= (as21 & 0x00007c) << 14;
367 temp |= (as21 & 0x000003) << 12;
368 *x = temp;
369 }
370
371 static INLINE unsigned int
372 ones (n)
373 int n;
374 {
375 unsigned int len_ones;
376 int i;
377
378 i = 0;
379 len_ones = 0;
380 while (i < n)
381 {
382 len_ones = (len_ones << 1) | 1;
383 i++;
384 }
385
386 return len_ones;
387 }
388
389 static INLINE void
390 sign_unext (x, len, result)
391 unsigned int x, len;
392 unsigned int *result;
393 {
394 unsigned int len_ones;
395
396 len_ones = ones (len);
397
398 *result = x & len_ones;
399 }
400
401 static INLINE unsigned long
402 low_sign_extend (x, len)
403 unsigned int x, len;
404 {
405 return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
406 }
407
408 static INLINE void
409 low_sign_unext (x, len, result)
410 unsigned int x, len;
411 unsigned int *result;
412 {
413 unsigned int temp;
414 unsigned int sign;
415 unsigned int rest;
416 unsigned int one_bit_at_len;
417 unsigned int len_ones;
418
419 len_ones = ones (len);
420 one_bit_at_len = 1 << (len - 1);
421
422 sign_unext (x, len, &temp);
423 sign = temp & one_bit_at_len;
424 sign >>= (len - 1);
425
426 rest = temp & (len_ones ^ one_bit_at_len);
427 rest <<= 1;
428
429 *result = rest | sign;
430 }
431
432 /* Handle field selectors for PA instructions. */
433
434 static INLINE unsigned long
435 hppa_field_adjust (value, constant_value, r_field)
436 unsigned long value;
437 unsigned long constant_value;
438 unsigned short r_field;
439 {
440 switch (r_field)
441 {
442 case e_fsel: /* F : no change */
443 case e_nsel: /* N : no change */
444 value += constant_value;
445 break;
446
447 case e_lssel: /* LS : if (bit 21) then add 0x800
448 arithmetic shift right 11 bits */
449 value += constant_value;
450 if (value & 0x00000400)
451 value += 0x800;
452 value = (value & 0xfffff800) >> 11;
453 break;
454
455 case e_rssel: /* RS : Sign extend from bit 21 */
456 value += constant_value;
457 if (value & 0x00000400)
458 value |= 0xfffff800;
459 else
460 value &= 0x7ff;
461 break;
462
463 case e_lsel: /* L : Arithmetic shift right 11 bits */
464 case e_nlsel: /* NL : Arithmetic shift right 11 bits */
465 value += constant_value;
466 value = (value & 0xfffff800) >> 11;
467 break;
468
469 case e_rsel: /* R : Set bits 0-20 to zero */
470 value += constant_value;
471 value = value & 0x7ff;
472 break;
473
474 case e_ldsel: /* LD : Add 0x800, arithmetic shift
475 right 11 bits */
476 value += constant_value;
477 value += 0x800;
478 value = (value & 0xfffff800) >> 11;
479 break;
480
481 case e_rdsel: /* RD : Set bits 0-20 to one */
482 value += constant_value;
483 value |= 0xfffff800;
484 break;
485
486 case e_lrsel: /* LR : L with "rounded" constant */
487 case e_nlrsel: /* NLR : NL with "rounded" constant */
488 value = value + ((constant_value + 0x1000) & 0xffffe000);
489 value = (value & 0xfffff800) >> 11;
490 break;
491
492 case e_rrsel: /* RR : R with "rounded" constant */
493 value = value + ((constant_value + 0x1000) & 0xffffe000);
494 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
495 break;
496
497 default:
498 abort ();
499 }
500 return value;
501
502 }
503
504 /* PA-RISC OPCODES */
505 #define get_opcode(insn) ((insn) & 0xfc000000) >> 26
506
507 /* FIXME: this list is incomplete. It should also be an enumerated
508 type rather than #defines. */
509
510 #define LDO 0x0d
511 #define LDB 0x10
512 #define LDH 0x11
513 #define LDW 0x12
514 #define LDWM 0x13
515 #define STB 0x18
516 #define STH 0x19
517 #define STW 0x1a
518 #define STWM 0x1b
519 #define COMICLR 0x24
520 #define SUBI 0x25
521 #define SUBIO 0x25
522 #define ADDIT 0x2c
523 #define ADDITO 0x2c
524 #define ADDI 0x2d
525 #define ADDIO 0x2d
526 #define LDIL 0x08
527 #define ADDIL 0x0a
528
529 #define MOVB 0x32
530 #define MOVIB 0x33
531 #define COMBT 0x20
532 #define COMBF 0x22
533 #define COMIBT 0x21
534 #define COMIBF 0x23
535 #define ADDBT 0x28
536 #define ADDBF 0x2a
537 #define ADDIBT 0x29
538 #define ADDIBF 0x2b
539 #define BVB 0x30
540 #define BB 0x31
541
542 #define BL 0x3a
543 #define BLE 0x39
544 #define BE 0x38
545
546
547 /* Given a machine instruction, return its format.
548
549 FIXME: opcodes which do not map to a known format
550 should return an error of some sort. */
551
552 static INLINE char
553 bfd_hppa_insn2fmt (insn)
554 unsigned long insn;
555 {
556 char fmt = -1;
557 unsigned char op = get_opcode (insn);
558
559 switch (op)
560 {
561 case ADDI:
562 case ADDIT:
563 case SUBI:
564 fmt = 11;
565 break;
566 case MOVB:
567 case MOVIB:
568 case COMBT:
569 case COMBF:
570 case COMIBT:
571 case COMIBF:
572 case ADDBT:
573 case ADDBF:
574 case ADDIBT:
575 case ADDIBF:
576 case BVB:
577 case BB:
578 fmt = 12;
579 break;
580 case LDO:
581 case LDB:
582 case LDH:
583 case LDW:
584 case LDWM:
585 case STB:
586 case STH:
587 case STW:
588 case STWM:
589 fmt = 14;
590 break;
591 case BL:
592 case BE:
593 case BLE:
594 fmt = 17;
595 break;
596 case LDIL:
597 case ADDIL:
598 fmt = 21;
599 break;
600 default:
601 fmt = 32;
602 break;
603 }
604 return fmt;
605 }
606
607
608 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
609 bits to change. */
610
611 static INLINE unsigned long
612 hppa_rebuild_insn (abfd, insn, value, r_format)
613 bfd *abfd;
614 unsigned long insn;
615 unsigned long value;
616 unsigned long r_format;
617 {
618 unsigned long const_part;
619 unsigned long rebuilt_part;
620
621 switch (r_format)
622 {
623 case 11:
624 {
625 unsigned w1, w;
626
627 const_part = insn & 0xffffe002;
628 dis_assemble_12 (value, &w1, &w);
629 rebuilt_part = (w1 << 2) | w;
630 return const_part | rebuilt_part;
631 }
632
633 case 12:
634 {
635 unsigned w1, w;
636
637 const_part = insn & 0xffffe002;
638 dis_assemble_12 (value, &w1, &w);
639 rebuilt_part = (w1 << 2) | w;
640 return const_part | rebuilt_part;
641 }
642
643 case 14:
644 {
645 unsigned int ext;
646
647 const_part = insn & 0xffffc000;
648 low_sign_unext (value, 14, &ext);
649 return const_part | ext;
650 }
651
652 case 17:
653 {
654 unsigned w1, w2, w;
655
656 const_part = insn & 0xffe0e002;
657 dis_assemble_17 (value, &w1, &w2, &w);
658 rebuilt_part = (w2 << 2) | (w1 << 16) | w;
659 return const_part | rebuilt_part;
660 }
661
662 case 21:
663 {
664 unsigned int w;
665
666 const_part = insn & 0xffe00000;
667 dis_assemble_21 (value, &w);
668 return const_part | w;
669 }
670
671 case 32:
672 const_part = 0;
673 return value;
674
675 default:
676 abort ();
677 }
678 return insn;
679 }
680
681 #endif /* _HPPA_H */
This page took 0.042986 seconds and 4 git commands to generate.