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