include/opcode/
* mips.h (mips_decode_reg_operand): New function. (INSN_WRITE_SHIFT, INSN_WRITE_1, INSN_WRITE_2, INSN_WRITE_ALL) (INSN_READ_SHIFT, INSN_READ_1, INSN_READ_2, INSN_READ_3, INSN_READ_4) (INSN_READ_ALL, INSN_READ_GPR_24, INSN_WRITE_GPR_24, INSN_UDI): New macros. (INSN_WRITE_GPR_D, INSN_WRITE_GPR_T, INSN_WRITE_FPR_D) (INSN_WRITE_FPR_S, INSN_WRITE_FPR_T, INSN_READ_GPR_S, INSN_READ_GPR_T) (INSN_READ_FPR_S, INSN_READ_FPR_T, INSN_READ_FPR_R, INSN_WRITE_GPR_S) (INSN2_WRITE_GPR_Z, INSN2_WRITE_FPR_Z, INSN2_READ_GPR_Z) (INSN2_READ_FPR_Z, INSN2_READ_GPR_D, INSN2_READ_FPR_D) (INSN2_WRITE_GPR_MB, INSN2_READ_GPR_MC, INSN2_MOD_GPR_MD) (INSN2_READ_GPR_ME, INSN2_MOD_GPR_MF, INSN2_READ_GPR_MG) (INSN2_READ_GPR_MJ, INSN2_WRITE_GPR_MJ, INSN2_READ_GPR_MP) (INSN2_WRITE_GPR_MP, INSN2_READ_GPR_MQ, INSN2_READ_GP) (INSN2_WRITE_GPR_MH, INSN2_READ_GPR_MMN): Delete. Renumber other macros to cover the gaps. (INSN2_MOD_SP): Replace with... (INSN2_WRITE_SP, INSN2_READ_SP): ...these new macros. (MIPS16_INSN_WRITE_X, MIPS16_INSN_WRITE_Y, MIPS16_INSN_WRITE_Z) (MIPS16_INSN_WRITE_T, MIPS16_INSN_WRITE_31, MIPS16_INSN_WRITE_GPR_Y) (MIPS16_INSN_READ_X, MIPS16_INSN_READ_Y, MIPS16_INSN_READ_Z) (MIPS16_INSN_READ_T, MIPS16_INSN_READ_SP, MIPS16_INSN_READ_GPR_X): Delete. opcodes/ * mips-opc.c (WR_1, WR_2, RD_1, RD_2, RD_3, RD_4, MOD_1, MOD_2, UDI): New macros. (WR_d, WR_t, WR_D, WR_T, WR_S, RD_s, RD_b, RD_t, RD_S, RD_T, RD_R) (WR_z, WR_Z, RD_z, RD_Z, RD_d): Delete. (mips_builtin_opcodes): Use the new position-based read-write flags instead of field-based ones. Use UDI for "udi..." instructions. * mips16-opc.c (WR_1, WR_2, RD_1, RD_2, RD_3, RD_4, MOD_1, MOD_2): New macros. (WR_x, WR_y, WR_z, WR_Y, RD_x, RD_y, RD_Z, RD_X): Delete. (RD_T, WR_T, WR_31): Redefine using generic INSN_* flags. (WR_SP, RD_16): New macros. (RD_SP): Redefine as an INSN2_* flag. (MOD_SP): Redefine in terms of RD_SP and WR_SP. (mips16_opcodes): Use the new position-based read-write flags instead of field-based ones. Use RD_16 for "nop". Move RD_SP to pinfo2 field. * micromips-opc.c (WR_1, WR_2, RD_1, RD_2, RD_3, RD_4, MOD_1, MOD_2): New macros. (WR_mb, RD_mc, RD_md, WR_md, RD_me, RD_mf, WR_mf, RD_mg, WR_mh, RD_mj) (WR_mj, RD_ml, RD_mmn, RD_mp, WR_mp, RD_mq, RD_gp, WR_d, WR_t, WR_D) (WR_T, WR_S, RD_s, RD_b, RD_t, RD_T, RD_S, RD_R, RD_D): Delete. (RD_sp, WR_sp): Redefine to INSN2_READ_SP and INSN2_WRITE_SP. (micromips_opcodes): Use the new position-based read-write flags instead of field-based ones. * mips-dis.c (print_insn_arg): Use mips_decode_reg_operand. (print_insn_mips, print_insn_micromips): Use INSN_WRITE_1 instead of field-based flags. gas/ * config/tc-mips.c (MAX_OPERANDS): New macro. (mips_operand_array): New structure. (mips_operands, mips16_operands, micromips_operands): New arrays. (micromips_to_32_reg_b_map, micromips_to_32_reg_c_map) (micromips_to_32_reg_e_map, micromips_to_32_reg_f_map) (micromips_to_32_reg_g_map, micromips_to_32_reg_l_map) (micromips_to_32_reg_q_map): Delete. (insn_operands, insn_opno, insn_extract_operand): New functions. (validate_mips_insn): Take a mips_operand_array as argument and use it to build up a list of operands. Extend to handle INSN_MACRO and MIPS16. (validate_mips16_insn): New function. (validate_micromips_insn): Take a mips_operand_array as argument. Handle INSN_MACRO. (md_begin): Initialize mips_operands, mips16_operands and micromips_operands. Call validate_mips_insn and validate_micromips_insn for macro instructions too. Call validate_mips16_insn for MIPS16 instructions. (insn_read_mask, insn_write_mask, operand_reg_mask, insn_reg_mask): New functions. (gpr_read_mask, gpr_write_mask, fpr_read_mask, fpr_write_mask): Use them. Handle INSN_UDI. (get_append_method): Use gpr_read_mask.
This commit is contained in:
parent
304263c612
commit
762d970290
|
@ -1,3 +1,29 @@
|
|||
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* mips.h (mips_decode_reg_operand): New function.
|
||||
(INSN_WRITE_SHIFT, INSN_WRITE_1, INSN_WRITE_2, INSN_WRITE_ALL)
|
||||
(INSN_READ_SHIFT, INSN_READ_1, INSN_READ_2, INSN_READ_3, INSN_READ_4)
|
||||
(INSN_READ_ALL, INSN_READ_GPR_24, INSN_WRITE_GPR_24, INSN_UDI):
|
||||
New macros.
|
||||
(INSN_WRITE_GPR_D, INSN_WRITE_GPR_T, INSN_WRITE_FPR_D)
|
||||
(INSN_WRITE_FPR_S, INSN_WRITE_FPR_T, INSN_READ_GPR_S, INSN_READ_GPR_T)
|
||||
(INSN_READ_FPR_S, INSN_READ_FPR_T, INSN_READ_FPR_R, INSN_WRITE_GPR_S)
|
||||
(INSN2_WRITE_GPR_Z, INSN2_WRITE_FPR_Z, INSN2_READ_GPR_Z)
|
||||
(INSN2_READ_FPR_Z, INSN2_READ_GPR_D, INSN2_READ_FPR_D)
|
||||
(INSN2_WRITE_GPR_MB, INSN2_READ_GPR_MC, INSN2_MOD_GPR_MD)
|
||||
(INSN2_READ_GPR_ME, INSN2_MOD_GPR_MF, INSN2_READ_GPR_MG)
|
||||
(INSN2_READ_GPR_MJ, INSN2_WRITE_GPR_MJ, INSN2_READ_GPR_MP)
|
||||
(INSN2_WRITE_GPR_MP, INSN2_READ_GPR_MQ, INSN2_READ_GP)
|
||||
(INSN2_WRITE_GPR_MH, INSN2_READ_GPR_MMN): Delete. Renumber other
|
||||
macros to cover the gaps.
|
||||
(INSN2_MOD_SP): Replace with...
|
||||
(INSN2_WRITE_SP, INSN2_READ_SP): ...these new macros.
|
||||
(MIPS16_INSN_WRITE_X, MIPS16_INSN_WRITE_Y, MIPS16_INSN_WRITE_Z)
|
||||
(MIPS16_INSN_WRITE_T, MIPS16_INSN_WRITE_31, MIPS16_INSN_WRITE_GPR_Y)
|
||||
(MIPS16_INSN_READ_X, MIPS16_INSN_READ_Y, MIPS16_INSN_READ_Z)
|
||||
(MIPS16_INSN_READ_T, MIPS16_INSN_READ_SP, MIPS16_INSN_READ_GPR_X):
|
||||
Delete.
|
||||
|
||||
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* mips.h (MIPS16_INSN_WRITE_SP, MIPS16_INSN_READ_31)
|
||||
|
|
|
@ -604,6 +604,17 @@ mips_decode_int_operand (const struct mips_int_operand *operand,
|
|||
return uval;
|
||||
}
|
||||
|
||||
/* Return the register that OPERAND encodes as UVAL. */
|
||||
|
||||
static inline int
|
||||
mips_decode_reg_operand (const struct mips_reg_operand *operand,
|
||||
unsigned int uval)
|
||||
{
|
||||
if (operand->reg_map)
|
||||
uval = operand->reg_map[uval];
|
||||
return uval;
|
||||
}
|
||||
|
||||
/* PC-relative operand OPERAND has value UVAL and is relative to BASE_PC.
|
||||
Return the address that it encodes. */
|
||||
|
||||
|
@ -836,71 +847,67 @@ struct mips_opcode
|
|||
/* These are the bits which may be set in the pinfo field of an
|
||||
instructions, if it is not equal to INSN_MACRO. */
|
||||
|
||||
/* Modifies the general purpose register in OP_*_RD. */
|
||||
#define INSN_WRITE_GPR_D 0x00000001
|
||||
/* Modifies the general purpose register in OP_*_RT. */
|
||||
#define INSN_WRITE_GPR_T 0x00000002
|
||||
/* Writes to operand number N. */
|
||||
#define INSN_WRITE_SHIFT 0
|
||||
#define INSN_WRITE_1 0x00000001
|
||||
#define INSN_WRITE_2 0x00000002
|
||||
#define INSN_WRITE_ALL 0x00000003
|
||||
/* Reads from operand number N. */
|
||||
#define INSN_READ_SHIFT 2
|
||||
#define INSN_READ_1 0x00000004
|
||||
#define INSN_READ_2 0x00000008
|
||||
#define INSN_READ_3 0x00000010
|
||||
#define INSN_READ_4 0x00000020
|
||||
#define INSN_READ_ALL 0x0000003c
|
||||
/* Modifies general purpose register 31. */
|
||||
#define INSN_WRITE_GPR_31 0x00000004
|
||||
/* Modifies the floating point register in OP_*_FD. */
|
||||
#define INSN_WRITE_FPR_D 0x00000008
|
||||
/* Modifies the floating point register in OP_*_FS. */
|
||||
#define INSN_WRITE_FPR_S 0x00000010
|
||||
/* Modifies the floating point register in OP_*_FT. */
|
||||
#define INSN_WRITE_FPR_T 0x00000020
|
||||
/* Reads the general purpose register in OP_*_RS. */
|
||||
#define INSN_READ_GPR_S 0x00000040
|
||||
/* Reads the general purpose register in OP_*_RT. */
|
||||
#define INSN_READ_GPR_T 0x00000080
|
||||
/* Reads the floating point register in OP_*_FS. */
|
||||
#define INSN_READ_FPR_S 0x00000100
|
||||
/* Reads the floating point register in OP_*_FT. */
|
||||
#define INSN_READ_FPR_T 0x00000200
|
||||
/* Reads the floating point register in OP_*_FR. */
|
||||
#define INSN_READ_FPR_R 0x00000400
|
||||
#define INSN_WRITE_GPR_31 0x00000040
|
||||
/* Modifies coprocessor condition code. */
|
||||
#define INSN_WRITE_COND_CODE 0x00000800
|
||||
#define INSN_WRITE_COND_CODE 0x00000080
|
||||
/* Reads coprocessor condition code. */
|
||||
#define INSN_READ_COND_CODE 0x00001000
|
||||
#define INSN_READ_COND_CODE 0x00000100
|
||||
/* TLB operation. */
|
||||
#define INSN_TLB 0x00002000
|
||||
#define INSN_TLB 0x00000200
|
||||
/* Reads coprocessor register other than floating point register. */
|
||||
#define INSN_COP 0x00004000
|
||||
#define INSN_COP 0x00000400
|
||||
/* Instruction loads value from memory, requiring delay. */
|
||||
#define INSN_LOAD_MEMORY_DELAY 0x00008000
|
||||
#define INSN_LOAD_MEMORY_DELAY 0x00000800
|
||||
/* Instruction loads value from coprocessor, requiring delay. */
|
||||
#define INSN_LOAD_COPROC_DELAY 0x00010000
|
||||
#define INSN_LOAD_COPROC_DELAY 0x00001000
|
||||
/* Instruction has unconditional branch delay slot. */
|
||||
#define INSN_UNCOND_BRANCH_DELAY 0x00020000
|
||||
#define INSN_UNCOND_BRANCH_DELAY 0x00002000
|
||||
/* Instruction has conditional branch delay slot. */
|
||||
#define INSN_COND_BRANCH_DELAY 0x00040000
|
||||
#define INSN_COND_BRANCH_DELAY 0x00004000
|
||||
/* Conditional branch likely: if branch not taken, insn nullified. */
|
||||
#define INSN_COND_BRANCH_LIKELY 0x00080000
|
||||
#define INSN_COND_BRANCH_LIKELY 0x00008000
|
||||
/* Moves to coprocessor register, requiring delay. */
|
||||
#define INSN_COPROC_MOVE_DELAY 0x00100000
|
||||
#define INSN_COPROC_MOVE_DELAY 0x00010000
|
||||
/* Loads coprocessor register from memory, requiring delay. */
|
||||
#define INSN_COPROC_MEMORY_DELAY 0x00200000
|
||||
#define INSN_COPROC_MEMORY_DELAY 0x00020000
|
||||
/* Reads the HI register. */
|
||||
#define INSN_READ_HI 0x00400000
|
||||
#define INSN_READ_HI 0x00040000
|
||||
/* Reads the LO register. */
|
||||
#define INSN_READ_LO 0x00800000
|
||||
#define INSN_READ_LO 0x00080000
|
||||
/* Modifies the HI register. */
|
||||
#define INSN_WRITE_HI 0x01000000
|
||||
#define INSN_WRITE_HI 0x00100000
|
||||
/* Modifies the LO register. */
|
||||
#define INSN_WRITE_LO 0x02000000
|
||||
#define INSN_WRITE_LO 0x00200000
|
||||
/* Not to be placed in a branch delay slot, either architecturally
|
||||
or for ease of handling (such as with instructions that take a trap). */
|
||||
#define INSN_NO_DELAY_SLOT 0x04000000
|
||||
#define INSN_NO_DELAY_SLOT 0x00400000
|
||||
/* Instruction stores value into memory. */
|
||||
#define INSN_STORE_MEMORY 0x08000000
|
||||
#define INSN_STORE_MEMORY 0x00800000
|
||||
/* Instruction uses single precision floating point. */
|
||||
#define FP_S 0x10000000
|
||||
#define FP_S 0x01000000
|
||||
/* Instruction uses double precision floating point. */
|
||||
#define FP_D 0x20000000
|
||||
#define FP_D 0x02000000
|
||||
/* Instruction is part of the tx39's integer multiply family. */
|
||||
#define INSN_MULT 0x40000000
|
||||
/* Modifies the general purpose register in MICROMIPSOP_*_RS. */
|
||||
#define INSN_WRITE_GPR_S 0x80000000
|
||||
#define INSN_MULT 0x04000000
|
||||
/* Reads general purpose register 24. */
|
||||
#define INSN_READ_GPR_24 0x08000000
|
||||
/* Writes to general purpose register 24. */
|
||||
#define INSN_WRITE_GPR_24 0x10000000
|
||||
/* A user-defined instruction. */
|
||||
#define INSN_UDI 0x20000000
|
||||
/* Instruction is actually a macro. It should be ignored by the
|
||||
disassembler, and requires special treatment by the assembler. */
|
||||
#define INSN_MACRO 0xffffffff
|
||||
|
@ -922,62 +929,24 @@ struct mips_opcode
|
|||
only be set for macros. For instructions, FP_D in pinfo carries the
|
||||
same information. */
|
||||
#define INSN2_M_FP_D 0x00000010
|
||||
/* Modifies the general purpose register in OP_*_RZ. */
|
||||
#define INSN2_WRITE_GPR_Z 0x00000020
|
||||
/* Modifies the floating point register in OP_*_FZ. */
|
||||
#define INSN2_WRITE_FPR_Z 0x00000040
|
||||
/* Reads the general purpose register in OP_*_RZ. */
|
||||
#define INSN2_READ_GPR_Z 0x00000080
|
||||
/* Reads the floating point register in OP_*_FZ. */
|
||||
#define INSN2_READ_FPR_Z 0x00000100
|
||||
/* Reads the general purpose register in OP_*_RD. */
|
||||
#define INSN2_READ_GPR_D 0x00000200
|
||||
|
||||
|
||||
/* Instruction has a branch delay slot that requires a 16-bit instruction. */
|
||||
#define INSN2_BRANCH_DELAY_16BIT 0x00000400
|
||||
#define INSN2_BRANCH_DELAY_16BIT 0x00000020
|
||||
/* Instruction has a branch delay slot that requires a 32-bit instruction. */
|
||||
#define INSN2_BRANCH_DELAY_32BIT 0x00000800
|
||||
/* Reads the floating point register in MICROMIPSOP_*_FD. */
|
||||
#define INSN2_READ_FPR_D 0x00001000
|
||||
/* Modifies the general purpose register in MICROMIPSOP_*_MB. */
|
||||
#define INSN2_WRITE_GPR_MB 0x00002000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_MC. */
|
||||
#define INSN2_READ_GPR_MC 0x00004000
|
||||
/* Reads/writes the general purpose register in MICROMIPSOP_*_MD. */
|
||||
#define INSN2_MOD_GPR_MD 0x00008000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_ME. */
|
||||
#define INSN2_READ_GPR_ME 0x00010000
|
||||
/* Reads/writes the general purpose register in MICROMIPSOP_*_MF. */
|
||||
#define INSN2_MOD_GPR_MF 0x00020000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_MG. */
|
||||
#define INSN2_READ_GPR_MG 0x00040000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_MJ. */
|
||||
#define INSN2_READ_GPR_MJ 0x00080000
|
||||
/* Modifies the general purpose register in MICROMIPSOP_*_MJ. */
|
||||
#define INSN2_WRITE_GPR_MJ 0x00100000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_MP. */
|
||||
#define INSN2_READ_GPR_MP 0x00200000
|
||||
/* Modifies the general purpose register in MICROMIPSOP_*_MP. */
|
||||
#define INSN2_WRITE_GPR_MP 0x00400000
|
||||
/* Reads the general purpose register in MICROMIPSOP_*_MQ. */
|
||||
#define INSN2_READ_GPR_MQ 0x00800000
|
||||
/* Reads/Writes the stack pointer ($29). */
|
||||
#define INSN2_MOD_SP 0x01000000
|
||||
#define INSN2_BRANCH_DELAY_32BIT 0x00000040
|
||||
/* Writes to the stack pointer ($29). */
|
||||
#define INSN2_WRITE_SP 0x00000080
|
||||
/* Reads from the stack pointer ($29). */
|
||||
#define INSN2_READ_SP 0x00000100
|
||||
/* Reads the RA ($31) register. */
|
||||
#define INSN2_READ_GPR_31 0x02000000
|
||||
/* Reads the global pointer ($28). */
|
||||
#define INSN2_READ_GP 0x04000000
|
||||
#define INSN2_READ_GPR_31 0x00000200
|
||||
/* Reads the program counter ($pc). */
|
||||
#define INSN2_READ_PC 0x08000000
|
||||
#define INSN2_READ_PC 0x00000400
|
||||
/* Is an unconditional branch insn. */
|
||||
#define INSN2_UNCOND_BRANCH 0x10000000
|
||||
#define INSN2_UNCOND_BRANCH 0x00000800
|
||||
/* Is a conditional branch insn. */
|
||||
#define INSN2_COND_BRANCH 0x20000000
|
||||
/* Modifies the general purpose registers in MICROMIPSOP_*_MH. */
|
||||
#define INSN2_WRITE_GPR_MH 0x40000000
|
||||
/* Reads the general purpose registers in MICROMIPSOP_*_MM/N. */
|
||||
#define INSN2_READ_GPR_MMN 0x80000000
|
||||
#define INSN2_COND_BRANCH 0x00001000
|
||||
/* Reads from $16. This is true of the MIPS16 0x6500 nop. */
|
||||
#define INSN2_READ_GPR_16 0x00002000
|
||||
|
||||
/* Masks used to mark instructions to indicate which MIPS ISA level
|
||||
they were introduced in. INSN_ISA_MASK masks an enumeration that
|
||||
|
@ -1633,34 +1602,6 @@ extern int bfd_mips_num_opcodes;
|
|||
#define MIPS16_ALL_ARGS 0xe
|
||||
#define MIPS16_ALL_STATICS 0xb
|
||||
|
||||
/* For the mips16, we use the same opcode table format and a few of
|
||||
the same flags. However, most of the flags are different. */
|
||||
|
||||
/* Modifies the register in MIPS16OP_*_RX. */
|
||||
#define MIPS16_INSN_WRITE_X 0x00000001
|
||||
/* Modifies the register in MIPS16OP_*_RY. */
|
||||
#define MIPS16_INSN_WRITE_Y 0x00000002
|
||||
/* Modifies the register in MIPS16OP_*_RZ. */
|
||||
#define MIPS16_INSN_WRITE_Z 0x00000004
|
||||
/* Modifies the T ($24) register. */
|
||||
#define MIPS16_INSN_WRITE_T 0x00000008
|
||||
/* Modifies the RA ($31) register. */
|
||||
#define MIPS16_INSN_WRITE_31 0x00000020
|
||||
/* Modifies the general purpose register in MIPS16OP_*_REG32R. */
|
||||
#define MIPS16_INSN_WRITE_GPR_Y 0x00000040
|
||||
/* Reads the register in MIPS16OP_*_RX. */
|
||||
#define MIPS16_INSN_READ_X 0x00000080
|
||||
/* Reads the register in MIPS16OP_*_RY. */
|
||||
#define MIPS16_INSN_READ_Y 0x00000100
|
||||
/* Reads the register in MIPS16OP_*_MOVE32Z. */
|
||||
#define MIPS16_INSN_READ_Z 0x00000200
|
||||
/* Reads the T ($24) register. */
|
||||
#define MIPS16_INSN_READ_T 0x00000400
|
||||
/* Reads the SP ($29) register. */
|
||||
#define MIPS16_INSN_READ_SP 0x00000800
|
||||
/* Reads the general purpose register in MIPS16OP_*_REGR32. */
|
||||
#define MIPS16_INSN_READ_GPR_X 0x00004000
|
||||
|
||||
/* The following flags have the same value for the mips16 opcode
|
||||
table:
|
||||
|
||||
|
|
Loading…
Reference in New Issue