Fix typo in last change.
[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, 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 */
This page took 0.073404 seconds and 5 git commands to generate.