X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Flibhppa.h;h=52ebf51f61a294f1230a043737e9a350afebd879;hb=29ceeffbdecd52296cecbc0d2d5148b204a4f930;hp=121398d2b2d4ce61a16ac4f2c942e4eae254ea92;hpb=3f9b03b5daf721100e6cb36e2a3f903e96ea1dbd;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/libhppa.h b/bfd/libhppa.h index 121398d2b2..52ebf51f61 100644 --- a/bfd/libhppa.h +++ b/bfd/libhppa.h @@ -1,5 +1,5 @@ /* HP PA-RISC SOM object file format: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 98, 99, 2000 + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by the Center for Software Science at the @@ -21,8 +21,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _HPPA_H -#define _HPPA_H +#ifndef _LIBHPPA_H +#define _LIBHPPA_H #define BYTES_IN_WORD 4 #define PA_PAGESIZE 0x1000 @@ -156,227 +156,74 @@ enum hppa_reloc_expr_type_alt #define HPPA_R_ARG_RELOC(a) \ (((a) >> 22) & 0x3ff) #define HPPA_R_CONSTANT(a) \ - ((((int)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22)) + ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22)) #define HPPA_R_ADDEND(r, c) \ (((r) << 22) + ((c) & 0x3fffff)) -#define HPPA_WIDE (0) /* PSW W-bit, need to check! FIXME */ -/* These macros get bit fields using HP's numbering (MSB = 0), - * but note that "MASK" assumes that the LSB bits are what's - * wanted. - */ -#ifndef GET_FIELD -#define GET_FIELD(X, FROM, TO) \ - ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) -#endif -#define GET_BIT(X, WHICH) \ - GET_FIELD (X, WHICH, WHICH) - -#define MASK(SIZE) \ - (~((-1) << SIZE)) - -#define CATENATE(X, XSIZE, Y, YSIZE) \ - (((X & MASK (XSIZE)) << YSIZE) | (Y & MASK (YSIZE))) - -#define ELEVEN(X) \ - CATENATE (GET_BIT (X, 10), 1, GET_FIELD (X, 0, 9), 10) /* Some functions to manipulate PA instructions. */ -/* NOTE: these use the HP convention that f{0} is the _left_ most - * bit (MSB) of f; they sometimes have to impose an assumption - * about the size of a field; and as far as I can tell, most - * aren't used. - */ - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) /* Declare the functions with the unused attribute to avoid warnings. */ -static INLINE unsigned int sign_extend (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int low_sign_extend (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_3 (unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_6 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_12 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_16 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_16a (unsigned int, unsigned int, - unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_17 (unsigned int, unsigned int, - unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int assemble_21 (unsigned int) - __attribute ((__unused__)); - -static INLINE unsigned int sign_unext (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int low_sign_unext (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_3 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_12 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_16 (unsigned int, unsigned int, int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_17 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_22 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int re_assemble_21 (unsigned int, unsigned int) - __attribute__ ((__unused__)); -static INLINE bfd_signed_vma hppa_field_adjust (bfd_signed_vma, bfd_signed_vma, - enum hppa_reloc_field_selector_type_alt) - __attribute__ ((__unused__)); -static INLINE int bfd_hppa_insn2fmt (unsigned int) - __attribute__ ((__unused__)); -static INLINE unsigned int hppa_rebuild_insn (bfd *, unsigned int, - unsigned int, unsigned int) - __attribute__ ((__unused__)); -#endif /* gcc 2.7 or higher */ - - -/* The *sign_extend and assemble_* functions are used to assemble - various bitfields taken from an instruction and return the - resulting immediate value. They correspond to functions by the - same name in HP's PA-RISC 2.0 Architecture Reference Manual. */ - -static INLINE unsigned int +static INLINE int sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED; +static INLINE int low_sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED; +static INLINE int sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED; +static INLINE int low_sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_3 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_12 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_14 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_16 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_17 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_21 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE int re_assemble_22 PARAMS ((int)) ATTRIBUTE_UNUSED; +static INLINE bfd_signed_vma hppa_field_adjust + PARAMS ((bfd_vma, bfd_signed_vma, + enum hppa_reloc_field_selector_type_alt)) ATTRIBUTE_UNUSED; +static INLINE int bfd_hppa_insn2fmt PARAMS ((bfd *, int)) ATTRIBUTE_UNUSED; +static INLINE int hppa_rebuild_insn PARAMS ((int, int, int)) ATTRIBUTE_UNUSED; + + +/* The *sign_extend functions are used to assemble various bitfields + taken from an instruction and return the resulting immediate + value. */ + +static INLINE int sign_extend (x, len) - unsigned int x, len; + int x, len; { - unsigned int signbit = (1 << (len - 1)); - unsigned int mask = (signbit << 1) - 1; + int signbit = (1 << (len - 1)); + int mask = (signbit << 1) - 1; return ((x & mask) ^ signbit) - signbit; } -static INLINE unsigned int +static INLINE int low_sign_extend (x, len) - unsigned int x, len; + int x, len; { return (x >> 1) - ((x & 1) << (len - 1)); } -static INLINE unsigned int -assemble_3 (x) - unsigned int x; -{ - return CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2); -} - -static INLINE unsigned int -assemble_6 (x, y) - unsigned int x, y; -{ - return (((x & 1) << 5) + (32 - (y & 0x1f))); -} - -static INLINE unsigned int -assemble_12 (x, y) - unsigned int x, y; -{ - return CATENATE (CATENATE (y, 1, GET_BIT (x, 10), 1), 2, - GET_FIELD (x, 0, 9), 9); -} - -static INLINE unsigned int -assemble_16 (x, y) - unsigned int x, y; -{ - /* Depends on PSW W-bit !*/ - unsigned int temp; - - if (HPPA_WIDE) - temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, - (GET_BIT (y, 13) ^ GET_BIT (x, 0)), 1), 2, - CATENATE ((GET_BIT (y, 13) ^ GET_BIT (x, 1)), 1, - GET_FIELD (y, 0, 12), 13), 14); - else - temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, GET_BIT (y, 13), 1), 2, - CATENATE (GET_BIT (y, 13), 1, GET_FIELD (y, 0, 12), 13), 14); - - return sign_extend (temp, 16); -} - -static INLINE unsigned int -assemble_16a (x, y, z) - unsigned int x, y, z; -{ - /* Depends on PSW W-bit !*/ - unsigned int temp; - - if (HPPA_WIDE) - temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2, - CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12); - else - temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12); - - return sign_extend ((temp << 2), 16); -} - -static INLINE unsigned int -assemble_17 (x, y, z) - unsigned int x, y, z; -{ - unsigned int temp; - - temp = CATENATE (CATENATE (z, 1, x, 5), 6, - CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11); - - return temp; -} - -static INLINE unsigned int -assemble_21 (x) - unsigned int x; -{ - unsigned int temp; - - temp = (( (x & 0x000001) << 20) - | ((x & 0x000ffe) << 8) - | ((x & 0x003000) >> 12) - | ((x & 0x00c000) >> 7) - | ((x & 0x1f0000) >> 14)); - return temp; -} - -static INLINE unsigned int -assemble_22 (a,b,c,d) - unsigned int a,b,c,d; -{ - unsigned int temp; - - temp = CATENATE (CATENATE (d, 1, a, 5), 6, - CATENATE (b, 5, ELEVEN (c), 11), 16); - - return sign_extend (temp, 22); -} - -/* The re_assemble_* functions splice together an opcode and an - immediate value. pa-risc uses all sorts of weird bitfields in the - instruction to hold the value. */ +/* The re_assemble_* functions prepare an immediate value for + insertion into an opcode. pa-risc uses all sorts of weird bitfields + in the instruction to hold the value. */ -static INLINE unsigned int +static INLINE int sign_unext (x, len) - unsigned int x, len; + int x, len; { - unsigned int len_ones; + int len_ones; - len_ones = ((unsigned int) 1 << len) - 1; + len_ones = (1 << len) - 1; return x & len_ones; } -static INLINE unsigned int +static INLINE int low_sign_unext (x, len) - unsigned int x, len; + int x, len; { - unsigned int temp; - unsigned int sign; + int temp; + int sign; sign = (x >> (len-1)) & 1; @@ -385,83 +232,69 @@ low_sign_unext (x, len) return (temp << 1) | sign; } -static INLINE unsigned int -re_assemble_3 (insn, as3) - unsigned int insn; - unsigned int as3; +static INLINE int +re_assemble_3 (as3) + int as3; { - return ((insn & ~ (7 << 13)) - | ((as3 & 4) << (13-2)) + return (( (as3 & 4) << (13-2)) | ((as3 & 3) << (13+1))); } -static INLINE unsigned int -re_assemble_12 (insn, as12) - unsigned int insn; - unsigned int as12; +static INLINE int +re_assemble_12 (as12) + int as12; { - return ((insn & ~ 0x1ffd) - | ((as12 & 0x800) >> 11) + return (( (as12 & 0x800) >> 11) | ((as12 & 0x400) >> (10 - 2)) | ((as12 & 0x3ff) << (1 + 2))); } -static INLINE unsigned int -re_assemble_16 (insn, as16, wide) - unsigned int insn; - unsigned int as16; - int wide; +static INLINE int +re_assemble_14 (as14) + int as14; { - unsigned int s, t; + return (( (as14 & 0x1fff) << 1) + | ((as14 & 0x2000) >> 13)); +} - if (wide) - { - /* Unusual 16-bit encoding. */ - t = (as16 << 1) & 0xffff; - s = (as16 & 0x8000); - return (insn & ~ 0xffff) | (t ^ s ^ (s >> 1)) | (s >> 15); - } - else - { - /* Standard 14-bit encoding. */ - t = (as16 << 1) & 0x3fff; - s = (as16 & 0x2000); - return (insn & ~ 0xffff) | t | (s >> 13); - } +static INLINE int +re_assemble_16 (as16) + int as16; +{ + int s, t; + + /* Unusual 16-bit encoding, for wide mode only. */ + t = (as16 << 1) & 0xffff; + s = (as16 & 0x8000); + return (t ^ s ^ (s >> 1)) | (s >> 15); } -static INLINE unsigned int -re_assemble_17 (insn, as17) - unsigned int insn; - unsigned int as17; +static INLINE int +re_assemble_17 (as17) + int as17; { - return ((insn & ~ 0x1f1ffd) - | ((as17 & 0x10000) >> 16) + return (( (as17 & 0x10000) >> 16) | ((as17 & 0x0f800) << (16 - 11)) | ((as17 & 0x00400) >> (10 - 2)) | ((as17 & 0x003ff) << (1 + 2))); } -static INLINE unsigned int -re_assemble_21 (insn, as21) - unsigned int insn; - unsigned int as21; +static INLINE int +re_assemble_21 (as21) + int as21; { - return ((insn & ~ 0x1fffff) - | ((as21 & 0x100000) >> 20) + return (( (as21 & 0x100000) >> 20) | ((as21 & 0x0ffe00) >> 8) | ((as21 & 0x000180) << 7) | ((as21 & 0x00007c) << 14) | ((as21 & 0x000003) << 12)); } -static INLINE unsigned int -re_assemble_22 (insn, as22) - unsigned int insn; - unsigned int as22; +static INLINE int +re_assemble_22 (as22) + int as22; { - return ((insn & ~ 0x3ff1ffd) - | ((as22 & 0x200000) >> 21) + return (( (as22 & 0x200000) >> 21) | ((as22 & 0x1f0000) << (21 - 16)) | ((as22 & 0x00f800) << (16 - 11)) | ((as22 & 0x000400) >> (10 - 2)) @@ -481,7 +314,7 @@ re_assemble_22 (insn, as22) static INLINE bfd_signed_vma hppa_field_adjust (sym_val, addend, r_field) - bfd_signed_vma sym_val; + bfd_vma sym_val; bfd_signed_vma addend; enum hppa_reloc_field_selector_type_alt r_field; { @@ -491,10 +324,18 @@ hppa_field_adjust (sym_val, addend, r_field) switch (r_field) { case e_fsel: - case e_nsel: /* F: No change. */ break; + case e_nsel: + /* N: null selector. I don't really understand what this is all + about, but HP's documentation says "this indicates that zero + bits are to be used for the displacement on the instruction. + This fixup is used to identify three-instruction sequences to + access data (for importing shared library data)." */ + value = 0; + break; + case e_lsel: case e_nlsel: /* L: Select top 21 bits. */ @@ -558,123 +399,158 @@ hppa_field_adjust (sym_val, addend, r_field) /* PA-RISC OPCODES */ #define get_opcode(insn) (((insn) >> 26) & 0x3f) -/* FIXME: this list is incomplete. It should also be an enumerated - type rather than #defines. */ - -#define LDO 0x0d -#define LDB 0x10 -#define LDH 0x11 -#define LDW 0x12 -#define LDWM 0x13 -#define STB 0x18 -#define STH 0x19 -#define STW 0x1a -#define STWM 0x1b -#define COMICLR 0x24 -#define SUBI 0x25 -#define SUBIO 0x25 -#define ADDIT 0x2c -#define ADDITO 0x2c -#define ADDI 0x2d -#define ADDIO 0x2d -#define LDIL 0x08 -#define ADDIL 0x0a - -#define MOVB 0x32 -#define MOVIB 0x33 -#define COMBT 0x20 -#define COMBF 0x22 -#define COMIBT 0x21 -#define COMIBF 0x23 -#define ADDBT 0x28 -#define ADDBF 0x2a -#define ADDIBT 0x29 -#define ADDIBF 0x2b -#define BVB 0x30 -#define BB 0x31 - -#define BL 0x3a -#define BLE 0x39 -#define BE 0x38 - -#define CMPBDT 0x27 -#define CMPBDF 0x2f -#define CMPIBD 0x3b -#define LDD 0x14 -#define STD 0x1c -#define LDWL 0x17 -#define STWL 0x1f -#define FLDW 0x16 -#define FSTW 0x1e - -/* Given a machine instruction, return its format. - - FIXME: opcodes which do not map to a known format - should return an error of some sort. */ +enum hppa_opcode_type +{ + /* None of the opcodes in the first group generate relocs, so we + aren't too concerned about them. */ + OP_SYSOP = 0x00, + OP_MEMMNG = 0x01, + OP_ALU = 0x02, + OP_NDXMEM = 0x03, + OP_SPOP = 0x04, + OP_DIAG = 0x05, + OP_FMPYADD = 0x06, + OP_UNDEF07 = 0x07, + OP_COPRW = 0x09, + OP_COPRDW = 0x0b, + OP_COPR = 0x0c, + OP_FLOAT = 0x0e, + OP_PRDSPEC = 0x0f, + OP_UNDEF15 = 0x15, + OP_UNDEF1d = 0x1d, + OP_FMPYSUB = 0x26, + OP_FPFUSED = 0x2e, + OP_SHEXDP0 = 0x34, + OP_SHEXDP1 = 0x35, + OP_SHEXDP2 = 0x36, + OP_UNDEF37 = 0x37, + OP_SHEXDP3 = 0x3c, + OP_SHEXDP4 = 0x3d, + OP_MULTMED = 0x3e, + OP_UNDEF3f = 0x3f, + + OP_LDIL = 0x08, + OP_ADDIL = 0x0a, + + OP_LDO = 0x0d, + OP_LDB = 0x10, + OP_LDH = 0x11, + OP_LDW = 0x12, + OP_LDWM = 0x13, + OP_STB = 0x18, + OP_STH = 0x19, + OP_STW = 0x1a, + OP_STWM = 0x1b, + + OP_LDD = 0x14, + OP_STD = 0x1c, + + OP_FLDW = 0x16, + OP_LDWL = 0x17, + OP_FSTW = 0x1e, + OP_STWL = 0x1f, + + OP_COMBT = 0x20, + OP_COMIBT = 0x21, + OP_COMBF = 0x22, + OP_COMIBF = 0x23, + OP_CMPBDT = 0x27, + OP_ADDBT = 0x28, + OP_ADDIBT = 0x29, + OP_ADDBF = 0x2a, + OP_ADDIBF = 0x2b, + OP_CMPBDF = 0x2f, + OP_BVB = 0x30, + OP_BB = 0x31, + OP_MOVB = 0x32, + OP_MOVIB = 0x33, + OP_CMPIBD = 0x3b, + + OP_COMICLR = 0x24, + OP_SUBI = 0x25, + OP_ADDIT = 0x2c, + OP_ADDI = 0x2d, + + OP_BE = 0x38, + OP_BLE = 0x39, + OP_BL = 0x3a +}; + + +/* Given a machine instruction, return its format. */ static INLINE int -bfd_hppa_insn2fmt (insn) - unsigned int insn; +bfd_hppa_insn2fmt (abfd, insn) + bfd *abfd; + int insn; { - unsigned char op = get_opcode (insn); + enum hppa_opcode_type op = get_opcode (insn); switch (op) { - case ADDI: - case ADDIT: - case SUBI: + case OP_COMICLR: + case OP_SUBI: + case OP_ADDIT: + case OP_ADDI: return 11; - case MOVB: - case MOVIB: - case COMBT: - case COMBF: - case COMIBT: - case COMIBF: - case ADDBT: - case ADDBF: - case ADDIBT: - case ADDIBF: - case BVB: - case BB: - case CMPBDT: - case CMPBDF: - case CMPIBD: + case OP_COMBT: + case OP_COMIBT: + case OP_COMBF: + case OP_COMIBF: + case OP_CMPBDT: + case OP_ADDBT: + case OP_ADDIBT: + case OP_ADDBF: + case OP_ADDIBF: + case OP_CMPBDF: + case OP_BVB: + case OP_BB: + case OP_MOVB: + case OP_MOVIB: + case OP_CMPIBD: return 12; - case LDO: - case LDB: - case LDH: - case LDW: - case LDWM: - case STB: - case STH: - case STW: - case STWM: + case OP_LDO: + case OP_LDB: + case OP_LDH: + case OP_LDW: + case OP_LDWM: + case OP_STB: + case OP_STH: + case OP_STW: + case OP_STWM: + if (abfd->arch_info->mach >= 25) + return 16; /* Wide mode, format 16. */ return 14; - case LDWL: - case STWL: - case FLDW: - case FSTW: + case OP_FLDW: + case OP_LDWL: + case OP_FSTW: + case OP_STWL: /* This is a hack. Unfortunately, format 11 is already taken and we're using integers rather than an enum, so it's hard to describe the 11a format. */ + if (abfd->arch_info->mach >= 25) + return -16; /* Wide mode, format 16a. */ return -11; - case LDD: - case STD: + case OP_LDD: + case OP_STD: + if (abfd->arch_info->mach >= 25) + return -10; /* Wide mode, format 10a. */ return 10; - case BL: - case BE: - case BLE: - if ((insn & 0x00008000) != 0) + case OP_BL: + if ((insn & 0x8000) != 0) return 22; + /* fall thru */ + case OP_BE: + case OP_BLE: return 17; - case LDIL: - case ADDIL: + case OP_LDIL: + case OP_ADDIL: return 21; default: @@ -687,21 +563,52 @@ bfd_hppa_insn2fmt (insn) /* Insert VALUE into INSN using R_FORMAT to determine exactly what bits to change. */ -static INLINE unsigned int -hppa_rebuild_insn (abfd, insn, value, r_format) - bfd *abfd ATTRIBUTE_UNUSED; - unsigned int insn; - unsigned int value; - unsigned int r_format; +static INLINE int +hppa_rebuild_insn (insn, value, r_format) + int insn; + int value; + int r_format; { switch (r_format) { - case 11: return (insn & ~ 0x7ff) | low_sign_unext (value, 11); - case 12: return re_assemble_12 (insn, value); - case 14: return (insn & ~ 0x3fff) | low_sign_unext (value, 14); - case 17: return re_assemble_17 (insn, value); - case 21: return re_assemble_21 (insn, value); - case 32: return value; + case 11: + return (insn & ~ 0x7ff) | low_sign_unext (value, 11); + + case 12: + return (insn & ~ 0x1ffd) | re_assemble_12 (value); + + + case 10: + return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8); + + case -11: + return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4); + + case 14: + return (insn & ~ 0x3fff) | re_assemble_14 (value); + + + case -10: + return (insn & ~ 0xfff1) | re_assemble_16 (value & -8); + + case -16: + return (insn & ~ 0xfff9) | re_assemble_16 (value & -4); + + case 16: + return (insn & ~ 0xffff) | re_assemble_16 (value); + + + case 17: + return (insn & ~ 0x1f1ffd) | re_assemble_17 (value); + + case 21: + return (insn & ~ 0x1fffff) | re_assemble_21 (value); + + case 22: + return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value); + + case 32: + return value; default: abort (); @@ -709,4 +616,4 @@ hppa_rebuild_insn (abfd, insn, value, r_format) return insn; } -#endif /* _HPPA_H */ +#endif /* _LIBHPPA_H */