* libhppa.h: Define HINLINE rather than INLINE. Define it to
[deliverable/binutils-gdb.git] / bfd / libhppa.h
1 /* HP PA-RISC SOM object file format: definitions internal to BFD.
2 Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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.
13
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.
18
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. */
22
23 #ifndef _HPPA_H
24 #define _HPPA_H
25
26 #define BYTES_IN_WORD 4
27 #define PA_PAGESIZE 0x1000
28
29 #ifndef HINLINE
30 #ifdef __GNUC__
31 #define HINLINE extern inline
32 #else
33 /* INLINE is defined in bfd.h. */
34 #define HINLINE static INLINE
35 #endif /* GNU C? */
36 #endif /* HINLINE */
37
38 /* The PA instruction set variants. */
39 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20};
40
41 /* HP PA-RISC relocation types */
42
43 enum 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,
62 R_HPPA_RTSEL = 0x11
63 };
64
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
79 #undef e_nsel
80 #undef e_nlsel
81 #undef e_nlrsel
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
95 /* for compatibility */
96 enum 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,
107 e_nsel = R_HPPA_NSEL,
108 e_nlsel = R_HPPA_NLSEL,
109 e_nlrsel = R_HPPA_NLRSEL,
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 };
117
118 enum 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 };
127
128 /* for compatibility */
129 enum 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
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
156 /* Some functions to manipulate PA instructions. */
157 HINLINE unsigned int
158 assemble_3 (x)
159 unsigned int x;
160 {
161 return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
162 }
163
164 HINLINE void
165 dis_assemble_3 (x, r)
166 unsigned int x;
167 unsigned int *r;
168 {
169 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
170 }
171
172 HINLINE unsigned int
173 assemble_12 (x, y)
174 unsigned int x, y;
175 {
176 return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff;
177 }
178
179 HINLINE void
180 dis_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 }
187
188 HINLINE unsigned long
189 assemble_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
201 HINLINE void
202 dis_assemble_17 (as17, x, y, z)
203 unsigned int as17;
204 unsigned int *x, *y, *z;
205 {
206
207 *z = (as17 & 0x10000) >> 16;
208 *x = (as17 & 0x0f800) >> 11;
209 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
210 }
211
212 HINLINE unsigned long
213 assemble_21 (x)
214 unsigned int x;
215 {
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
226 HINLINE void
227 dis_assemble_21 (as21, x)
228 unsigned int as21, *x;
229 {
230 unsigned long temp;
231
232
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 }
240
241 HINLINE unsigned long
242 sign_extend (x, len)
243 unsigned int x, len;
244 {
245 return (int)(x >> (len - 1) ? (-1 << len) | x : x);
246 }
247
248 HINLINE unsigned int
249 ones (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
266 HINLINE void
267 sign_unext (x, len, result)
268 unsigned int x, len;
269 unsigned int *result;
270 {
271 unsigned int len_ones;
272
273 len_ones = ones (len);
274
275 *result = x & len_ones;
276 }
277
278 HINLINE unsigned long
279 low_sign_extend (x, len)
280 unsigned int x, len;
281 {
282 return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
283 }
284
285 HINLINE void
286 low_sign_unext (x, len, result)
287 unsigned int x, len;
288 unsigned int *result;
289 {
290 unsigned int temp;
291 unsigned int sign;
292 unsigned int rest;
293 unsigned int one_bit_at_len;
294 unsigned int len_ones;
295
296 len_ones = ones (len);
297 one_bit_at_len = 1 << (len - 1);
298
299 sign_unext (x, len, &temp);
300 sign = temp & one_bit_at_len;
301 sign >>= (len - 1);
302
303 rest = temp & (len_ones ^ one_bit_at_len);
304 rest <<= 1;
305
306 *result = rest | sign;
307 }
308
309 /* Handle field selectors for PA instructions. */
310
311 HINLINE unsigned long
312 hppa_field_adjust (value, constant_value, r_field)
313 unsigned long value;
314 unsigned long constant_value;
315 unsigned short r_field;
316 {
317 switch (r_field)
318 {
319 case e_fsel: /* F : no change */
320 case e_nsel: /* N : no change */
321 value += constant_value;
322 break;
323
324 case e_lssel: /* LS : if (bit 21) then add 0x800
325 arithmetic shift right 11 bits */
326 value += constant_value;
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 */
333 value += constant_value;
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 */
341 case e_nlsel: /* NL : Arithmetic shift right 11 bits */
342 value += constant_value;
343 value = (value & 0xfffff800) >> 11;
344 break;
345
346 case e_rsel: /* R : Set bits 0-20 to zero */
347 value += constant_value;
348 value = value & 0x7ff;
349 break;
350
351 case e_ldsel: /* LD : Add 0x800, arithmetic shift
352 right 11 bits */
353 value += constant_value;
354 value += 0x800;
355 value = (value & 0xfffff800) >> 11;
356 break;
357
358 case e_rdsel: /* RD : Set bits 0-20 to one */
359 value += constant_value;
360 value |= 0xfffff800;
361 break;
362
363 case e_lrsel: /* LR : L with "rounded" constant */
364 case e_nlrsel: /* NLR : NL with "rounded" constant */
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 }
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
429 HINLINE char
430 bfd_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
488 HINLINE unsigned long
489 hppa_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
550 #endif /* _HPPA_H */
This page took 0.060419 seconds and 5 git commands to generate.