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