2000-12-11 Fernando Nasser <fnasser@redhat.com>
[deliverable/binutils-gdb.git] / bfd / libhppa.h
CommitLineData
252b5132 1/* HP PA-RISC SOM object file format: definitions internal to BFD.
a1934524 2 Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 98, 99, 2000
5f771d47 3 Free Software Foundation, Inc.
252b5132
RH
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
edd21aca
AM
24#ifndef _LIBHPPA_H
25#define _LIBHPPA_H
252b5132
RH
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
252b5132 38/* The PA instruction set variants. */
9fd9378c 39enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
252b5132
RH
40
41/* HP PA-RISC relocation types */
42
43enum hppa_reloc_field_selector_type
44 {
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,
1560fbe4
JL
62 R_HPPA_RTSEL = 0x11,
63 R_HPPA_LTPSEL = 0x12,
64 R_HPPA_RTPSEL = 0x13
252b5132
RH
65 };
66
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
96
97/* for compatibility */
98enum hppa_reloc_field_selector_type_alt
99 {
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,
1560fbe4
JL
117 e_rtsel = R_HPPA_RTSEL,
118 e_ltpsel = R_HPPA_LTPSEL,
119 e_rtpsel = R_HPPA_RTPSEL
252b5132
RH
120 };
121
122enum hppa_reloc_expr_type
123 {
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
130 };
131
132/* for compatibility */
133enum hppa_reloc_expr_type_alt
134 {
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
141 };
142
143
37afc161
JL
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.
148
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).
152
153 The high order 10 bits contain parameter relocation information,
154 the low order 22 bits contain the constant offset. */
3f9b03b5
AM
155
156#define HPPA_R_ARG_RELOC(a) \
157 (((a) >> 22) & 0x3ff)
158#define HPPA_R_CONSTANT(a) \
7c30ac37 159 ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
3f9b03b5
AM
160#define HPPA_R_ADDEND(r, c) \
161 (((r) << 22) + ((c) & 0x3fffff))
252b5132 162
3f9b03b5 163
252b5132
RH
164/* Some functions to manipulate PA instructions. */
165
3f9b03b5 166/* Declare the functions with the unused attribute to avoid warnings. */
edd21aca
AM
167static INLINE int sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED;
168static INLINE int low_sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED;
169static INLINE int sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED;
170static INLINE int low_sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED;
171static INLINE int re_assemble_3 PARAMS ((int)) ATTRIBUTE_UNUSED;
172static INLINE int re_assemble_12 PARAMS ((int)) ATTRIBUTE_UNUSED;
173static INLINE int re_assemble_14 PARAMS ((int)) ATTRIBUTE_UNUSED;
174static INLINE int re_assemble_16 PARAMS ((int)) ATTRIBUTE_UNUSED;
175static INLINE int re_assemble_17 PARAMS ((int)) ATTRIBUTE_UNUSED;
176static INLINE int re_assemble_21 PARAMS ((int)) ATTRIBUTE_UNUSED;
177static INLINE int re_assemble_22 PARAMS ((int)) ATTRIBUTE_UNUSED;
178static INLINE bfd_signed_vma hppa_field_adjust
179 PARAMS ((bfd_vma, bfd_signed_vma,
180 enum hppa_reloc_field_selector_type_alt)) ATTRIBUTE_UNUSED;
181static INLINE int bfd_hppa_insn2fmt PARAMS ((bfd *, int)) ATTRIBUTE_UNUSED;
182static INLINE int hppa_rebuild_insn PARAMS ((int, int, int)) ATTRIBUTE_UNUSED;
183
184
185/* The *sign_extend functions are used to assemble various bitfields
186 taken from an instruction and return the resulting immediate
187 value. */
188
189static INLINE int
252b5132 190sign_extend (x, len)
edd21aca 191 int x, len;
252b5132 192{
edd21aca
AM
193 int signbit = (1 << (len - 1));
194 int mask = (signbit << 1) - 1;
3f9b03b5 195 return ((x & mask) ^ signbit) - signbit;
252b5132
RH
196}
197
edd21aca 198static INLINE int
3f9b03b5 199low_sign_extend (x, len)
edd21aca 200 int x, len;
252b5132 201{
3f9b03b5 202 return (x >> 1) - ((x & 1) << (len - 1));
252b5132
RH
203}
204
252b5132 205
edd21aca
AM
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. */
252b5132 209
edd21aca 210static INLINE int
3f9b03b5 211sign_unext (x, len)
edd21aca 212 int x, len;
252b5132 213{
edd21aca 214 int len_ones;
252b5132 215
edd21aca 216 len_ones = (1 << len) - 1;
252b5132 217
3f9b03b5 218 return x & len_ones;
252b5132
RH
219}
220
edd21aca 221static INLINE int
3f9b03b5 222low_sign_unext (x, len)
edd21aca 223 int x, len;
252b5132 224{
edd21aca
AM
225 int temp;
226 int sign;
252b5132 227
3f9b03b5 228 sign = (x >> (len-1)) & 1;
252b5132 229
3f9b03b5
AM
230 temp = sign_unext (x, len-1);
231
232 return (temp << 1) | sign;
252b5132
RH
233}
234
edd21aca
AM
235static INLINE int
236re_assemble_3 (as3)
237 int as3;
252b5132 238{
edd21aca 239 return (( (as3 & 4) << (13-2))
3f9b03b5 240 | ((as3 & 3) << (13+1)));
252b5132
RH
241}
242
edd21aca
AM
243static INLINE int
244re_assemble_12 (as12)
245 int as12;
252b5132 246{
edd21aca 247 return (( (as12 & 0x800) >> 11)
3f9b03b5
AM
248 | ((as12 & 0x400) >> (10 - 2))
249 | ((as12 & 0x3ff) << (1 + 2)));
250}
251
edd21aca
AM
252static INLINE int
253re_assemble_14 (as14)
254 int as14;
3f9b03b5 255{
edd21aca
AM
256 return (( (as14 & 0x1fff) << 1)
257 | ((as14 & 0x2000) >> 13));
258}
252b5132 259
edd21aca
AM
260static INLINE int
261re_assemble_16 (as16)
262 int as16;
263{
264 int s, t;
265
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);
3f9b03b5 270}
252b5132 271
edd21aca
AM
272static INLINE int
273re_assemble_17 (as17)
274 int as17;
3f9b03b5 275{
edd21aca 276 return (( (as17 & 0x10000) >> 16)
3f9b03b5
AM
277 | ((as17 & 0x0f800) << (16 - 11))
278 | ((as17 & 0x00400) >> (10 - 2))
279 | ((as17 & 0x003ff) << (1 + 2)));
280}
252b5132 281
edd21aca
AM
282static INLINE int
283re_assemble_21 (as21)
284 int as21;
3f9b03b5 285{
edd21aca 286 return (( (as21 & 0x100000) >> 20)
3f9b03b5
AM
287 | ((as21 & 0x0ffe00) >> 8)
288 | ((as21 & 0x000180) << 7)
289 | ((as21 & 0x00007c) << 14)
290 | ((as21 & 0x000003) << 12));
291}
252b5132 292
edd21aca
AM
293static INLINE int
294re_assemble_22 (as22)
295 int as22;
3f9b03b5 296{
edd21aca 297 return (( (as22 & 0x200000) >> 21)
3f9b03b5
AM
298 | ((as22 & 0x1f0000) << (21 - 16))
299 | ((as22 & 0x00f800) << (16 - 11))
300 | ((as22 & 0x000400) >> (10 - 2))
301 | ((as22 & 0x0003ff) << (1 + 2)));
252b5132
RH
302}
303
252b5132 304
3f9b03b5
AM
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.
308
309 LDIL L'start,%r1 ; put left part into r1
310 LDW R'start(%r1),%r2 ; add r1 and right part to form address
311
312 This function returns sign extended values in all cases.
313*/
314
315static INLINE bfd_signed_vma
316hppa_field_adjust (sym_val, addend, r_field)
edd21aca 317 bfd_vma sym_val;
3f9b03b5
AM
318 bfd_signed_vma addend;
319 enum hppa_reloc_field_selector_type_alt r_field;
252b5132 320{
3f9b03b5
AM
321 bfd_signed_vma value;
322
323 value = sym_val + addend;
252b5132
RH
324 switch (r_field)
325 {
3f9b03b5 326 case e_fsel:
3f9b03b5 327 /* F: No change. */
252b5132
RH
328 break;
329
edd21aca
AM
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;
338
3f9b03b5
AM
339 case e_lsel:
340 case e_nlsel:
341 /* L: Select top 21 bits. */
342 value = value >> 11;
252b5132
RH
343 break;
344
3f9b03b5
AM
345 case e_rsel:
346 /* R: Select bottom 11 bits. */
347 value = value & 0x7ff;
252b5132
RH
348 break;
349
3f9b03b5
AM
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;
252b5132
RH
354 break;
355
3f9b03b5
AM
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;
252b5132
RH
362 break;
363
3f9b03b5
AM
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;
252b5132
RH
370 break;
371
3f9b03b5
AM
372 case e_rdsel:
373 /* RD: Set bits 0-20 to one. */
374 value = value | -0x800;
252b5132
RH
375 break;
376
3f9b03b5
AM
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;
252b5132
RH
382 break;
383
3f9b03b5
AM
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);
252b5132
RH
391 break;
392
393 default:
394 abort ();
395 }
396 return value;
252b5132
RH
397}
398
399/* PA-RISC OPCODES */
3f9b03b5 400#define get_opcode(insn) (((insn) >> 26) & 0x3f)
252b5132 401
edd21aca
AM
402enum hppa_opcode_type
403{
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,
431
432 OP_LDIL = 0x08,
433 OP_ADDIL = 0x0a,
434
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,
444
445 OP_LDD = 0x14,
446 OP_STD = 0x1c,
447
448 OP_FLDW = 0x16,
449 OP_LDWL = 0x17,
450 OP_FSTW = 0x1e,
451 OP_STWL = 0x1f,
452
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,
468
469 OP_COMICLR = 0x24,
470 OP_SUBI = 0x25,
471 OP_ADDIT = 0x2c,
472 OP_ADDI = 0x2d,
473
474 OP_BE = 0x38,
475 OP_BLE = 0x39,
476 OP_BL = 0x3a
477};
478
479
480/* Given a machine instruction, return its format. */
252b5132 481
7a7191b7 482static INLINE int
edd21aca
AM
483bfd_hppa_insn2fmt (abfd, insn)
484 bfd *abfd;
485 int insn;
252b5132 486{
edd21aca 487 enum hppa_opcode_type op = get_opcode (insn);
3f9b03b5 488
252b5132
RH
489 switch (op)
490 {
edd21aca
AM
491 case OP_COMICLR:
492 case OP_SUBI:
493 case OP_ADDIT:
494 case OP_ADDI:
3f9b03b5
AM
495 return 11;
496
edd21aca
AM
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:
3f9b03b5
AM
512 return 12;
513
edd21aca
AM
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. */
3f9b03b5
AM
525 return 14;
526
edd21aca
AM
527 case OP_FLDW:
528 case OP_LDWL:
529 case OP_FSTW:
530 case OP_STWL:
2667095f
JL
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
3f9b03b5 533 to describe the 11a format. */
edd21aca
AM
534 if (abfd->arch_info->mach >= 25)
535 return -16; /* Wide mode, format 16a. */
3f9b03b5
AM
536 return -11;
537
edd21aca
AM
538 case OP_LDD:
539 case OP_STD:
540 if (abfd->arch_info->mach >= 25)
541 return -10; /* Wide mode, format 10a. */
3f9b03b5
AM
542 return 10;
543
edd21aca
AM
544 case OP_BL:
545 if ((insn & 0x8000) != 0)
2667095f 546 return 22;
edd21aca
AM
547 /* fall thru */
548 case OP_BE:
549 case OP_BLE:
3f9b03b5
AM
550 return 17;
551
edd21aca
AM
552 case OP_LDIL:
553 case OP_ADDIL:
3f9b03b5
AM
554 return 21;
555
252b5132 556 default:
252b5132
RH
557 break;
558 }
3f9b03b5 559 return 32;
252b5132
RH
560}
561
562
563/* Insert VALUE into INSN using R_FORMAT to determine exactly what
564 bits to change. */
3f9b03b5 565
edd21aca
AM
566static INLINE int
567hppa_rebuild_insn (insn, value, r_format)
568 int insn;
569 int value;
570 int r_format;
252b5132 571{
252b5132
RH
572 switch (r_format)
573 {
edd21aca
AM
574 case 11:
575 return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
576
577 case 12:
578 return (insn & ~ 0x1ffd) | re_assemble_12 (value);
579
580
581 case 10:
582 return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
583
584 case -11:
585 return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
586
587 case 14:
588 return (insn & ~ 0x3fff) | re_assemble_14 (value);
589
590
591 case -10:
592 return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
593
594 case -16:
595 return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
596
597 case 16:
598 return (insn & ~ 0xffff) | re_assemble_16 (value);
599
600
601 case 17:
602 return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
603
604 case 21:
605 return (insn & ~ 0x1fffff) | re_assemble_21 (value);
606
607 case 22:
608 return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
609
610 case 32:
611 return value;
252b5132
RH
612
613 default:
614 abort ();
615 }
616 return insn;
617}
618
edd21aca 619#endif /* _LIBHPPA_H */
This page took 0.098589 seconds and 4 git commands to generate.