* configure.tgt (sparc64-*-solaris2*): Delete.
[deliverable/binutils-gdb.git] / bfd / libhppa.h
CommitLineData
76c7e44d 1/* HP PA-RISC SOM object file format: definitions internal to BFD.
d3e572fe 2 Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
76c7e44d
SG
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
d9ad93bc 7 This file is part of BFD, the Binary File Descriptor library.
76c7e44d 8
d9ad93bc
KR
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.
76c7e44d 13
d9ad93bc
KR
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.
76c7e44d 18
d9ad93bc
KR
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
6c7b3090 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
76c7e44d 22
d9ad93bc
KR
23#ifndef _HPPA_H
24#define _HPPA_H
d325e28c 25
d9ad93bc 26#define BYTES_IN_WORD 4
85579659 27#define PA_PAGESIZE 0x1000
205d660d 28
1680791e 29#ifndef HINLINE
d9ad93bc 30#ifdef __GNUC__
1680791e 31#define HINLINE extern inline
d9ad93bc 32#else
1680791e
ILT
33/* INLINE is defined in bfd.h. */
34#define HINLINE static INLINE
d9ad93bc 35#endif /* GNU C? */
1680791e 36#endif /* HINLINE */
d325e28c 37
6c7b3090
JL
38/* The PA instruction set variants. */
39enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20};
40
d9ad93bc 41/* HP PA-RISC relocation types */
d325e28c 42
d9ad93bc
KR
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,
6c7b3090 54 R_HPPA_NSEL = 0x9,
1680791e
ILT
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
d9ad93bc 63 };
89c789f6 64
aef3ae9a
JK
65/* /usr/include/reloc.h defines these to constants. We want to use
66 them in enums, so #undef them before we start using them. We might
67 be able to fix this another way by simply managing not to include
68 /usr/include/reloc.h, but currently GDB picks up these defines
69 somewhere. */
70#undef e_fsel
71#undef e_lssel
72#undef e_rssel
73#undef e_lsel
74#undef e_rsel
75#undef e_ldsel
76#undef e_rdsel
77#undef e_lrsel
78#undef e_rrsel
6c7b3090 79#undef e_nsel
1680791e
ILT
80#undef e_nlsel
81#undef e_nlrsel
aef3ae9a
JK
82#undef e_psel
83#undef e_lpsel
84#undef e_rpsel
85#undef e_tsel
86#undef e_ltsel
87#undef e_rtsel
88#undef e_one
89#undef e_two
90#undef e_pcrel
91#undef e_con
92#undef e_plabel
93#undef e_abs
94
d9ad93bc
KR
95/* for compatibility */
96enum hppa_reloc_field_selector_type_alt
97 {
98 e_fsel = R_HPPA_FSEL,
99 e_lssel = R_HPPA_LSSEL,
100 e_rssel = R_HPPA_RSSEL,
101 e_lsel = R_HPPA_LSEL,
102 e_rsel = R_HPPA_RSEL,
103 e_ldsel = R_HPPA_LDSEL,
104 e_rdsel = R_HPPA_RDSEL,
105 e_lrsel = R_HPPA_LRSEL,
106 e_rrsel = R_HPPA_RRSEL,
6c7b3090 107 e_nsel = R_HPPA_NSEL,
1680791e
ILT
108 e_nlsel = R_HPPA_NLSEL,
109 e_nlrsel = R_HPPA_NLRSEL,
d9ad93bc
KR
110 e_psel = R_HPPA_PSEL,
111 e_lpsel = R_HPPA_LPSEL,
112 e_rpsel = R_HPPA_RPSEL,
113 e_tsel = R_HPPA_TSEL,
114 e_ltsel = R_HPPA_LTSEL,
115 e_rtsel = R_HPPA_RTSEL
116 };
89c789f6 117
d9ad93bc
KR
118enum hppa_reloc_expr_type
119 {
120 R_HPPA_E_ONE = 0,
121 R_HPPA_E_TWO = 1,
122 R_HPPA_E_PCREL = 2,
123 R_HPPA_E_CON = 3,
124 R_HPPA_E_PLABEL = 7,
125 R_HPPA_E_ABS = 18
126 };
d325e28c 127
d9ad93bc
KR
128/* for compatibility */
129enum hppa_reloc_expr_type_alt
130 {
131 e_one = R_HPPA_E_ONE,
132 e_two = R_HPPA_E_TWO,
133 e_pcrel = R_HPPA_E_PCREL,
134 e_con = R_HPPA_E_CON,
135 e_plabel = R_HPPA_E_PLABEL,
136 e_abs = R_HPPA_E_ABS
137 };
138
139
f6061456
JL
140/* Relocations for function calls must be accompanied by parameter
141 relocation bits. These bits describe exactly where the caller has
142 placed the function's arguments and where it expects to find a return
143 value.
144
145 Both ELF and SOM encode this information within the addend field
146 of the call relocation. (Note this could break very badly if one
147 was to make a call like bl foo + 0x12345678).
148
149 The high order 10 bits contain parameter relocation information,
150 the low order 22 bits contain the constant offset. */
151
152#define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF)
153#define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10)
154#define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF))
155
d9ad93bc 156/* Some functions to manipulate PA instructions. */
1680791e 157HINLINE unsigned int
d9ad93bc
KR
158assemble_3 (x)
159 unsigned int x;
160{
161 return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
162}
d325e28c 163
1680791e 164HINLINE void
d9ad93bc
KR
165dis_assemble_3 (x, r)
166 unsigned int x;
167 unsigned int *r;
168{
169 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
170}
89c789f6 171
1680791e 172HINLINE unsigned int
d9ad93bc
KR
173assemble_12 (x, y)
174 unsigned int x, y;
175{
176 return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
177}
89c789f6 178
1680791e 179HINLINE void
d9ad93bc
KR
180dis_assemble_12 (as12, x, y)
181 unsigned int as12;
182 unsigned int *x, *y;
183{
184 *y = (as12 & 0x800) >> 11;
185 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
186}
76c7e44d 187
1680791e 188HINLINE unsigned long
d9ad93bc
KR
189assemble_17 (x, y, z)
190 unsigned int x, y, z;
191{
192 unsigned long temp;
193
194 temp = ((z & 1) << 16) |
195 ((x & 0x1f) << 11) |
196 ((y & 1) << 10) |
197 ((y & 0x7fe) >> 1);
198 return temp & 0x1ffff;
199}
200
1680791e 201HINLINE void
d9ad93bc
KR
202dis_assemble_17 (as17, x, y, z)
203 unsigned int as17;
204 unsigned int *x, *y, *z;
205{
76c7e44d 206
d9ad93bc
KR
207 *z = (as17 & 0x10000) >> 16;
208 *x = (as17 & 0x0f800) >> 11;
209 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
210}
76c7e44d 211
1680791e 212HINLINE unsigned long
d9ad93bc
KR
213assemble_21 (x)
214 unsigned int x;
76c7e44d 215{
d9ad93bc
KR
216 unsigned long temp;
217
218 temp = ((x & 1) << 20) |
219 ((x & 0xffe) << 8) |
220 ((x & 0xc000) >> 7) |
221 ((x & 0x1f0000) >> 14) |
222 ((x & 0x003000) >> 12);
223 return temp & 0x1fffff;
224}
225
1680791e 226HINLINE void
d9ad93bc
KR
227dis_assemble_21 (as21, x)
228 unsigned int as21, *x;
76c7e44d 229{
d9ad93bc 230 unsigned long temp;
76c7e44d 231
76c7e44d 232
d9ad93bc
KR
233 temp = (as21 & 0x100000) >> 20;
234 temp |= (as21 & 0x0ffe00) >> 8;
235 temp |= (as21 & 0x000180) << 7;
236 temp |= (as21 & 0x00007c) << 14;
237 temp |= (as21 & 0x000003) << 12;
238 *x = temp;
239}
76c7e44d 240
1680791e 241HINLINE unsigned long
6c7b3090 242sign_extend (x, len)
d9ad93bc
KR
243 unsigned int x, len;
244{
6c7b3090 245 return (int)(x >> (len - 1) ? (-1 << len) | x : x);
d9ad93bc 246}
76c7e44d 247
1680791e 248HINLINE unsigned int
d9ad93bc
KR
249ones (n)
250 int n;
251{
252 unsigned int len_ones;
253 int i;
254
255 i = 0;
256 len_ones = 0;
257 while (i < n)
258 {
259 len_ones = (len_ones << 1) | 1;
260 i++;
261 }
262
263 return len_ones;
264}
265
1680791e 266HINLINE void
d9ad93bc
KR
267sign_unext (x, len, result)
268 unsigned int x, len;
269 unsigned int *result;
270{
271 unsigned int len_ones;
76c7e44d 272
d9ad93bc 273 len_ones = ones (len);
76c7e44d 274
d9ad93bc
KR
275 *result = x & len_ones;
276}
76c7e44d 277
1680791e 278HINLINE unsigned long
6c7b3090 279low_sign_extend (x, len)
d9ad93bc
KR
280 unsigned int x, len;
281{
6c7b3090 282 return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
d9ad93bc 283}
205d660d 284
1680791e 285HINLINE void
d9ad93bc
KR
286low_sign_unext (x, len, result)
287 unsigned int x, len;
288 unsigned int *result;
76c7e44d 289{
d9ad93bc
KR
290 unsigned int temp;
291 unsigned int sign;
292 unsigned int rest;
293 unsigned int one_bit_at_len;
294 unsigned int len_ones;
8568acaa 295
d9ad93bc
KR
296 len_ones = ones (len);
297 one_bit_at_len = 1 << (len - 1);
8568acaa 298
d9ad93bc
KR
299 sign_unext (x, len, &temp);
300 sign = temp & one_bit_at_len;
301 sign >>= (len - 1);
b2057735 302
d9ad93bc
KR
303 rest = temp & (len_ones ^ one_bit_at_len);
304 rest <<= 1;
8568acaa 305
d9ad93bc
KR
306 *result = rest | sign;
307}
8568acaa 308
d9ad93bc
KR
309/* Handle field selectors for PA instructions. */
310
1680791e 311HINLINE unsigned long
d9ad93bc
KR
312hppa_field_adjust (value, constant_value, r_field)
313 unsigned long value;
314 unsigned long constant_value;
315 unsigned short r_field;
8568acaa 316{
d9ad93bc
KR
317 switch (r_field)
318 {
319 case e_fsel: /* F : no change */
1680791e 320 case e_nsel: /* N : no change */
6c7b3090 321 value += constant_value;
d9ad93bc
KR
322 break;
323
324 case e_lssel: /* LS : if (bit 21) then add 0x800
325 arithmetic shift right 11 bits */
6c7b3090 326 value += constant_value;
d9ad93bc
KR
327 if (value & 0x00000400)
328 value += 0x800;
329 value = (value & 0xfffff800) >> 11;
330 break;
331
332 case e_rssel: /* RS : Sign extend from bit 21 */
6c7b3090 333 value += constant_value;
d9ad93bc
KR
334 if (value & 0x00000400)
335 value |= 0xfffff800;
336 else
337 value &= 0x7ff;
338 break;
339
340 case e_lsel: /* L : Arithmetic shift right 11 bits */
1680791e 341 case e_nlsel: /* NL : Arithmetic shift right 11 bits */
6c7b3090 342 value += constant_value;
d9ad93bc
KR
343 value = (value & 0xfffff800) >> 11;
344 break;
345
346 case e_rsel: /* R : Set bits 0-20 to zero */
6c7b3090 347 value += constant_value;
d9ad93bc
KR
348 value = value & 0x7ff;
349 break;
350
351 case e_ldsel: /* LD : Add 0x800, arithmetic shift
352 right 11 bits */
6c7b3090 353 value += constant_value;
d9ad93bc
KR
354 value += 0x800;
355 value = (value & 0xfffff800) >> 11;
356 break;
357
358 case e_rdsel: /* RD : Set bits 0-20 to one */
6c7b3090 359 value += constant_value;
d9ad93bc
KR
360 value |= 0xfffff800;
361 break;
362
363 case e_lrsel: /* LR : L with "rounded" constant */
1680791e 364 case e_nlrsel: /* NLR : NL with "rounded" constant */
d9ad93bc
KR
365 value = value + ((constant_value + 0x1000) & 0xffffe000);
366 value = (value & 0xfffff800) >> 11;
367 break;
368
369 case e_rrsel: /* RR : R with "rounded" constant */
370 value = value + ((constant_value + 0x1000) & 0xffffe000);
371 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
372 break;
373
374 default:
375 abort ();
376 }
377 return value;
378
379}
f6061456
JL
380
381/* PA-RISC OPCODES */
382#define get_opcode(insn) ((insn) & 0xfc000000) >> 26
383
384/* FIXME: this list is incomplete. It should also be an enumerated
385 type rather than #defines. */
386
387#define LDO 0x0d
388#define LDB 0x10
389#define LDH 0x11
390#define LDW 0x12
391#define LDWM 0x13
392#define STB 0x18
393#define STH 0x19
394#define STW 0x1a
395#define STWM 0x1b
396#define COMICLR 0x24
397#define SUBI 0x25
398#define SUBIO 0x25
399#define ADDIT 0x2c
400#define ADDITO 0x2c
401#define ADDI 0x2d
402#define ADDIO 0x2d
403#define LDIL 0x08
404#define ADDIL 0x0a
405
406#define MOVB 0x32
407#define MOVIB 0x33
408#define COMBT 0x20
409#define COMBF 0x22
410#define COMIBT 0x21
411#define COMIBF 0x23
412#define ADDBT 0x28
413#define ADDBF 0x2a
414#define ADDIBT 0x29
415#define ADDIBF 0x2b
416#define BVB 0x30
417#define BB 0x31
418
419#define BL 0x3a
420#define BLE 0x39
421#define BE 0x38
422
423
424/* Given a machine instruction, return its format.
425
426 FIXME: opcodes which do not map to a known format
427 should return an error of some sort. */
428
1680791e 429HINLINE char
f6061456
JL
430bfd_hppa_insn2fmt (insn)
431 unsigned long insn;
432{
433 char fmt = -1;
434 unsigned char op = get_opcode (insn);
435
436 switch (op)
437 {
438 case ADDI:
439 case ADDIT:
440 case SUBI:
441 fmt = 11;
442 break;
443 case MOVB:
444 case MOVIB:
445 case COMBT:
446 case COMBF:
447 case COMIBT:
448 case COMIBF:
449 case ADDBT:
450 case ADDBF:
451 case ADDIBT:
452 case ADDIBF:
453 case BVB:
454 case BB:
455 fmt = 12;
456 break;
457 case LDO:
458 case LDB:
459 case LDH:
460 case LDW:
461 case LDWM:
462 case STB:
463 case STH:
464 case STW:
465 case STWM:
466 fmt = 14;
467 break;
468 case BL:
469 case BE:
470 case BLE:
471 fmt = 17;
472 break;
473 case LDIL:
474 case ADDIL:
475 fmt = 21;
476 break;
477 default:
478 fmt = 32;
479 break;
480 }
481 return fmt;
482}
483
484
485/* Insert VALUE into INSN using R_FORMAT to determine exactly what
486 bits to change. */
487
1680791e 488HINLINE unsigned long
f6061456
JL
489hppa_rebuild_insn (abfd, insn, value, r_format)
490 bfd *abfd;
491 unsigned long insn;
492 unsigned long value;
493 unsigned long r_format;
494{
495 unsigned long const_part;
496 unsigned long rebuilt_part;
497
498 switch (r_format)
499 {
500 case 11:
501 {
502 unsigned w1, w;
503
504 const_part = insn & 0xffffe002;
505 dis_assemble_12 (value, &w1, &w);
506 rebuilt_part = (w1 << 2) | w;
507 return const_part | rebuilt_part;
508 }
509
510 case 12:
511 {
512 unsigned w1, w;
513
514 const_part = insn & 0xffffe002;
515 dis_assemble_12 (value, &w1, &w);
516 rebuilt_part = (w1 << 2) | w;
517 return const_part | rebuilt_part;
518 }
519
520 case 14:
521 const_part = insn & 0xffffc000;
522 low_sign_unext (value, 14, &rebuilt_part);
523 return const_part | rebuilt_part;
524
525 case 17:
526 {
527 unsigned w1, w2, w;
528
529 const_part = insn & 0xffe0e002;
530 dis_assemble_17 (value, &w1, &w2, &w);
531 rebuilt_part = (w2 << 2) | (w1 << 16) | w;
532 return const_part | rebuilt_part;
533 }
534
535 case 21:
536 const_part = insn & 0xffe00000;
537 dis_assemble_21 (value, &rebuilt_part);
538 return const_part | rebuilt_part;
539
540 case 32:
541 const_part = 0;
542 return value;
543
544 default:
545 abort ();
546 }
547 return insn;
548}
549
d9ad93bc 550#endif /* _HPPA_H */
This page took 0.153296 seconds and 4 git commands to generate.