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