1 /* HP PA-RISC SOM object file format: definitions internal to BFD.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
26 #define BYTES_IN_WORD 4
36 /* HP PA-RISC relocation types */
38 enum hppa_reloc_field_selector_type
57 /* /usr/include/reloc.h defines these to constants. We want to use
58 them in enums, so #undef them before we start using them. We might
59 be able to fix this another way by simply managing not to include
60 /usr/include/reloc.h, but currently GDB picks up these defines
84 /* for compatibility */
85 enum hppa_reloc_field_selector_type_alt
88 e_lssel
= R_HPPA_LSSEL
,
89 e_rssel
= R_HPPA_RSSEL
,
92 e_ldsel
= R_HPPA_LDSEL
,
93 e_rdsel
= R_HPPA_RDSEL
,
94 e_lrsel
= R_HPPA_LRSEL
,
95 e_rrsel
= R_HPPA_RRSEL
,
97 e_lpsel
= R_HPPA_LPSEL
,
98 e_rpsel
= R_HPPA_RPSEL
,
100 e_ltsel
= R_HPPA_LTSEL
,
101 e_rtsel
= R_HPPA_RTSEL
104 enum hppa_reloc_expr_type
114 /* for compatibility */
115 enum hppa_reloc_expr_type_alt
117 e_one
= R_HPPA_E_ONE
,
118 e_two
= R_HPPA_E_TWO
,
119 e_pcrel
= R_HPPA_E_PCREL
,
120 e_con
= R_HPPA_E_CON
,
121 e_plabel
= R_HPPA_E_PLABEL
,
126 /* Some functions to manipulate PA instructions. */
127 static INLINE
unsigned int
131 return (((x
& 1) << 2) | ((x
& 6) >> 1)) & 7;
135 dis_assemble_3 (x
, r
)
139 *r
= (((x
& 4) >> 2) | ((x
& 3) << 1)) & 7;
142 static INLINE
unsigned int
146 return (((y
& 1) << 11) | ((x
& 1) << 10) | ((x
& 0x7fe) >> 1)) & 0xfff;
150 dis_assemble_12 (as12
, x
, y
)
154 *y
= (as12
& 0x800) >> 11;
155 *x
= ((as12
& 0x3ff) << 1) | ((as12
& 0x400) >> 10);
158 static INLINE
unsigned long
159 assemble_17 (x
, y
, z
)
160 unsigned int x
, y
, z
;
164 temp
= ((z
& 1) << 16) |
168 return temp
& 0x1ffff;
172 dis_assemble_17 (as17
, x
, y
, z
)
174 unsigned int *x
, *y
, *z
;
177 *z
= (as17
& 0x10000) >> 16;
178 *x
= (as17
& 0x0f800) >> 11;
179 *y
= (((as17
& 0x00400) >> 10) | ((as17
& 0x3ff) << 1)) & 0x7ff;
182 static INLINE
unsigned long
188 temp
= ((x
& 1) << 20) |
190 ((x
& 0xc000) >> 7) |
191 ((x
& 0x1f0000) >> 14) |
192 ((x
& 0x003000) >> 12);
193 return temp
& 0x1fffff;
197 dis_assemble_21 (as21
, x
)
198 unsigned int as21
, *x
;
203 temp
= (as21
& 0x100000) >> 20;
204 temp
|= (as21
& 0x0ffe00) >> 8;
205 temp
|= (as21
& 0x000180) << 7;
206 temp
|= (as21
& 0x00007c) << 14;
207 temp
|= (as21
& 0x000003) << 12;
211 static INLINE
unsigned long
215 return (x
<< (32 - len
)) >> (32 - len
);
218 static INLINE
unsigned int
222 unsigned int len_ones
;
229 len_ones
= (len_ones
<< 1) | 1;
237 sign_unext (x
, len
, result
)
239 unsigned int *result
;
241 unsigned int len_ones
;
243 len_ones
= ones (len
);
245 *result
= x
& len_ones
;
248 static INLINE
unsigned long
249 low_sign_ext (x
, len
)
252 unsigned int temp1
, temp2
;
253 unsigned int len_ones
;
255 len_ones
= ones (len
);
257 temp1
= (x
& 1) << (len
- 1);
258 temp2
= ((x
& 0xfffffffe) & len_ones
) >> 1;
259 return sign_ext ((temp1
| temp2
), len
);
263 low_sign_unext (x
, len
, result
)
265 unsigned int *result
;
270 unsigned int one_bit_at_len
;
271 unsigned int len_ones
;
273 len_ones
= ones (len
);
274 one_bit_at_len
= 1 << (len
- 1);
276 sign_unext (x
, len
, &temp
);
277 sign
= temp
& one_bit_at_len
;
280 rest
= temp
& (len_ones
^ one_bit_at_len
);
283 *result
= rest
| sign
;
286 /* Handle field selectors for PA instructions. */
288 static INLINE
unsigned long
289 hppa_field_adjust (value
, constant_value
, r_field
)
291 unsigned long constant_value
;
292 unsigned short r_field
;
294 unsigned long init_value
= value
;
295 value
+= constant_value
;
298 case e_fsel
: /* F : no change */
301 case e_lssel
: /* LS : if (bit 21) then add 0x800
302 arithmetic shift right 11 bits */
303 if (value
& 0x00000400)
305 value
= (value
& 0xfffff800) >> 11;
308 case e_rssel
: /* RS : Sign extend from bit 21 */
309 if (value
& 0x00000400)
315 case e_lsel
: /* L : Arithmetic shift right 11 bits */
316 value
= (value
& 0xfffff800) >> 11;
319 case e_rsel
: /* R : Set bits 0-20 to zero */
320 value
= value
& 0x7ff;
323 case e_ldsel
: /* LD : Add 0x800, arithmetic shift
326 value
= (value
& 0xfffff800) >> 11;
329 case e_rdsel
: /* RD : Set bits 0-20 to one */
333 case e_lrsel
: /* LR : L with "rounded" constant */
334 value
= value
+ ((constant_value
+ 0x1000) & 0xffffe000);
335 value
= (value
& 0xfffff800) >> 11;
338 case e_rrsel
: /* RR : R with "rounded" constant */
339 value
= value
+ ((constant_value
+ 0x1000) & 0xffffe000);
340 value
= (value
& 0x7ff) + constant_value
- ((constant_value
+ 0x1000) & 0xffffe000);