2001-02-17 Philip Blundell <philb@gnu.org>
[binutils.git] / bfd / libhppa.h
blob8ef8f53b3688d50a2ab0f5307b4f797af38c8c4d
1 /* HP PA-RISC SOM object file format: definitions internal to BFD.
2 Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 98, 99, 2000
3 Free Software Foundation, Inc.
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
8 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
24 #ifndef _LIBHPPA_H
25 #define _LIBHPPA_H
27 #define BYTES_IN_WORD 4
28 #define PA_PAGESIZE 0x1000
30 #ifndef INLINE
31 #ifdef __GNUC__
32 #define INLINE inline
33 #else
34 #define INLINE
35 #endif /* GNU C? */
36 #endif /* INLINE */
38 /* The PA instruction set variants. */
39 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
41 /* HP PA-RISC relocation types */
43 enum hppa_reloc_field_selector_type
45 R_HPPA_FSEL = 0x0,
46 R_HPPA_LSSEL = 0x1,
47 R_HPPA_RSSEL = 0x2,
48 R_HPPA_LSEL = 0x3,
49 R_HPPA_RSEL = 0x4,
50 R_HPPA_LDSEL = 0x5,
51 R_HPPA_RDSEL = 0x6,
52 R_HPPA_LRSEL = 0x7,
53 R_HPPA_RRSEL = 0x8,
54 R_HPPA_NSEL = 0x9,
55 R_HPPA_NLSEL = 0xa,
56 R_HPPA_NLRSEL = 0xb,
57 R_HPPA_PSEL = 0xc,
58 R_HPPA_LPSEL = 0xd,
59 R_HPPA_RPSEL = 0xe,
60 R_HPPA_TSEL = 0xf,
61 R_HPPA_LTSEL = 0x10,
62 R_HPPA_RTSEL = 0x11,
63 R_HPPA_LTPSEL = 0x12,
64 R_HPPA_RTPSEL = 0x13
67 /* /usr/include/reloc.h defines these to constants. We want to use
68 them in enums, so #undef them before we start using them. We might
69 be able to fix this another way by simply managing not to include
70 /usr/include/reloc.h, but currently GDB picks up these defines
71 somewhere. */
72 #undef e_fsel
73 #undef e_lssel
74 #undef e_rssel
75 #undef e_lsel
76 #undef e_rsel
77 #undef e_ldsel
78 #undef e_rdsel
79 #undef e_lrsel
80 #undef e_rrsel
81 #undef e_nsel
82 #undef e_nlsel
83 #undef e_nlrsel
84 #undef e_psel
85 #undef e_lpsel
86 #undef e_rpsel
87 #undef e_tsel
88 #undef e_ltsel
89 #undef e_rtsel
90 #undef e_one
91 #undef e_two
92 #undef e_pcrel
93 #undef e_con
94 #undef e_plabel
95 #undef e_abs
97 /* for compatibility */
98 enum hppa_reloc_field_selector_type_alt
100 e_fsel = R_HPPA_FSEL,
101 e_lssel = R_HPPA_LSSEL,
102 e_rssel = R_HPPA_RSSEL,
103 e_lsel = R_HPPA_LSEL,
104 e_rsel = R_HPPA_RSEL,
105 e_ldsel = R_HPPA_LDSEL,
106 e_rdsel = R_HPPA_RDSEL,
107 e_lrsel = R_HPPA_LRSEL,
108 e_rrsel = R_HPPA_RRSEL,
109 e_nsel = R_HPPA_NSEL,
110 e_nlsel = R_HPPA_NLSEL,
111 e_nlrsel = R_HPPA_NLRSEL,
112 e_psel = R_HPPA_PSEL,
113 e_lpsel = R_HPPA_LPSEL,
114 e_rpsel = R_HPPA_RPSEL,
115 e_tsel = R_HPPA_TSEL,
116 e_ltsel = R_HPPA_LTSEL,
117 e_rtsel = R_HPPA_RTSEL,
118 e_ltpsel = R_HPPA_LTPSEL,
119 e_rtpsel = R_HPPA_RTPSEL
122 enum hppa_reloc_expr_type
124 R_HPPA_E_ONE = 0,
125 R_HPPA_E_TWO = 1,
126 R_HPPA_E_PCREL = 2,
127 R_HPPA_E_CON = 3,
128 R_HPPA_E_PLABEL = 7,
129 R_HPPA_E_ABS = 18
132 /* for compatibility */
133 enum hppa_reloc_expr_type_alt
135 e_one = R_HPPA_E_ONE,
136 e_two = R_HPPA_E_TWO,
137 e_pcrel = R_HPPA_E_PCREL,
138 e_con = R_HPPA_E_CON,
139 e_plabel = R_HPPA_E_PLABEL,
140 e_abs = R_HPPA_E_ABS
144 /* Relocations for function calls must be accompanied by parameter
145 relocation bits. These bits describe exactly where the caller has
146 placed the function's arguments and where it expects to find a return
147 value.
149 Both ELF and SOM encode this information within the addend field
150 of the call relocation. (Note this could break very badly if one
151 was to make a call like bl foo + 0x12345678).
153 The high order 10 bits contain parameter relocation information,
154 the low order 22 bits contain the constant offset. */
156 #define HPPA_R_ARG_RELOC(a) \
157 (((a) >> 22) & 0x3ff)
158 #define HPPA_R_CONSTANT(a) \
159 ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
160 #define HPPA_R_ADDEND(r, c) \
161 (((r) << 22) + ((c) & 0x3fffff))
164 /* Some functions to manipulate PA instructions. */
166 /* Declare the functions with the unused attribute to avoid warnings. */
167 static INLINE int sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED;
168 static INLINE int low_sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED;
169 static INLINE int sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED;
170 static INLINE int low_sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED;
171 static INLINE int re_assemble_3 PARAMS ((int)) ATTRIBUTE_UNUSED;
172 static INLINE int re_assemble_12 PARAMS ((int)) ATTRIBUTE_UNUSED;
173 static INLINE int re_assemble_14 PARAMS ((int)) ATTRIBUTE_UNUSED;
174 static INLINE int re_assemble_16 PARAMS ((int)) ATTRIBUTE_UNUSED;
175 static INLINE int re_assemble_17 PARAMS ((int)) ATTRIBUTE_UNUSED;
176 static INLINE int re_assemble_21 PARAMS ((int)) ATTRIBUTE_UNUSED;
177 static INLINE int re_assemble_22 PARAMS ((int)) ATTRIBUTE_UNUSED;
178 static INLINE bfd_signed_vma hppa_field_adjust
179 PARAMS ((bfd_vma, bfd_signed_vma,
180 enum hppa_reloc_field_selector_type_alt)) ATTRIBUTE_UNUSED;
181 static INLINE int bfd_hppa_insn2fmt PARAMS ((bfd *, int)) ATTRIBUTE_UNUSED;
182 static INLINE int hppa_rebuild_insn PARAMS ((int, int, int)) ATTRIBUTE_UNUSED;
185 /* The *sign_extend functions are used to assemble various bitfields
186 taken from an instruction and return the resulting immediate
187 value. */
189 static INLINE int
190 sign_extend (x, len)
191 int x, len;
193 int signbit = (1 << (len - 1));
194 int mask = (signbit << 1) - 1;
195 return ((x & mask) ^ signbit) - signbit;
198 static INLINE int
199 low_sign_extend (x, len)
200 int x, len;
202 return (x >> 1) - ((x & 1) << (len - 1));
206 /* The re_assemble_* functions prepare an immediate value for
207 insertion into an opcode. pa-risc uses all sorts of weird bitfields
208 in the instruction to hold the value. */
210 static INLINE int
211 sign_unext (x, len)
212 int x, len;
214 int len_ones;
216 len_ones = (1 << len) - 1;
218 return x & len_ones;
221 static INLINE int
222 low_sign_unext (x, len)
223 int x, len;
225 int temp;
226 int sign;
228 sign = (x >> (len-1)) & 1;
230 temp = sign_unext (x, len-1);
232 return (temp << 1) | sign;
235 static INLINE int
236 re_assemble_3 (as3)
237 int as3;
239 return (( (as3 & 4) << (13-2))
240 | ((as3 & 3) << (13+1)));
243 static INLINE int
244 re_assemble_12 (as12)
245 int as12;
247 return (( (as12 & 0x800) >> 11)
248 | ((as12 & 0x400) >> (10 - 2))
249 | ((as12 & 0x3ff) << (1 + 2)));
252 static INLINE int
253 re_assemble_14 (as14)
254 int as14;
256 return (( (as14 & 0x1fff) << 1)
257 | ((as14 & 0x2000) >> 13));
260 static INLINE int
261 re_assemble_16 (as16)
262 int as16;
264 int s, t;
266 /* Unusual 16-bit encoding, for wide mode only. */
267 t = (as16 << 1) & 0xffff;
268 s = (as16 & 0x8000);
269 return (t ^ s ^ (s >> 1)) | (s >> 15);
272 static INLINE int
273 re_assemble_17 (as17)
274 int as17;
276 return (( (as17 & 0x10000) >> 16)
277 | ((as17 & 0x0f800) << (16 - 11))
278 | ((as17 & 0x00400) >> (10 - 2))
279 | ((as17 & 0x003ff) << (1 + 2)));
282 static INLINE int
283 re_assemble_21 (as21)
284 int as21;
286 return (( (as21 & 0x100000) >> 20)
287 | ((as21 & 0x0ffe00) >> 8)
288 | ((as21 & 0x000180) << 7)
289 | ((as21 & 0x00007c) << 14)
290 | ((as21 & 0x000003) << 12));
293 static INLINE int
294 re_assemble_22 (as22)
295 int as22;
297 return (( (as22 & 0x200000) >> 21)
298 | ((as22 & 0x1f0000) << (21 - 16))
299 | ((as22 & 0x00f800) << (16 - 11))
300 | ((as22 & 0x000400) >> (10 - 2))
301 | ((as22 & 0x0003ff) << (1 + 2)));
305 /* Handle field selectors for PA instructions.
306 The L and R (and LS, RS etc.) selectors are used in pairs to form a
307 full 32 bit address. eg.
309 LDIL L'start,%r1 ; put left part into r1
310 LDW R'start(%r1),%r2 ; add r1 and right part to form address
312 This function returns sign extended values in all cases.
315 static INLINE bfd_signed_vma
316 hppa_field_adjust (sym_val, addend, r_field)
317 bfd_vma sym_val;
318 bfd_signed_vma addend;
319 enum hppa_reloc_field_selector_type_alt r_field;
321 bfd_signed_vma value;
323 value = sym_val + addend;
324 switch (r_field)
326 case e_fsel:
327 /* F: No change. */
328 break;
330 case e_nsel:
331 /* N: null selector. I don't really understand what this is all
332 about, but HP's documentation says "this indicates that zero
333 bits are to be used for the displacement on the instruction.
334 This fixup is used to identify three-instruction sequences to
335 access data (for importing shared library data)." */
336 value = 0;
337 break;
339 case e_lsel:
340 case e_nlsel:
341 /* L: Select top 21 bits. */
342 value = value >> 11;
343 break;
345 case e_rsel:
346 /* R: Select bottom 11 bits. */
347 value = value & 0x7ff;
348 break;
350 case e_lssel:
351 /* LS: Round to nearest multiple of 2048 then select top 21 bits. */
352 value = value + 0x400;
353 value = value >> 11;
354 break;
356 case e_rssel:
357 /* RS: Select bottom 11 bits for LS.
358 We need to return a value such that 2048 * LS'x + RS'x == x.
359 ie. RS'x = x - ((x + 0x400) & -0x800)
360 this is just a sign extension from bit 21. */
361 value = ((value & 0x7ff) ^ 0x400) - 0x400;
362 break;
364 case e_ldsel:
365 /* LD: Round to next multiple of 2048 then select top 21 bits.
366 Yes, if we are already on a multiple of 2048, we go up to the
367 next one. RD in this case will be -2048. */
368 value = value + 0x800;
369 value = value >> 11;
370 break;
372 case e_rdsel:
373 /* RD: Set bits 0-20 to one. */
374 value = value | -0x800;
375 break;
377 case e_lrsel:
378 case e_nlrsel:
379 /* LR: L with rounding of the addend to nearest 8k. */
380 value = sym_val + ((addend + 0x1000) & -0x2000);
381 value = value >> 11;
382 break;
384 case e_rrsel:
385 /* RR: R with rounding of the addend to nearest 8k.
386 We need to return a value such that 2048 * LR'x + RR'x == x
387 ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
388 . = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
389 . = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000) */
390 value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
391 break;
393 default:
394 abort ();
396 return value;
399 /* PA-RISC OPCODES */
400 #define get_opcode(insn) (((insn) >> 26) & 0x3f)
402 enum hppa_opcode_type
404 /* None of the opcodes in the first group generate relocs, so we
405 aren't too concerned about them. */
406 OP_SYSOP = 0x00,
407 OP_MEMMNG = 0x01,
408 OP_ALU = 0x02,
409 OP_NDXMEM = 0x03,
410 OP_SPOP = 0x04,
411 OP_DIAG = 0x05,
412 OP_FMPYADD = 0x06,
413 OP_UNDEF07 = 0x07,
414 OP_COPRW = 0x09,
415 OP_COPRDW = 0x0b,
416 OP_COPR = 0x0c,
417 OP_FLOAT = 0x0e,
418 OP_PRDSPEC = 0x0f,
419 OP_UNDEF15 = 0x15,
420 OP_UNDEF1d = 0x1d,
421 OP_FMPYSUB = 0x26,
422 OP_FPFUSED = 0x2e,
423 OP_SHEXDP0 = 0x34,
424 OP_SHEXDP1 = 0x35,
425 OP_SHEXDP2 = 0x36,
426 OP_UNDEF37 = 0x37,
427 OP_SHEXDP3 = 0x3c,
428 OP_SHEXDP4 = 0x3d,
429 OP_MULTMED = 0x3e,
430 OP_UNDEF3f = 0x3f,
432 OP_LDIL = 0x08,
433 OP_ADDIL = 0x0a,
435 OP_LDO = 0x0d,
436 OP_LDB = 0x10,
437 OP_LDH = 0x11,
438 OP_LDW = 0x12,
439 OP_LDWM = 0x13,
440 OP_STB = 0x18,
441 OP_STH = 0x19,
442 OP_STW = 0x1a,
443 OP_STWM = 0x1b,
445 OP_LDD = 0x14,
446 OP_STD = 0x1c,
448 OP_FLDW = 0x16,
449 OP_LDWL = 0x17,
450 OP_FSTW = 0x1e,
451 OP_STWL = 0x1f,
453 OP_COMBT = 0x20,
454 OP_COMIBT = 0x21,
455 OP_COMBF = 0x22,
456 OP_COMIBF = 0x23,
457 OP_CMPBDT = 0x27,
458 OP_ADDBT = 0x28,
459 OP_ADDIBT = 0x29,
460 OP_ADDBF = 0x2a,
461 OP_ADDIBF = 0x2b,
462 OP_CMPBDF = 0x2f,
463 OP_BVB = 0x30,
464 OP_BB = 0x31,
465 OP_MOVB = 0x32,
466 OP_MOVIB = 0x33,
467 OP_CMPIBD = 0x3b,
469 OP_COMICLR = 0x24,
470 OP_SUBI = 0x25,
471 OP_ADDIT = 0x2c,
472 OP_ADDI = 0x2d,
474 OP_BE = 0x38,
475 OP_BLE = 0x39,
476 OP_BL = 0x3a
480 /* Given a machine instruction, return its format. */
482 static INLINE int
483 bfd_hppa_insn2fmt (abfd, insn)
484 bfd *abfd;
485 int insn;
487 enum hppa_opcode_type op = get_opcode (insn);
489 switch (op)
491 case OP_COMICLR:
492 case OP_SUBI:
493 case OP_ADDIT:
494 case OP_ADDI:
495 return 11;
497 case OP_COMBT:
498 case OP_COMIBT:
499 case OP_COMBF:
500 case OP_COMIBF:
501 case OP_CMPBDT:
502 case OP_ADDBT:
503 case OP_ADDIBT:
504 case OP_ADDBF:
505 case OP_ADDIBF:
506 case OP_CMPBDF:
507 case OP_BVB:
508 case OP_BB:
509 case OP_MOVB:
510 case OP_MOVIB:
511 case OP_CMPIBD:
512 return 12;
514 case OP_LDO:
515 case OP_LDB:
516 case OP_LDH:
517 case OP_LDW:
518 case OP_LDWM:
519 case OP_STB:
520 case OP_STH:
521 case OP_STW:
522 case OP_STWM:
523 if (abfd->arch_info->mach >= 25)
524 return 16; /* Wide mode, format 16. */
525 return 14;
527 case OP_FLDW:
528 case OP_LDWL:
529 case OP_FSTW:
530 case OP_STWL:
531 /* This is a hack. Unfortunately, format 11 is already taken
532 and we're using integers rather than an enum, so it's hard
533 to describe the 11a format. */
534 if (abfd->arch_info->mach >= 25)
535 return -16; /* Wide mode, format 16a. */
536 return -11;
538 case OP_LDD:
539 case OP_STD:
540 if (abfd->arch_info->mach >= 25)
541 return -10; /* Wide mode, format 10a. */
542 return 10;
544 case OP_BL:
545 if ((insn & 0x8000) != 0)
546 return 22;
547 /* fall thru */
548 case OP_BE:
549 case OP_BLE:
550 return 17;
552 case OP_LDIL:
553 case OP_ADDIL:
554 return 21;
556 default:
557 break;
559 return 32;
563 /* Insert VALUE into INSN using R_FORMAT to determine exactly what
564 bits to change. */
566 static INLINE int
567 hppa_rebuild_insn (insn, value, r_format)
568 int insn;
569 int value;
570 int r_format;
572 switch (r_format)
574 case 11:
575 return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
577 case 12:
578 return (insn & ~ 0x1ffd) | re_assemble_12 (value);
581 case 10:
582 return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
584 case -11:
585 return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
587 case 14:
588 return (insn & ~ 0x3fff) | re_assemble_14 (value);
591 case -10:
592 return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
594 case -16:
595 return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
597 case 16:
598 return (insn & ~ 0xffff) | re_assemble_16 (value);
601 case 17:
602 return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
604 case 21:
605 return (insn & ~ 0x1fffff) | re_assemble_21 (value);
607 case 22:
608 return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
610 case 32:
611 return value;
613 default:
614 abort ();
616 return insn;
619 #endif /* _LIBHPPA_H */