diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index afc0807ea..dd37f6c90 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,12 @@ +2007-11-29 Mark Shinwell + + * mips.h (INSN_ISA*): Redefine certain values as an + enumeration. Update comments. + (mips_isa_table): New. + (ISA_MIPS*): Redefine to match enumeration. + (OPCODE_IS_MEMBER): Modify to correctly test new INSN_ISA* + values. + 2007-08-08 Ben Elliston * ppc.h (PPC_OPCODE_PPCPS): New. diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 71822a41b..d74dccd94 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -472,20 +472,43 @@ struct mips_opcode #define INSN_MACRO 0xffffffff /* Masks used to mark instructions to indicate which MIPS ISA level - they were introduced in. ISAs, as defined below, are logical - ORs of these bits, indicating that they support the instructions - defined at the given level. */ + they were introduced in. INSN_ISA_MASK masks an enumeration that + specifies the base ISA level(s). The remainder of a 32-bit + word constructed using these macros is a bitmask of the remaining + INSN_* values below. */ -#define INSN_ISA_MASK 0x00000fff -#define INSN_ISA1 0x00000001 -#define INSN_ISA2 0x00000002 -#define INSN_ISA3 0x00000004 -#define INSN_ISA4 0x00000008 -#define INSN_ISA5 0x00000010 -#define INSN_ISA32 0x00000020 -#define INSN_ISA64 0x00000040 -#define INSN_ISA32R2 0x00000080 -#define INSN_ISA64R2 0x00000100 +#define INSN_ISA_MASK 0x0000000ful + +/* We cannot start at zero due to ISA_UNKNOWN below. */ +#define INSN_ISA1 1 +#define INSN_ISA2 2 +#define INSN_ISA3 3 +#define INSN_ISA4 4 +#define INSN_ISA5 5 +#define INSN_ISA32 6 +#define INSN_ISA32R2 7 +#define INSN_ISA64 8 +#define INSN_ISA64R2 9 +/* Below this point the INSN_* values correspond to combinations of ISAs. + They are only for use in the opcodes table to indicate membership of + a combination of ISAs that cannot be expressed using the usual inclusion + ordering on the above INSN_* values. */ +#define INSN_ISA3_32 10 +#define INSN_ISA3_32R2 11 +#define INSN_ISA4_32 12 +#define INSN_ISA4_32R2 13 +#define INSN_ISA5_32R2 14 + +/* Given INSN_ISA* values X and Y, where X ranges over INSN_ISA1 through + INSN_ISA5_32R2 and Y ranges over INSN_ISA1 through INSN_ISA64R2, + this table describes whether at least one of the ISAs described by X + is/are implemented by ISA Y. (Think of Y as the ISA level supported by + a particular core and X as the ISA level(s) at which a certain instruction + is defined.) The ISA(s) described by X is/are implemented by Y iff + (mips_isa_table[(Y & INSN_ISA_MASK) - 1] >> ((X & INSN_ISA_MASK) - 1)) & 1 + is non-zero. */ +static const unsigned int mips_isa_table[] = + { 0x0001, 0x0003, 0x0607, 0x1e0f, 0x3e1f, 0x0a23, 0x3e63, 0x3ebf, 0x3fff }; /* Masks used for MIPS-defined ASEs. */ #define INSN_ASE_MASK 0x3c00f000 @@ -533,17 +556,17 @@ struct mips_opcode /* MIPS ISA defines, use instead of hardcoding ISA level. */ #define ISA_UNKNOWN 0 /* Gas internal use. */ -#define ISA_MIPS1 (INSN_ISA1) -#define ISA_MIPS2 (ISA_MIPS1 | INSN_ISA2) -#define ISA_MIPS3 (ISA_MIPS2 | INSN_ISA3) -#define ISA_MIPS4 (ISA_MIPS3 | INSN_ISA4) -#define ISA_MIPS5 (ISA_MIPS4 | INSN_ISA5) +#define ISA_MIPS1 INSN_ISA1 +#define ISA_MIPS2 INSN_ISA2 +#define ISA_MIPS3 INSN_ISA3 +#define ISA_MIPS4 INSN_ISA4 +#define ISA_MIPS5 INSN_ISA5 -#define ISA_MIPS32 (ISA_MIPS2 | INSN_ISA32) -#define ISA_MIPS64 (ISA_MIPS5 | INSN_ISA32 | INSN_ISA64) +#define ISA_MIPS32 INSN_ISA32 +#define ISA_MIPS64 INSN_ISA64 -#define ISA_MIPS32R2 (ISA_MIPS32 | INSN_ISA32R2) -#define ISA_MIPS64R2 (ISA_MIPS64 | INSN_ISA32R2 | INSN_ISA64R2) +#define ISA_MIPS32R2 INSN_ISA32R2 +#define ISA_MIPS64R2 INSN_ISA64R2 /* CPU defines, use instead of hardcoding processor number. Keep this @@ -583,7 +606,12 @@ struct mips_opcode test, or zero if no CPU specific ISA test is desired. */ #define OPCODE_IS_MEMBER(insn, isa, cpu) \ - (((insn)->membership & isa) != 0 \ + (((isa & INSN_ISA_MASK) != 0 \ + && ((insn)->membership & INSN_ISA_MASK) != 0 \ + && ((mips_isa_table [(isa & INSN_ISA_MASK) - 1] >> \ + (((insn)->membership & INSN_ISA_MASK) - 1)) & 1) != 0) \ + || ((isa & ~INSN_ISA_MASK) \ + & ((insn)->membership & ~INSN_ISA_MASK)) != 0 \ || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0) \ || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0) \ || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0) \