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.
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
26 #define BYTES_IN_WORD 4
27 #define PA_PAGESIZE 0x1000
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 *,
47 __attribute__ ((__unused__));
48 static INLINE unsigned long assemble_17 (unsigned int, 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,
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 */
78 /* The PA instruction set variants. */
79 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20};
81 /* HP PA-RISC relocation types */
83 enum hppa_reloc_field_selector_type
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
135 /* for compatibility */
136 enum hppa_reloc_field_selector_type_alt
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
158 enum hppa_reloc_expr_type
168 /* for compatibility */
169 enum hppa_reloc_expr_type_alt
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,
180 #define HPPA_WIDE (0) /* PSW W-bit, need to check! FIXME */
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
187 #define GET_FIELD(X, FROM, TO) \
188 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
190 #define GET_BIT(X, WHICH) \
191 GET_FIELD (X, WHICH, WHICH)
196 #define CATENATE(X, XSIZE, Y, YSIZE) \
197 (((X & MASK (XSIZE)) << YSIZE) | (Y & MASK (YSIZE)))
200 CATENATE (GET_BIT (X, 10), 1, GET_FIELD (X, 0, 9), 10)
202 /* Some functions to manipulate PA instructions. */
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
210 static INLINE unsigned long
214 return (int)(x >> (len - 1) ? (-1 << len) | x : x);
217 static INLINE unsigned int
221 return CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2);
225 dis_assemble_3 (x, r)
229 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
232 static INLINE unsigned int
236 return (((x & 0x1) << 5) + (32 - (y & 0x1f)));
239 static INLINE unsigned int
243 return CATENATE (CATENATE (y, 1, GET_BIT (x, 10), 1), 2,
244 GET_FIELD (x, 0, 9), 9);
248 dis_assemble_12 (as12, x, y)
252 *y = (as12 & 0x800) >> 11;
253 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
256 static INLINE unsigned long
260 /* Depends on PSW W-bit !*/
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);
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);
272 return sign_extend (temp, 16);
276 static INLINE unsigned long
277 assemble_16a (x, y, z)
278 unsigned int x, y, z;
280 /* Depends on PSW W-bit !*/
284 temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2,
285 CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12);
287 temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12);
289 return sign_extend ((temp << 2), 16);
292 static INLINE unsigned long
293 assemble_17 (x, y, z)
294 unsigned int x, y, z;
298 temp = CATENATE (CATENATE (z, 1, x, 5), 6,
299 CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11);
305 dis_assemble_17 (as17, x, y, z)
307 unsigned int *x, *y, *z;
310 *z = (as17 & 0x10000) >> 16;
311 *x = (as17 & 0x0f800) >> 11;
312 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
315 static INLINE unsigned long
321 temp = ((x & 1) << 20) |
323 ((x & 0xc000) >> 7) |
324 ((x & 0x1f0000) >> 14) |
325 ((x & 0x003000) >> 12);
326 return temp & 0x1fffff;
329 static INLINE unsigned long
330 assemble_22 (a,b,c,d)
331 unsigned int a,b,c,d;
335 temp = CATENATE (CATENATE (d, 1, a, 5), 6,
336 CATENATE (b, 5, ELEVEN (c), 11), 16);
338 return sign_extend (temp, 22);
342 dis_assemble_21 (as21, x)
343 unsigned int as21, *x;
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;
356 static INLINE unsigned int
360 unsigned int len_ones;
367 len_ones = (len_ones << 1) | 1;
375 sign_unext (x, len, result)
377 unsigned int *result;
379 unsigned int len_ones;
381 len_ones = ones (len);
383 *result = x & len_ones;
386 static INLINE unsigned long
387 low_sign_extend (x, len)
390 return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
394 low_sign_unext (x, len, result)
396 unsigned int *result;
401 unsigned int one_bit_at_len;
402 unsigned int len_ones;
404 len_ones = ones (len);
405 one_bit_at_len = 1 << (len - 1);
407 sign_unext (x, len, &temp);
408 sign = temp & one_bit_at_len;
411 rest = temp & (len_ones ^ one_bit_at_len);
414 *result = rest | sign;
417 /* Handle field selectors for PA instructions. */
419 static INLINE unsigned long
420 hppa_field_adjust (value, constant_value, r_field)
422 unsigned long constant_value;
423 unsigned short r_field;
427 case e_fsel: /* F : no change */
428 case e_nsel: /* N : no change */
429 value += constant_value;
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)
437 value = (value & 0xfffff800) >> 11;
440 case e_rssel: /* RS : Sign extend from bit 21 */
441 value += constant_value;
442 if (value & 0x00000400)
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;
454 case e_rsel: /* R : Set bits 0-20 to zero */
455 value += constant_value;
456 value = value & 0x7ff;
459 case e_ldsel: /* LD : Add 0x800, arithmetic shift
461 value += constant_value;
463 value = (value & 0xfffff800) >> 11;
466 case e_rdsel: /* RD : Set bits 0-20 to one */
467 value += constant_value;
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;
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);
489 /* PA-RISC OPCODES */
490 #define get_opcode(insn) ((insn) & 0xfc000000) >> 26
492 /* FIXME: this list is incomplete. It should also be an enumerated
493 type rather than #defines. */
532 /* Given a machine instruction, return its format.
534 FIXME: opcodes which do not map to a known format
535 should return an error of some sort. */
538 bfd_hppa_insn2fmt (insn)
542 unsigned char op = get_opcode (insn);
593 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
596 static INLINE unsigned long
597 hppa_rebuild_insn (abfd, insn, value, r_format)
601 unsigned long r_format;
603 unsigned long const_part;
604 unsigned long rebuilt_part;
612 const_part = insn & 0xffffe002;
613 dis_assemble_12 (value, &w1, &w);
614 rebuilt_part = (w1 << 2) | w;
615 return const_part | rebuilt_part;
622 const_part = insn & 0xffffe002;
623 dis_assemble_12 (value, &w1, &w);
624 rebuilt_part = (w1 << 2) | w;
625 return const_part | rebuilt_part;
632 const_part = insn & 0xffffc000;
633 low_sign_unext (value, 14, &ext);
634 return const_part | ext;
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;
651 const_part = insn & 0xffe00000;
652 dis_assemble_21 (value, &w);
653 return const_part | w;