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
265459441c
commit
fc76e73056
|
@ -1,3 +1,29 @@
|
||||||
|
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
* config/tc-mips.c (compact_branch_p, uncond_branch_p): Use the same
|
* config/tc-mips.c (compact_branch_p, uncond_branch_p): Use the same
|
||||||
|
|
|
@ -689,6 +689,15 @@ static int mips_debug = 0;
|
||||||
fill a branch delay slot. */
|
fill a branch delay slot. */
|
||||||
static struct mips_cl_insn history[1 + MAX_NOPS];
|
static struct mips_cl_insn history[1 + MAX_NOPS];
|
||||||
|
|
||||||
|
/* Arrays of operands for each instruction. */
|
||||||
|
#define MAX_OPERANDS 5
|
||||||
|
struct mips_operand_array {
|
||||||
|
const struct mips_operand *operand[MAX_OPERANDS];
|
||||||
|
};
|
||||||
|
static struct mips_operand_array *mips_operands;
|
||||||
|
static struct mips_operand_array *mips16_operands;
|
||||||
|
static struct mips_operand_array *micromips_operands;
|
||||||
|
|
||||||
/* Nop instructions used by emit_nop. */
|
/* Nop instructions used by emit_nop. */
|
||||||
static struct mips_cl_insn nop_insn;
|
static struct mips_cl_insn nop_insn;
|
||||||
static struct mips_cl_insn mips16_nop_insn;
|
static struct mips_cl_insn mips16_nop_insn;
|
||||||
|
@ -764,12 +773,7 @@ static const unsigned int mips16_to_32_reg_map[] =
|
||||||
|
|
||||||
/* Map microMIPS register numbers to normal MIPS register numbers. */
|
/* Map microMIPS register numbers to normal MIPS register numbers. */
|
||||||
|
|
||||||
#define micromips_to_32_reg_b_map mips16_to_32_reg_map
|
|
||||||
#define micromips_to_32_reg_c_map mips16_to_32_reg_map
|
|
||||||
#define micromips_to_32_reg_d_map mips16_to_32_reg_map
|
#define micromips_to_32_reg_d_map mips16_to_32_reg_map
|
||||||
#define micromips_to_32_reg_e_map mips16_to_32_reg_map
|
|
||||||
#define micromips_to_32_reg_f_map mips16_to_32_reg_map
|
|
||||||
#define micromips_to_32_reg_g_map mips16_to_32_reg_map
|
|
||||||
|
|
||||||
/* The microMIPS registers with type h. */
|
/* The microMIPS registers with type h. */
|
||||||
static const unsigned int micromips_to_32_reg_h_map1[] =
|
static const unsigned int micromips_to_32_reg_h_map1[] =
|
||||||
|
@ -781,8 +785,6 @@ static const unsigned int micromips_to_32_reg_h_map2[] =
|
||||||
6, 7, 7, 21, 22, 5, 6, 7
|
6, 7, 7, 21, 22, 5, 6, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
#define micromips_to_32_reg_l_map mips16_to_32_reg_map
|
|
||||||
|
|
||||||
/* The microMIPS registers with type m. */
|
/* The microMIPS registers with type m. */
|
||||||
static const unsigned int micromips_to_32_reg_m_map[] =
|
static const unsigned int micromips_to_32_reg_m_map[] =
|
||||||
{
|
{
|
||||||
|
@ -791,12 +793,6 @@ static const unsigned int micromips_to_32_reg_m_map[] =
|
||||||
|
|
||||||
#define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
|
#define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
|
||||||
|
|
||||||
/* The microMIPS registers with type q. */
|
|
||||||
static const unsigned int micromips_to_32_reg_q_map[] =
|
|
||||||
{
|
|
||||||
0, 17, 2, 3, 4, 5, 6, 7
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Classifies the kind of instructions we're interested in when
|
/* Classifies the kind of instructions we're interested in when
|
||||||
implementing -mfix-vr4120. */
|
implementing -mfix-vr4120. */
|
||||||
enum fix_vr4120_class
|
enum fix_vr4120_class
|
||||||
|
@ -1966,6 +1962,39 @@ create_insn (struct mips_cl_insn *insn, const struct mips_opcode *mo)
|
||||||
insn->cleared_p = 0;
|
insn->cleared_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a list of all the operands in INSN. */
|
||||||
|
|
||||||
|
static const struct mips_operand_array *
|
||||||
|
insn_operands (const struct mips_cl_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->insn_mo >= &mips_opcodes[0]
|
||||||
|
&& insn->insn_mo < &mips_opcodes[NUMOPCODES])
|
||||||
|
return &mips_operands[insn->insn_mo - &mips_opcodes[0]];
|
||||||
|
|
||||||
|
if (insn->insn_mo >= &mips16_opcodes[0]
|
||||||
|
&& insn->insn_mo < &mips16_opcodes[bfd_mips16_num_opcodes])
|
||||||
|
return &mips16_operands[insn->insn_mo - &mips16_opcodes[0]];
|
||||||
|
|
||||||
|
if (insn->insn_mo >= µmips_opcodes[0]
|
||||||
|
&& insn->insn_mo < µmips_opcodes[bfd_micromips_num_opcodes])
|
||||||
|
return µmips_operands[insn->insn_mo - µmips_opcodes[0]];
|
||||||
|
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a description of operand OPNO of INSN. */
|
||||||
|
|
||||||
|
static const struct mips_operand *
|
||||||
|
insn_opno (const struct mips_cl_insn *insn, unsigned opno)
|
||||||
|
{
|
||||||
|
const struct mips_operand_array *operands;
|
||||||
|
|
||||||
|
operands = insn_operands (insn);
|
||||||
|
if (opno >= MAX_OPERANDS || !operands->operand[opno])
|
||||||
|
abort ();
|
||||||
|
return operands->operand[opno];
|
||||||
|
}
|
||||||
|
|
||||||
/* Install UVAL as the value of OPERAND in INSN. */
|
/* Install UVAL as the value of OPERAND in INSN. */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -1975,6 +2004,15 @@ insn_insert_operand (struct mips_cl_insn *insn,
|
||||||
insn->insn_opcode = mips_insert_operand (operand, insn->insn_opcode, uval);
|
insn->insn_opcode = mips_insert_operand (operand, insn->insn_opcode, uval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extract the value of OPERAND from INSN. */
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
insn_extract_operand (const struct mips_cl_insn *insn,
|
||||||
|
const struct mips_operand *operand)
|
||||||
|
{
|
||||||
|
return mips_extract_operand (operand, insn->insn_opcode);
|
||||||
|
}
|
||||||
|
|
||||||
/* Record the current MIPS16/microMIPS mode in now_seg. */
|
/* Record the current MIPS16/microMIPS mode in now_seg. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2831,28 +2869,34 @@ is_delay_slot_valid (const struct mips_opcode *mo)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For consistency checking, verify that all bits of OPCODE are
|
/* For consistency checking, verify that all bits of OPCODE are specified
|
||||||
specified either by the match/mask part of the instruction
|
either by the match/mask part of the instruction definition, or by the
|
||||||
definition, or by the operand list. INSN_BITS says which
|
operand list. Also build up a list of operands in OPERANDS.
|
||||||
bits of the instruction are significant and DECODE_OPERAND
|
|
||||||
provides the mips_operand description of each operand. */
|
INSN_BITS says which bits of the instruction are significant.
|
||||||
|
If OPCODE is a standard or microMIPS instruction, DECODE_OPERAND
|
||||||
|
provides the mips_operand description of each operand. DECODE_OPERAND
|
||||||
|
is null for MIPS16 instructions. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
validate_mips_insn (const struct mips_opcode *opcode,
|
validate_mips_insn (const struct mips_opcode *opcode,
|
||||||
unsigned long insn_bits,
|
unsigned long insn_bits,
|
||||||
const struct mips_operand *(*decode_operand) (const char *))
|
const struct mips_operand *(*decode_operand) (const char *),
|
||||||
|
struct mips_operand_array *operands)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned long used_bits, doubled, undefined;
|
unsigned long used_bits, doubled, undefined, opno, mask;
|
||||||
const struct mips_operand *operand;
|
const struct mips_operand *operand;
|
||||||
|
|
||||||
if ((opcode->mask & opcode->match) != opcode->match)
|
mask = (opcode->pinfo == INSN_MACRO ? 0 : opcode->mask);
|
||||||
|
if ((mask & opcode->match) != opcode->match)
|
||||||
{
|
{
|
||||||
as_bad (_("internal: bad mips opcode (mask error): %s %s"),
|
as_bad (_("internal: bad mips opcode (mask error): %s %s"),
|
||||||
opcode->name, opcode->args);
|
opcode->name, opcode->args);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
used_bits = 0;
|
used_bits = 0;
|
||||||
|
opno = 0;
|
||||||
for (s = opcode->args; *s; ++s)
|
for (s = opcode->args; *s; ++s)
|
||||||
switch (*s)
|
switch (*s)
|
||||||
{
|
{
|
||||||
|
@ -2862,33 +2906,44 @@ validate_mips_insn (const struct mips_opcode *opcode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
operand = decode_operand (s);
|
if (!decode_operand)
|
||||||
if (!operand)
|
operand = decode_mips16_operand (*s, FALSE);
|
||||||
|
else
|
||||||
|
operand = decode_operand (s);
|
||||||
|
if (!operand && opcode->pinfo != INSN_MACRO)
|
||||||
{
|
{
|
||||||
as_bad (_("internal: unknown operand type: %s %s"),
|
as_bad (_("internal: unknown operand type: %s %s"),
|
||||||
opcode->name, opcode->args);
|
opcode->name, opcode->args);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
used_bits |= ((1 << operand->size) - 1) << operand->lsb;
|
gas_assert (opno < MAX_OPERANDS);
|
||||||
if (operand->type == OP_MDMX_IMM_REG)
|
operands->operand[opno] = operand;
|
||||||
/* Bit 5 is the format selector (OB vs QH). The opcode table
|
if (operand)
|
||||||
has separate entries for each format. */
|
{
|
||||||
used_bits &= ~(1 << (operand->lsb + 5));
|
used_bits |= ((1 << operand->size) - 1) << operand->lsb;
|
||||||
|
if (operand->type == OP_MDMX_IMM_REG)
|
||||||
|
/* Bit 5 is the format selector (OB vs QH). The opcode table
|
||||||
|
has separate entries for each format. */
|
||||||
|
used_bits &= ~(1 << (operand->lsb + 5));
|
||||||
|
if (operand->type == OP_ENTRY_EXIT_LIST)
|
||||||
|
used_bits &= ~(mask & 0x700);
|
||||||
|
}
|
||||||
/* Skip prefix characters. */
|
/* Skip prefix characters. */
|
||||||
if (*s == '+' || *s == 'm')
|
if (decode_operand && (*s == '+' || *s == 'm'))
|
||||||
++s;
|
++s;
|
||||||
|
opno += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
doubled = used_bits & opcode->mask & insn_bits;
|
doubled = used_bits & mask & insn_bits;
|
||||||
if (doubled)
|
if (doubled)
|
||||||
{
|
{
|
||||||
as_bad (_("internal: bad mips opcode (bits 0x%08lx doubly defined):"
|
as_bad (_("internal: bad mips opcode (bits 0x%08lx doubly defined):"
|
||||||
" %s %s"), doubled, opcode->name, opcode->args);
|
" %s %s"), doubled, opcode->name, opcode->args);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
used_bits |= opcode->mask;
|
used_bits |= mask;
|
||||||
undefined = ~used_bits & insn_bits;
|
undefined = ~used_bits & insn_bits;
|
||||||
if (undefined)
|
if (opcode->pinfo != INSN_MACRO && undefined)
|
||||||
{
|
{
|
||||||
as_bad (_("internal: bad mips opcode (bits 0x%08lx undefined): %s %s"),
|
as_bad (_("internal: bad mips opcode (bits 0x%08lx undefined): %s %s"),
|
||||||
undefined, opcode->name, opcode->args);
|
undefined, opcode->name, opcode->args);
|
||||||
|
@ -2904,15 +2959,40 @@ validate_mips_insn (const struct mips_opcode *opcode,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The MIPS16 version of validate_mips_insn. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
validate_mips16_insn (const struct mips_opcode *opcode,
|
||||||
|
struct mips_operand_array *operands)
|
||||||
|
{
|
||||||
|
if (opcode->args[0] == 'a' || opcode->args[0] == 'i')
|
||||||
|
{
|
||||||
|
/* In this case OPCODE defines the first 16 bits in a 32-bit jump
|
||||||
|
instruction. Use TMP to describe the full instruction. */
|
||||||
|
struct mips_opcode tmp;
|
||||||
|
|
||||||
|
tmp = *opcode;
|
||||||
|
tmp.match <<= 16;
|
||||||
|
tmp.mask <<= 16;
|
||||||
|
return validate_mips_insn (&tmp, 0xffffffff, 0, operands);
|
||||||
|
}
|
||||||
|
return validate_mips_insn (opcode, 0xffff, 0, operands);
|
||||||
|
}
|
||||||
|
|
||||||
/* The microMIPS version of validate_mips_insn. */
|
/* The microMIPS version of validate_mips_insn. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
validate_micromips_insn (const struct mips_opcode *opc)
|
validate_micromips_insn (const struct mips_opcode *opc,
|
||||||
|
struct mips_operand_array *operands)
|
||||||
{
|
{
|
||||||
unsigned long insn_bits;
|
unsigned long insn_bits;
|
||||||
unsigned long major;
|
unsigned long major;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
|
||||||
|
if (opc->pinfo == INSN_MACRO)
|
||||||
|
return validate_mips_insn (opc, 0xffffffff, decode_micromips_operand,
|
||||||
|
operands);
|
||||||
|
|
||||||
length = micromips_insn_length (opc);
|
length = micromips_insn_length (opc);
|
||||||
if (length != 2 && length != 4)
|
if (length != 2 && length != 4)
|
||||||
{
|
{
|
||||||
|
@ -2933,7 +3013,8 @@ validate_micromips_insn (const struct mips_opcode *opc)
|
||||||
insn_bits = 1 << 4 * length;
|
insn_bits = 1 << 4 * length;
|
||||||
insn_bits <<= 4 * length;
|
insn_bits <<= 4 * length;
|
||||||
insn_bits -= 1;
|
insn_bits -= 1;
|
||||||
return validate_mips_insn (opc, insn_bits, decode_micromips_operand);
|
return validate_mips_insn (opc, insn_bits, decode_micromips_operand,
|
||||||
|
operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called once, at assembler startup time. It should set up
|
/* This function is called once, at assembler startup time. It should set up
|
||||||
|
@ -2958,6 +3039,7 @@ md_begin (void)
|
||||||
|
|
||||||
op_hash = hash_new ();
|
op_hash = hash_new ();
|
||||||
|
|
||||||
|
mips_operands = XCNEWVEC (struct mips_operand_array, NUMOPCODES);
|
||||||
for (i = 0; i < NUMOPCODES;)
|
for (i = 0; i < NUMOPCODES;)
|
||||||
{
|
{
|
||||||
const char *name = mips_opcodes[i].name;
|
const char *name = mips_opcodes[i].name;
|
||||||
|
@ -2972,18 +3054,15 @@ md_begin (void)
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (mips_opcodes[i].pinfo != INSN_MACRO)
|
if (!validate_mips_insn (&mips_opcodes[i], 0xffffffff,
|
||||||
|
decode_mips_operand, &mips_operands[i]))
|
||||||
|
broken = 1;
|
||||||
|
if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
|
||||||
{
|
{
|
||||||
if (!validate_mips_insn (&mips_opcodes[i], 0xffffffff,
|
create_insn (&nop_insn, mips_opcodes + i);
|
||||||
decode_mips_operand))
|
if (mips_fix_loongson2f_nop)
|
||||||
broken = 1;
|
nop_insn.insn_opcode = LOONGSON2F_NOP_INSN;
|
||||||
if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
|
nop_insn.fixed_p = 1;
|
||||||
{
|
|
||||||
create_insn (&nop_insn, mips_opcodes + i);
|
|
||||||
if (mips_fix_loongson2f_nop)
|
|
||||||
nop_insn.insn_opcode = LOONGSON2F_NOP_INSN;
|
|
||||||
nop_insn.fixed_p = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -2991,6 +3070,8 @@ md_begin (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
mips16_op_hash = hash_new ();
|
mips16_op_hash = hash_new ();
|
||||||
|
mips16_operands = XCNEWVEC (struct mips_operand_array,
|
||||||
|
bfd_mips16_num_opcodes);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < bfd_mips16_num_opcodes)
|
while (i < bfd_mips16_num_opcodes)
|
||||||
|
@ -3003,14 +3084,8 @@ md_begin (void)
|
||||||
mips16_opcodes[i].name, retval);
|
mips16_opcodes[i].name, retval);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (mips16_opcodes[i].pinfo != INSN_MACRO
|
if (!validate_mips16_insn (&mips16_opcodes[i], &mips16_operands[i]))
|
||||||
&& ((mips16_opcodes[i].match & mips16_opcodes[i].mask)
|
broken = 1;
|
||||||
!= mips16_opcodes[i].match))
|
|
||||||
{
|
|
||||||
fprintf (stderr, _("internal error: bad mips16 opcode: %s %s\n"),
|
|
||||||
mips16_opcodes[i].name, mips16_opcodes[i].args);
|
|
||||||
broken = 1;
|
|
||||||
}
|
|
||||||
if (mips16_nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
|
if (mips16_nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
|
||||||
{
|
{
|
||||||
create_insn (&mips16_nop_insn, mips16_opcodes + i);
|
create_insn (&mips16_nop_insn, mips16_opcodes + i);
|
||||||
|
@ -3023,6 +3098,8 @@ md_begin (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
micromips_op_hash = hash_new ();
|
micromips_op_hash = hash_new ();
|
||||||
|
micromips_operands = XCNEWVEC (struct mips_operand_array,
|
||||||
|
bfd_micromips_num_opcodes);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < bfd_micromips_num_opcodes)
|
while (i < bfd_micromips_num_opcodes)
|
||||||
|
@ -3035,27 +3112,30 @@ md_begin (void)
|
||||||
as_fatal (_("internal: can't hash `%s': %s"),
|
as_fatal (_("internal: can't hash `%s': %s"),
|
||||||
micromips_opcodes[i].name, retval);
|
micromips_opcodes[i].name, retval);
|
||||||
do
|
do
|
||||||
if (micromips_opcodes[i].pinfo != INSN_MACRO)
|
{
|
||||||
{
|
struct mips_cl_insn *micromips_nop_insn;
|
||||||
struct mips_cl_insn *micromips_nop_insn;
|
|
||||||
|
|
||||||
if (!validate_micromips_insn (µmips_opcodes[i]))
|
if (!validate_micromips_insn (µmips_opcodes[i],
|
||||||
broken = 1;
|
µmips_operands[i]))
|
||||||
|
broken = 1;
|
||||||
|
|
||||||
if (micromips_insn_length (micromips_opcodes + i) == 2)
|
if (micromips_opcodes[i].pinfo != INSN_MACRO)
|
||||||
micromips_nop_insn = µmips_nop16_insn;
|
{
|
||||||
else if (micromips_insn_length (micromips_opcodes + i) == 4)
|
if (micromips_insn_length (micromips_opcodes + i) == 2)
|
||||||
micromips_nop_insn = µmips_nop32_insn;
|
micromips_nop_insn = µmips_nop16_insn;
|
||||||
else
|
else if (micromips_insn_length (micromips_opcodes + i) == 4)
|
||||||
continue;
|
micromips_nop_insn = µmips_nop32_insn;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
if (micromips_nop_insn->insn_mo == NULL
|
if (micromips_nop_insn->insn_mo == NULL
|
||||||
&& strcmp (name, "nop") == 0)
|
&& strcmp (name, "nop") == 0)
|
||||||
{
|
{
|
||||||
create_insn (micromips_nop_insn, micromips_opcodes + i);
|
create_insn (micromips_nop_insn, micromips_opcodes + i);
|
||||||
micromips_nop_insn->fixed_p = 1;
|
micromips_nop_insn->fixed_p = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while (++i < bfd_micromips_num_opcodes
|
while (++i < bfd_micromips_num_opcodes
|
||||||
&& strcmp (micromips_opcodes[i].name, name) == 0);
|
&& strcmp (micromips_opcodes[i].name, name) == 0);
|
||||||
}
|
}
|
||||||
|
@ -3580,26 +3660,116 @@ get_delay_slot_nop (const struct mips_cl_insn *ip)
|
||||||
return NOP_INSN;
|
return NOP_INSN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the mask of core registers that IP reads or writes. */
|
/* Return a mask that has bit N set if OPCODE reads the register(s)
|
||||||
|
in operand N. */
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
gpr_mod_mask (const struct mips_cl_insn *ip)
|
insn_read_mask (const struct mips_opcode *opcode)
|
||||||
{
|
{
|
||||||
unsigned long pinfo2;
|
return (opcode->pinfo & INSN_READ_ALL) >> INSN_READ_SHIFT;
|
||||||
unsigned int mask;
|
}
|
||||||
|
|
||||||
mask = 0;
|
/* Return a mask that has bit N set if OPCODE writes to the register(s)
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
in operand N. */
|
||||||
if (mips_opts.micromips)
|
|
||||||
|
static unsigned int
|
||||||
|
insn_write_mask (const struct mips_opcode *opcode)
|
||||||
|
{
|
||||||
|
return (opcode->pinfo & INSN_WRITE_ALL) >> INSN_WRITE_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a mask of the registers specified by operand OPERAND of INSN.
|
||||||
|
Ignore registers of type OP_REG_<t> unless bit OP_REG_<t> of TYPE_MASK
|
||||||
|
is set. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
operand_reg_mask (const struct mips_cl_insn *insn,
|
||||||
|
const struct mips_operand *operand,
|
||||||
|
unsigned int type_mask)
|
||||||
|
{
|
||||||
|
unsigned int uval, vsel;
|
||||||
|
|
||||||
|
switch (operand->type)
|
||||||
{
|
{
|
||||||
if (pinfo2 & INSN2_MOD_GPR_MD)
|
case OP_INT:
|
||||||
mask |= 1 << micromips_to_32_reg_d_map[EXTRACT_OPERAND (1, MD, *ip)];
|
case OP_MAPPED_INT:
|
||||||
if (pinfo2 & INSN2_MOD_GPR_MF)
|
case OP_MSB:
|
||||||
mask |= 1 << micromips_to_32_reg_f_map[EXTRACT_OPERAND (1, MF, *ip)];
|
case OP_PCREL:
|
||||||
|
case OP_PERF_REG:
|
||||||
|
case OP_ADDIUSP_INT:
|
||||||
|
case OP_ENTRY_EXIT_LIST:
|
||||||
|
case OP_REPEAT_DEST_REG:
|
||||||
|
case OP_REPEAT_PREV_REG:
|
||||||
|
case OP_PC:
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
case OP_REG:
|
||||||
|
{
|
||||||
|
const struct mips_reg_operand *reg_op;
|
||||||
|
|
||||||
|
reg_op = (const struct mips_reg_operand *) operand;
|
||||||
|
if (!(type_mask & (1 << reg_op->reg_type)))
|
||||||
|
return 0;
|
||||||
|
uval = insn_extract_operand (insn, operand);
|
||||||
|
return 1 << mips_decode_reg_operand (reg_op, uval);
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_REG_PAIR:
|
||||||
|
{
|
||||||
|
const struct mips_reg_pair_operand *pair_op;
|
||||||
|
|
||||||
|
pair_op = (const struct mips_reg_pair_operand *) operand;
|
||||||
|
if (!(type_mask & (1 << pair_op->reg_type)))
|
||||||
|
return 0;
|
||||||
|
uval = insn_extract_operand (insn, operand);
|
||||||
|
return (1 << pair_op->reg1_map[uval]) | (1 << pair_op->reg2_map[uval]);
|
||||||
|
}
|
||||||
|
|
||||||
|
case OP_CLO_CLZ_DEST:
|
||||||
|
if (!(type_mask & (1 << OP_REG_GP)))
|
||||||
|
return 0;
|
||||||
|
uval = insn_extract_operand (insn, operand);
|
||||||
|
return (1 << (uval & 31)) | (1 << (uval >> 5));
|
||||||
|
|
||||||
|
case OP_LWM_SWM_LIST:
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
case OP_SAVE_RESTORE_LIST:
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
case OP_MDMX_IMM_REG:
|
||||||
|
if (!(type_mask & (1 << OP_REG_VEC)))
|
||||||
|
return 0;
|
||||||
|
uval = insn_extract_operand (insn, operand);
|
||||||
|
vsel = uval >> 5;
|
||||||
|
if ((vsel & 0x18) == 0x18)
|
||||||
|
return 0;
|
||||||
|
return 1 << (uval & 31);
|
||||||
}
|
}
|
||||||
if (pinfo2 & INSN2_MOD_SP)
|
abort ();
|
||||||
mask |= 1 << SP;
|
}
|
||||||
return mask;
|
|
||||||
|
/* Return a mask of the registers specified by operands OPNO_MASK of INSN,
|
||||||
|
where bit N of OPNO_MASK is set if operand N should be included.
|
||||||
|
Ignore registers of type OP_REG_<t> unless bit OP_REG_<t> of TYPE_MASK
|
||||||
|
is set. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
insn_reg_mask (const struct mips_cl_insn *insn,
|
||||||
|
unsigned int type_mask, unsigned int opno_mask)
|
||||||
|
{
|
||||||
|
unsigned int opno, reg_mask;
|
||||||
|
|
||||||
|
opno = 0;
|
||||||
|
reg_mask = 0;
|
||||||
|
while (opno_mask != 0)
|
||||||
|
{
|
||||||
|
if (opno_mask & 1)
|
||||||
|
reg_mask |= operand_reg_mask (insn, insn_opno (insn, opno), type_mask);
|
||||||
|
opno_mask >>= 1;
|
||||||
|
opno += 1;
|
||||||
|
}
|
||||||
|
return reg_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the mask of core registers that IP reads. */
|
/* Return the mask of core registers that IP reads. */
|
||||||
|
@ -3610,60 +3780,24 @@ gpr_read_mask (const struct mips_cl_insn *ip)
|
||||||
unsigned long pinfo, pinfo2;
|
unsigned long pinfo, pinfo2;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
|
|
||||||
mask = gpr_mod_mask (ip);
|
mask = insn_reg_mask (ip, 1 << OP_REG_GP, insn_read_mask (ip->insn_mo));
|
||||||
pinfo = ip->insn_mo->pinfo;
|
pinfo = ip->insn_mo->pinfo;
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
pinfo2 = ip->insn_mo->pinfo2;
|
||||||
if (mips_opts.mips16)
|
if (pinfo & INSN_UDI)
|
||||||
{
|
{
|
||||||
if (pinfo & MIPS16_INSN_READ_X)
|
/* UDI instructions have traditionally been assumed to read RS
|
||||||
mask |= 1 << mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RX, *ip)];
|
and RT. */
|
||||||
if (pinfo & MIPS16_INSN_READ_Y)
|
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
|
||||||
mask |= 1 << mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RY, *ip)];
|
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
|
||||||
if (pinfo & MIPS16_INSN_READ_T)
|
|
||||||
mask |= 1 << TREG;
|
|
||||||
if (pinfo & MIPS16_INSN_READ_SP)
|
|
||||||
mask |= 1 << SP;
|
|
||||||
if (pinfo & MIPS16_INSN_READ_Z)
|
|
||||||
mask |= 1 << (mips16_to_32_reg_map
|
|
||||||
[MIPS16_EXTRACT_OPERAND (MOVE32Z, *ip)]);
|
|
||||||
if (pinfo & MIPS16_INSN_READ_GPR_X)
|
|
||||||
mask |= 1 << MIPS16_EXTRACT_OPERAND (REGR32, *ip);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_D)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
|
|
||||||
if (pinfo & INSN_READ_GPR_T)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
|
|
||||||
if (pinfo & INSN_READ_GPR_S)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
|
|
||||||
if (pinfo2 & INSN2_READ_GP)
|
|
||||||
mask |= 1 << GP;
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_Z)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
|
|
||||||
}
|
}
|
||||||
|
if (pinfo & INSN_READ_GPR_24)
|
||||||
|
mask |= 1 << 24;
|
||||||
|
if (pinfo2 & INSN2_READ_GPR_16)
|
||||||
|
mask |= 1 << 16;
|
||||||
|
if (pinfo2 & INSN2_READ_SP)
|
||||||
|
mask |= 1 << SP;
|
||||||
if (pinfo2 & INSN2_READ_GPR_31)
|
if (pinfo2 & INSN2_READ_GPR_31)
|
||||||
mask |= 1 << RA;
|
mask |= 1 << 31;
|
||||||
if (mips_opts.micromips)
|
|
||||||
{
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MC)
|
|
||||||
mask |= 1 << micromips_to_32_reg_c_map[EXTRACT_OPERAND (1, MC, *ip)];
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_ME)
|
|
||||||
mask |= 1 << micromips_to_32_reg_e_map[EXTRACT_OPERAND (1, ME, *ip)];
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MG)
|
|
||||||
mask |= 1 << micromips_to_32_reg_g_map[EXTRACT_OPERAND (1, MG, *ip)];
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MJ)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (1, MJ, *ip);
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MMN)
|
|
||||||
{
|
|
||||||
mask |= 1 << micromips_to_32_reg_m_map[EXTRACT_OPERAND (1, MM, *ip)];
|
|
||||||
mask |= 1 << micromips_to_32_reg_n_map[EXTRACT_OPERAND (1, MN, *ip)];
|
|
||||||
}
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MP)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (1, MP, *ip);
|
|
||||||
if (pinfo2 & INSN2_READ_GPR_MQ)
|
|
||||||
mask |= 1 << micromips_to_32_reg_q_map[EXTRACT_OPERAND (1, MQ, *ip)];
|
|
||||||
}
|
|
||||||
/* Don't include register 0. */
|
/* Don't include register 0. */
|
||||||
return mask & ~1;
|
return mask & ~1;
|
||||||
}
|
}
|
||||||
|
@ -3676,51 +3810,18 @@ gpr_write_mask (const struct mips_cl_insn *ip)
|
||||||
unsigned long pinfo, pinfo2;
|
unsigned long pinfo, pinfo2;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
|
|
||||||
mask = gpr_mod_mask (ip);
|
mask = insn_reg_mask (ip, 1 << OP_REG_GP, insn_write_mask (ip->insn_mo));
|
||||||
pinfo = ip->insn_mo->pinfo;
|
pinfo = ip->insn_mo->pinfo;
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
pinfo2 = ip->insn_mo->pinfo2;
|
||||||
if (mips_opts.mips16)
|
if (pinfo & INSN_WRITE_GPR_24)
|
||||||
{
|
mask |= 1 << 24;
|
||||||
if (pinfo & MIPS16_INSN_WRITE_X)
|
if (pinfo & INSN_WRITE_GPR_31)
|
||||||
mask |= 1 << mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RX, *ip)];
|
mask |= 1 << 31;
|
||||||
if (pinfo & MIPS16_INSN_WRITE_Y)
|
if (pinfo & INSN_UDI)
|
||||||
mask |= 1 << mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RY, *ip)];
|
/* UDI instructions have traditionally been assumed to write to RD. */
|
||||||
if (pinfo & MIPS16_INSN_WRITE_Z)
|
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
|
||||||
mask |= 1 << mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RZ, *ip)];
|
if (pinfo2 & INSN2_WRITE_SP)
|
||||||
if (pinfo & MIPS16_INSN_WRITE_T)
|
mask |= 1 << SP;
|
||||||
mask |= 1 << TREG;
|
|
||||||
if (pinfo & MIPS16_INSN_WRITE_31)
|
|
||||||
mask |= 1 << RA;
|
|
||||||
if (pinfo & MIPS16_INSN_WRITE_GPR_Y)
|
|
||||||
mask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pinfo & INSN_WRITE_GPR_D)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
|
|
||||||
if (pinfo & INSN_WRITE_GPR_T)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
|
|
||||||
if (pinfo & INSN_WRITE_GPR_S)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
|
|
||||||
if (pinfo & INSN_WRITE_GPR_31)
|
|
||||||
mask |= 1 << RA;
|
|
||||||
if (pinfo2 & INSN2_WRITE_GPR_Z)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
|
|
||||||
}
|
|
||||||
if (mips_opts.micromips)
|
|
||||||
{
|
|
||||||
if (pinfo2 & INSN2_WRITE_GPR_MB)
|
|
||||||
mask |= 1 << micromips_to_32_reg_b_map[EXTRACT_OPERAND (1, MB, *ip)];
|
|
||||||
if (pinfo2 & INSN2_WRITE_GPR_MH)
|
|
||||||
{
|
|
||||||
mask |= 1 << micromips_to_32_reg_h_map1[EXTRACT_OPERAND (1, MH, *ip)];
|
|
||||||
mask |= 1 << micromips_to_32_reg_h_map2[EXTRACT_OPERAND (1, MH, *ip)];
|
|
||||||
}
|
|
||||||
if (pinfo2 & INSN2_WRITE_GPR_MJ)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (1, MJ, *ip);
|
|
||||||
if (pinfo2 & INSN2_WRITE_GPR_MP)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (1, MP, *ip);
|
|
||||||
}
|
|
||||||
/* Don't include register 0. */
|
/* Don't include register 0. */
|
||||||
return mask & ~1;
|
return mask & ~1;
|
||||||
}
|
}
|
||||||
|
@ -3730,25 +3831,12 @@ gpr_write_mask (const struct mips_cl_insn *ip)
|
||||||
static unsigned int
|
static unsigned int
|
||||||
fpr_read_mask (const struct mips_cl_insn *ip)
|
fpr_read_mask (const struct mips_cl_insn *ip)
|
||||||
{
|
{
|
||||||
unsigned long pinfo, pinfo2;
|
unsigned long pinfo;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
|
|
||||||
mask = 0;
|
mask = insn_reg_mask (ip, (1 << OP_REG_FP) | (1 << OP_REG_VEC),
|
||||||
|
insn_read_mask (ip->insn_mo));
|
||||||
pinfo = ip->insn_mo->pinfo;
|
pinfo = ip->insn_mo->pinfo;
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
|
||||||
if (!mips_opts.mips16)
|
|
||||||
{
|
|
||||||
if (pinfo2 & INSN2_READ_FPR_D)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
|
|
||||||
if (pinfo & INSN_READ_FPR_S)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FS, *ip);
|
|
||||||
if (pinfo & INSN_READ_FPR_T)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FT, *ip);
|
|
||||||
if (pinfo & INSN_READ_FPR_R)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FR, *ip);
|
|
||||||
if (pinfo2 & INSN2_READ_FPR_Z)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FZ, *ip);
|
|
||||||
}
|
|
||||||
/* Conservatively treat all operands to an FP_D instruction are doubles.
|
/* Conservatively treat all operands to an FP_D instruction are doubles.
|
||||||
(This is overly pessimistic for things like cvt.d.s.) */
|
(This is overly pessimistic for things like cvt.d.s.) */
|
||||||
if (HAVE_32BIT_FPRS && (pinfo & FP_D))
|
if (HAVE_32BIT_FPRS && (pinfo & FP_D))
|
||||||
|
@ -3761,23 +3849,12 @@ fpr_read_mask (const struct mips_cl_insn *ip)
|
||||||
static unsigned int
|
static unsigned int
|
||||||
fpr_write_mask (const struct mips_cl_insn *ip)
|
fpr_write_mask (const struct mips_cl_insn *ip)
|
||||||
{
|
{
|
||||||
unsigned long pinfo, pinfo2;
|
unsigned long pinfo;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
|
|
||||||
mask = 0;
|
mask = insn_reg_mask (ip, (1 << OP_REG_FP) | (1 << OP_REG_VEC),
|
||||||
|
insn_write_mask (ip->insn_mo));
|
||||||
pinfo = ip->insn_mo->pinfo;
|
pinfo = ip->insn_mo->pinfo;
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
|
||||||
if (!mips_opts.mips16)
|
|
||||||
{
|
|
||||||
if (pinfo & INSN_WRITE_FPR_D)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
|
|
||||||
if (pinfo & INSN_WRITE_FPR_S)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FS, *ip);
|
|
||||||
if (pinfo & INSN_WRITE_FPR_T)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FT, *ip);
|
|
||||||
if (pinfo2 & INSN2_WRITE_FPR_Z)
|
|
||||||
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FZ, *ip);
|
|
||||||
}
|
|
||||||
/* Conservatively treat all operands to an FP_D instruction are doubles.
|
/* Conservatively treat all operands to an FP_D instruction are doubles.
|
||||||
(This is overly pessimistic for things like cvt.s.d.) */
|
(This is overly pessimistic for things like cvt.s.d.) */
|
||||||
if (HAVE_32BIT_FPRS && (pinfo & FP_D))
|
if (HAVE_32BIT_FPRS && (pinfo & FP_D))
|
||||||
|
@ -5769,8 +5846,6 @@ static enum append_method
|
||||||
get_append_method (struct mips_cl_insn *ip, expressionS *address_expr,
|
get_append_method (struct mips_cl_insn *ip, expressionS *address_expr,
|
||||||
bfd_reloc_code_real_type *reloc_type)
|
bfd_reloc_code_real_type *reloc_type)
|
||||||
{
|
{
|
||||||
unsigned long pinfo, pinfo2;
|
|
||||||
|
|
||||||
/* The relaxed version of a macro sequence must be inherently
|
/* The relaxed version of a macro sequence must be inherently
|
||||||
hazard-free. */
|
hazard-free. */
|
||||||
if (mips_relax.sequence == 2)
|
if (mips_relax.sequence == 2)
|
||||||
|
@ -5787,12 +5862,9 @@ get_append_method (struct mips_cl_insn *ip, expressionS *address_expr,
|
||||||
&& can_swap_branch_p (ip, address_expr, reloc_type))
|
&& can_swap_branch_p (ip, address_expr, reloc_type))
|
||||||
return APPEND_SWAP;
|
return APPEND_SWAP;
|
||||||
|
|
||||||
pinfo = ip->insn_mo->pinfo;
|
|
||||||
pinfo2 = ip->insn_mo->pinfo2;
|
|
||||||
if (mips_opts.mips16
|
if (mips_opts.mips16
|
||||||
&& ISA_SUPPORTS_MIPS16E
|
&& ISA_SUPPORTS_MIPS16E
|
||||||
&& ((pinfo & MIPS16_INSN_READ_X) != 0
|
&& gpr_read_mask (ip) != 0)
|
||||||
|| (pinfo2 & INSN2_READ_GPR_31) != 0))
|
|
||||||
return APPEND_ADD_COMPACT;
|
return APPEND_ADD_COMPACT;
|
||||||
|
|
||||||
return APPEND_ADD_WITH_NOP;
|
return APPEND_ADD_WITH_NOP;
|
||||||
|
|
|
@ -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>
|
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
* mips.h (MIPS16_INSN_WRITE_SP, MIPS16_INSN_READ_31)
|
* 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 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.
|
/* PC-relative operand OPERAND has value UVAL and is relative to BASE_PC.
|
||||||
Return the address that it encodes. */
|
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
|
/* These are the bits which may be set in the pinfo field of an
|
||||||
instructions, if it is not equal to INSN_MACRO. */
|
instructions, if it is not equal to INSN_MACRO. */
|
||||||
|
|
||||||
/* Modifies the general purpose register in OP_*_RD. */
|
/* Writes to operand number N. */
|
||||||
#define INSN_WRITE_GPR_D 0x00000001
|
#define INSN_WRITE_SHIFT 0
|
||||||
/* Modifies the general purpose register in OP_*_RT. */
|
#define INSN_WRITE_1 0x00000001
|
||||||
#define INSN_WRITE_GPR_T 0x00000002
|
#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. */
|
/* Modifies general purpose register 31. */
|
||||||
#define INSN_WRITE_GPR_31 0x00000004
|
#define INSN_WRITE_GPR_31 0x00000040
|
||||||
/* 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
|
|
||||||
/* Modifies coprocessor condition code. */
|
/* Modifies coprocessor condition code. */
|
||||||
#define INSN_WRITE_COND_CODE 0x00000800
|
#define INSN_WRITE_COND_CODE 0x00000080
|
||||||
/* Reads coprocessor condition code. */
|
/* Reads coprocessor condition code. */
|
||||||
#define INSN_READ_COND_CODE 0x00001000
|
#define INSN_READ_COND_CODE 0x00000100
|
||||||
/* TLB operation. */
|
/* TLB operation. */
|
||||||
#define INSN_TLB 0x00002000
|
#define INSN_TLB 0x00000200
|
||||||
/* Reads coprocessor register other than floating point register. */
|
/* Reads coprocessor register other than floating point register. */
|
||||||
#define INSN_COP 0x00004000
|
#define INSN_COP 0x00000400
|
||||||
/* Instruction loads value from memory, requiring delay. */
|
/* 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. */
|
/* 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. */
|
/* Instruction has unconditional branch delay slot. */
|
||||||
#define INSN_UNCOND_BRANCH_DELAY 0x00020000
|
#define INSN_UNCOND_BRANCH_DELAY 0x00002000
|
||||||
/* Instruction has conditional branch delay slot. */
|
/* 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. */
|
/* 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. */
|
/* 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. */
|
/* Loads coprocessor register from memory, requiring delay. */
|
||||||
#define INSN_COPROC_MEMORY_DELAY 0x00200000
|
#define INSN_COPROC_MEMORY_DELAY 0x00020000
|
||||||
/* Reads the HI register. */
|
/* Reads the HI register. */
|
||||||
#define INSN_READ_HI 0x00400000
|
#define INSN_READ_HI 0x00040000
|
||||||
/* Reads the LO register. */
|
/* Reads the LO register. */
|
||||||
#define INSN_READ_LO 0x00800000
|
#define INSN_READ_LO 0x00080000
|
||||||
/* Modifies the HI register. */
|
/* Modifies the HI register. */
|
||||||
#define INSN_WRITE_HI 0x01000000
|
#define INSN_WRITE_HI 0x00100000
|
||||||
/* Modifies the LO register. */
|
/* 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
|
/* Not to be placed in a branch delay slot, either architecturally
|
||||||
or for ease of handling (such as with instructions that take a trap). */
|
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. */
|
/* Instruction stores value into memory. */
|
||||||
#define INSN_STORE_MEMORY 0x08000000
|
#define INSN_STORE_MEMORY 0x00800000
|
||||||
/* Instruction uses single precision floating point. */
|
/* Instruction uses single precision floating point. */
|
||||||
#define FP_S 0x10000000
|
#define FP_S 0x01000000
|
||||||
/* Instruction uses double precision floating point. */
|
/* Instruction uses double precision floating point. */
|
||||||
#define FP_D 0x20000000
|
#define FP_D 0x02000000
|
||||||
/* Instruction is part of the tx39's integer multiply family. */
|
/* Instruction is part of the tx39's integer multiply family. */
|
||||||
#define INSN_MULT 0x40000000
|
#define INSN_MULT 0x04000000
|
||||||
/* Modifies the general purpose register in MICROMIPSOP_*_RS. */
|
/* Reads general purpose register 24. */
|
||||||
#define INSN_WRITE_GPR_S 0x80000000
|
#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
|
/* Instruction is actually a macro. It should be ignored by the
|
||||||
disassembler, and requires special treatment by the assembler. */
|
disassembler, and requires special treatment by the assembler. */
|
||||||
#define INSN_MACRO 0xffffffff
|
#define INSN_MACRO 0xffffffff
|
||||||
|
@ -922,62 +929,24 @@ struct mips_opcode
|
||||||
only be set for macros. For instructions, FP_D in pinfo carries the
|
only be set for macros. For instructions, FP_D in pinfo carries the
|
||||||
same information. */
|
same information. */
|
||||||
#define INSN2_M_FP_D 0x00000010
|
#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. */
|
/* 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. */
|
/* Instruction has a branch delay slot that requires a 32-bit instruction. */
|
||||||
#define INSN2_BRANCH_DELAY_32BIT 0x00000800
|
#define INSN2_BRANCH_DELAY_32BIT 0x00000040
|
||||||
/* Reads the floating point register in MICROMIPSOP_*_FD. */
|
/* Writes to the stack pointer ($29). */
|
||||||
#define INSN2_READ_FPR_D 0x00001000
|
#define INSN2_WRITE_SP 0x00000080
|
||||||
/* Modifies the general purpose register in MICROMIPSOP_*_MB. */
|
/* Reads from the stack pointer ($29). */
|
||||||
#define INSN2_WRITE_GPR_MB 0x00002000
|
#define INSN2_READ_SP 0x00000100
|
||||||
/* 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
|
|
||||||
/* Reads the RA ($31) register. */
|
/* Reads the RA ($31) register. */
|
||||||
#define INSN2_READ_GPR_31 0x02000000
|
#define INSN2_READ_GPR_31 0x00000200
|
||||||
/* Reads the global pointer ($28). */
|
|
||||||
#define INSN2_READ_GP 0x04000000
|
|
||||||
/* Reads the program counter ($pc). */
|
/* Reads the program counter ($pc). */
|
||||||
#define INSN2_READ_PC 0x08000000
|
#define INSN2_READ_PC 0x00000400
|
||||||
/* Is an unconditional branch insn. */
|
/* Is an unconditional branch insn. */
|
||||||
#define INSN2_UNCOND_BRANCH 0x10000000
|
#define INSN2_UNCOND_BRANCH 0x00000800
|
||||||
/* Is a conditional branch insn. */
|
/* Is a conditional branch insn. */
|
||||||
#define INSN2_COND_BRANCH 0x20000000
|
#define INSN2_COND_BRANCH 0x00001000
|
||||||
/* Modifies the general purpose registers in MICROMIPSOP_*_MH. */
|
/* Reads from $16. This is true of the MIPS16 0x6500 nop. */
|
||||||
#define INSN2_WRITE_GPR_MH 0x40000000
|
#define INSN2_READ_GPR_16 0x00002000
|
||||||
/* Reads the general purpose registers in MICROMIPSOP_*_MM/N. */
|
|
||||||
#define INSN2_READ_GPR_MMN 0x80000000
|
|
||||||
|
|
||||||
/* Masks used to mark instructions to indicate which MIPS ISA level
|
/* Masks used to mark instructions to indicate which MIPS ISA level
|
||||||
they were introduced in. INSN_ISA_MASK masks an enumeration that
|
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_ARGS 0xe
|
||||||
#define MIPS16_ALL_STATICS 0xb
|
#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
|
/* The following flags have the same value for the mips16 opcode
|
||||||
table:
|
table:
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,33 @@
|
||||||
|
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
* mips16-opc.c (UBR, CBR, RD_31, RD_PC): Redefine as INSN2_* flags.
|
* mips16-opc.c (UBR, CBR, RD_31, RD_PC): Redefine as INSN2_* flags.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1003,8 +1003,7 @@ print_insn_arg (struct disassemble_info *info,
|
||||||
const struct mips_reg_operand *reg_op;
|
const struct mips_reg_operand *reg_op;
|
||||||
|
|
||||||
reg_op = (const struct mips_reg_operand *) operand;
|
reg_op = (const struct mips_reg_operand *) operand;
|
||||||
if (reg_op->reg_map)
|
uval = mips_decode_reg_operand (reg_op, uval);
|
||||||
uval = reg_op->reg_map[uval];
|
|
||||||
print_reg (info, opcode, reg_op->reg_type, uval);
|
print_reg (info, opcode, reg_op->reg_type, uval);
|
||||||
|
|
||||||
state->last_reg_type = reg_op->reg_type;
|
state->last_reg_type = reg_op->reg_type;
|
||||||
|
@ -1346,8 +1345,7 @@ print_insn_mips (bfd_vma memaddr,
|
||||||
/* Figure out instruction type and branch delay information. */
|
/* Figure out instruction type and branch delay information. */
|
||||||
if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
|
if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
|
||||||
{
|
{
|
||||||
if ((op->pinfo & (INSN_WRITE_GPR_31
|
if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
|
||||||
| INSN_WRITE_GPR_D)) != 0)
|
|
||||||
info->insn_type = dis_jsr;
|
info->insn_type = dis_jsr;
|
||||||
else
|
else
|
||||||
info->insn_type = dis_branch;
|
info->insn_type = dis_branch;
|
||||||
|
@ -1894,7 +1892,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
|
||||||
if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
|
if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
|
||||||
| (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
|
| (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
|
||||||
{
|
{
|
||||||
if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
|
if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
|
||||||
info->insn_type = dis_jsr;
|
info->insn_type = dis_jsr;
|
||||||
else
|
else
|
||||||
info->insn_type = dis_branch;
|
info->insn_type = dis_branch;
|
||||||
|
|
3404
opcodes/mips-opc.c
3404
opcodes/mips-opc.c
File diff suppressed because it is too large
Load Diff
|
@ -144,19 +144,18 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
|
||||||
|
|
||||||
#define UBD INSN_UNCOND_BRANCH_DELAY
|
#define UBD INSN_UNCOND_BRANCH_DELAY
|
||||||
|
|
||||||
#define WR_x MIPS16_INSN_WRITE_X
|
#define WR_1 INSN_WRITE_1
|
||||||
#define WR_y MIPS16_INSN_WRITE_Y
|
#define WR_2 INSN_WRITE_2
|
||||||
#define WR_z MIPS16_INSN_WRITE_Z
|
#define RD_1 INSN_READ_1
|
||||||
#define WR_T MIPS16_INSN_WRITE_T
|
#define RD_2 INSN_READ_2
|
||||||
#define WR_31 MIPS16_INSN_WRITE_31
|
#define RD_3 INSN_READ_3
|
||||||
#define WR_Y MIPS16_INSN_WRITE_GPR_Y
|
#define RD_4 INSN_READ_4
|
||||||
|
#define MOD_1 (WR_1|RD_1)
|
||||||
|
#define MOD_2 (WR_2|RD_2)
|
||||||
|
|
||||||
#define RD_x MIPS16_INSN_READ_X
|
#define RD_T INSN_READ_GPR_24
|
||||||
#define RD_y MIPS16_INSN_READ_Y
|
#define WR_T INSN_WRITE_GPR_24
|
||||||
#define RD_Z MIPS16_INSN_READ_Z
|
#define WR_31 INSN_WRITE_GPR_31
|
||||||
#define RD_T MIPS16_INSN_READ_T
|
|
||||||
#define RD_SP MIPS16_INSN_READ_SP
|
|
||||||
#define RD_X MIPS16_INSN_READ_GPR_X
|
|
||||||
|
|
||||||
#define WR_HI INSN_WRITE_HI
|
#define WR_HI INSN_WRITE_HI
|
||||||
#define WR_LO INSN_WRITE_LO
|
#define WR_LO INSN_WRITE_LO
|
||||||
|
@ -166,7 +165,10 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
|
||||||
#define NODS INSN_NO_DELAY_SLOT
|
#define NODS INSN_NO_DELAY_SLOT
|
||||||
#define TRAP INSN_NO_DELAY_SLOT
|
#define TRAP INSN_NO_DELAY_SLOT
|
||||||
|
|
||||||
#define MOD_SP INSN2_MOD_SP
|
#define RD_16 INSN2_READ_GPR_16
|
||||||
|
#define RD_SP INSN2_READ_SP
|
||||||
|
#define WR_SP INSN2_WRITE_SP
|
||||||
|
#define MOD_SP (RD_SP|WR_SP)
|
||||||
#define RD_31 INSN2_READ_GPR_31
|
#define RD_31 INSN2_READ_GPR_31
|
||||||
#define RD_PC INSN2_READ_PC
|
#define RD_PC INSN2_READ_PC
|
||||||
#define UBR INSN2_UNCOND_BRANCH
|
#define UBR INSN2_UNCOND_BRANCH
|
||||||
|
@ -181,27 +183,27 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
|
||||||
const struct mips_opcode mips16_opcodes[] =
|
const struct mips_opcode mips16_opcodes[] =
|
||||||
{
|
{
|
||||||
/* name, args, match, mask, pinfo, pinfo2, membership */
|
/* name, args, match, mask, pinfo, pinfo2, membership */
|
||||||
{"nop", "", 0x6500, 0xffff, RD_Z, 0, I1, 0, 0 }, /* move $0,$Z */
|
{"nop", "", 0x6500, 0xffff, 0, RD_16, I1, 0, 0 }, /* move $0,$Z */
|
||||||
{"la", "x,A", 0x0800, 0xf800, WR_x, RD_PC, I1, 0, 0 },
|
{"la", "x,A", 0x0800, 0xf800, WR_1, RD_PC, I1, 0, 0 },
|
||||||
{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, I1, 0, 0 },
|
{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"addiu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1, 0, 0 },
|
{"addiu", "y,x,4", 0x4000, 0xf810, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"addiu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1, 0, 0 },
|
{"addiu", "x,k", 0x4800, 0xf800, MOD_1, 0, I1, 0, 0 },
|
||||||
{"addiu", "S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
{"addiu", "S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
||||||
{"addiu", "S,S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
{"addiu", "S,S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
||||||
{"addiu", "x,P,V", 0x0800, 0xf800, WR_x, RD_PC, I1, 0, 0 },
|
{"addiu", "x,P,V", 0x0800, 0xf800, WR_1, RD_PC, I1, 0, 0 },
|
||||||
{"addiu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1, 0, 0 },
|
{"addiu", "x,S,V", 0x0000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
|
||||||
{"addu", "z,v,y", 0xe001, 0xf803, WR_z|RD_x|RD_y, 0, I1, 0, 0 },
|
{"addu", "z,v,y", 0xe001, 0xf803, WR_1|RD_2|RD_3, 0, I1, 0, 0 },
|
||||||
{"addu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1, 0, 0 },
|
{"addu", "y,x,4", 0x4000, 0xf810, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"addu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1, 0, 0 },
|
{"addu", "x,k", 0x4800, 0xf800, MOD_1, 0, I1, 0, 0 },
|
||||||
{"addu", "S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
{"addu", "S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
||||||
{"addu", "S,S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
{"addu", "S,S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
|
||||||
{"addu", "x,P,V", 0x0800, 0xf800, WR_x, RD_PC, I1, 0, 0 },
|
{"addu", "x,P,V", 0x0800, 0xf800, WR_1, RD_PC, I1, 0, 0 },
|
||||||
{"addu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1, 0, 0 },
|
{"addu", "x,S,V", 0x0000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
|
||||||
{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y, 0, I1, 0, 0 },
|
{"and", "x,y", 0xe80c, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"b", "q", 0x1000, 0xf800, 0, UBR, I1, 0, 0 },
|
{"b", "q", 0x1000, 0xf800, 0, UBR, I1, 0, 0 },
|
||||||
{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, I1, 0, 0 },
|
{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"beq", "x,I,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"beq", "x,I,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"beqz", "x,p", 0x2000, 0xf800, RD_x, CBR, I1, 0, 0 },
|
{"beqz", "x,p", 0x2000, 0xf800, RD_1, CBR, I1, 0, 0 },
|
||||||
{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, I1, 0, 0 },
|
{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"bge", "x,I,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"bge", "x,I,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1, 0, 0 },
|
{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
|
@ -220,52 +222,52 @@ const struct mips_opcode mips16_opcodes[] =
|
||||||
{"bltu", "x,I,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"bltu", "x,I,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1, 0, 0 },
|
{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"bne", "x,I,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"bne", "x,I,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"bnez", "x,p", 0x2800, 0xf800, RD_x, CBR, I1, 0, 0 },
|
{"bnez", "x,p", 0x2800, 0xf800, RD_1, CBR, I1, 0, 0 },
|
||||||
{"break", "6", 0xe805, 0xf81f, TRAP, 0, I1, 0, 0 },
|
{"break", "6", 0xe805, 0xf81f, TRAP, 0, I1, 0, 0 },
|
||||||
{"bteqz", "p", 0x6000, 0xff00, RD_T, CBR, I1, 0, 0 },
|
{"bteqz", "p", 0x6000, 0xff00, RD_T, CBR, I1, 0, 0 },
|
||||||
{"btnez", "p", 0x6100, 0xff00, RD_T, CBR, I1, 0, 0 },
|
{"btnez", "p", 0x6100, 0xff00, RD_T, CBR, I1, 0, 0 },
|
||||||
{"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"cmpi", "x,U", 0x7000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"cmp", "x,y", 0xe80a, 0xf81f, WR_T|RD_x|RD_y, 0, I1, 0, 0 },
|
{"cmp", "x,y", 0xe80a, 0xf81f, RD_1|RD_2|WR_T, 0, I1, 0, 0 },
|
||||||
{"cmp", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"cmp", "x,U", 0x7000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"dla", "y,E", 0xfe00, 0xff00, WR_y, RD_PC, I3, 0, 0 },
|
{"dla", "y,E", 0xfe00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
|
||||||
{"daddiu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, 0, I3, 0, 0 },
|
{"daddiu", "y,x,4", 0x4010, 0xf810, WR_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"daddiu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, 0, I3, 0, 0 },
|
{"daddiu", "y,j", 0xfd00, 0xff00, MOD_1, 0, I3, 0, 0 },
|
||||||
{"daddiu", "S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
{"daddiu", "S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
||||||
{"daddiu", "S,S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
{"daddiu", "S,S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
||||||
{"daddiu", "y,P,W", 0xfe00, 0xff00, WR_y, RD_PC, I3, 0, 0 },
|
{"daddiu", "y,P,W", 0xfe00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
|
||||||
{"daddiu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, 0, I3, 0, 0 },
|
{"daddiu", "y,S,W", 0xff00, 0xff00, WR_1, RD_SP, I3, 0, 0 },
|
||||||
{"daddu", "z,v,y", 0xe000, 0xf803, WR_z|RD_x|RD_y, 0, I3, 0, 0 },
|
{"daddu", "z,v,y", 0xe000, 0xf803, WR_1|RD_2|RD_3, 0, I3, 0, 0 },
|
||||||
{"daddu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, 0, I3, 0, 0 },
|
{"daddu", "y,x,4", 0x4010, 0xf810, WR_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"daddu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, 0, I3, 0, 0 },
|
{"daddu", "y,j", 0xfd00, 0xff00, MOD_1, 0, I3, 0, 0 },
|
||||||
{"daddu", "S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
{"daddu", "S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
||||||
{"daddu", "S,S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
{"daddu", "S,S,K", 0xfb00, 0xff00, 0, MOD_SP, I3, 0, 0 },
|
||||||
{"daddu", "y,P,W", 0xfe00, 0xff00, WR_y, RD_PC, I3, 0, 0 },
|
{"daddu", "y,P,W", 0xfe00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
|
||||||
{"daddu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, 0, I3, 0, 0 },
|
{"daddu", "y,S,W", 0xff00, 0xff00, WR_1, RD_SP, I3, 0, 0 },
|
||||||
{"ddiv", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"ddiv", "0,x,y", 0xe81e, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"ddivu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"ddivu", "0,x,y", 0xe81f, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"div", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"div", "0,x,y", 0xe81a, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"divu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"divu", "0,x,y", 0xe81b, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"dmul", "z,v,y", 0, (int) M_DMUL, INSN_MACRO, 0, I3, 0, 0 },
|
{"dmul", "z,v,y", 0, (int) M_DMUL, INSN_MACRO, 0, I3, 0, 0 },
|
||||||
{"dmult", "x,y", 0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"dmult", "x,y", 0xe81c, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"dmultu", "x,y", 0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"dmultu", "x,y", 0xe81d, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"drem", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"drem", "0,x,y", 0xe81e, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"dremu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3, 0, 0 },
|
{"dremu", "0,x,y", 0xe81f, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I3, 0, 0 },
|
||||||
{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"dsllv", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsllv", "y,x", 0xe814, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsll", "x,w,[", 0x3001, 0xf803, WR_x|RD_y, 0, I3, 0, 0 },
|
{"dsll", "x,w,[", 0x3001, 0xf803, WR_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsll", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsll", "y,x", 0xe814, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsrav", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsrav", "y,x", 0xe817, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsra", "y,]", 0xe813, 0xf81f, WR_y|RD_y, 0, I3, 0, 0 },
|
{"dsra", "y,]", 0xe813, 0xf81f, MOD_1, 0, I3, 0, 0 },
|
||||||
{"dsra", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsra", "y,x", 0xe817, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsrlv", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsrlv", "y,x", 0xe816, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsrl", "y,]", 0xe808, 0xf81f, WR_y|RD_y, 0, I3, 0, 0 },
|
{"dsrl", "y,]", 0xe808, 0xf81f, MOD_1, 0, I3, 0, 0 },
|
||||||
{"dsrl", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3, 0, 0 },
|
{"dsrl", "y,x", 0xe816, 0xf81f, MOD_1|RD_2, 0, I3, 0, 0 },
|
||||||
{"dsubu", "z,v,y", 0xe002, 0xf803, WR_z|RD_x|RD_y, 0, I3, 0, 0 },
|
{"dsubu", "z,v,y", 0xe002, 0xf803, WR_1|RD_2|RD_3, 0, I3, 0, 0 },
|
||||||
{"dsubu", "y,x,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"dsubu", "y,x,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"dsubu", "y,I", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1, 0, 0 },
|
{"dsubu", "y,I", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"exit", "L", 0xed09, 0xff1f, TRAP, 0, I1, 0, 0 },
|
{"exit", "L", 0xed09, 0xff1f, TRAP, 0, I1, 0, 0 },
|
||||||
|
@ -275,88 +277,88 @@ const struct mips_opcode mips16_opcodes[] =
|
||||||
{"entry", "", 0xe809, 0xffff, TRAP, 0, I1, 0, 0 },
|
{"entry", "", 0xe809, 0xffff, TRAP, 0, I1, 0, 0 },
|
||||||
{"entry", "l", 0xe809, 0xf81f, TRAP, 0, I1, 0, 0 },
|
{"entry", "l", 0xe809, 0xf81f, TRAP, 0, I1, 0, 0 },
|
||||||
{"extend", "e", 0xf000, 0xf800, 0, 0, I1, 0, 0 },
|
{"extend", "e", 0xf000, 0xf800, 0, 0, I1, 0, 0 },
|
||||||
{"jalr", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1, 0, 0 },
|
{"jalr", "x", 0xe840, 0xf8ff, RD_1|WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jalr", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1, 0, 0 },
|
{"jalr", "R,x", 0xe840, 0xf8ff, RD_2|WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1, 0, 0 },
|
{"jal", "x", 0xe840, 0xf8ff, RD_1|WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1, 0, 0 },
|
{"jal", "R,x", 0xe840, 0xf8ff, RD_2|WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jal", "a", 0x1800, 0xfc00, UBD|WR_31, 0, I1, 0, 0 },
|
{"jal", "a", 0x1800, 0xfc00, WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jalx", "i", 0x1c00, 0xfc00, UBD|WR_31, 0, I1, 0, 0 },
|
{"jalx", "i", 0x1c00, 0xfc00, WR_31|UBD, 0, I1, 0, 0 },
|
||||||
{"jr", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1, 0, 0 },
|
{"jr", "x", 0xe800, 0xf8ff, RD_1|UBD, 0, I1, 0, 0 },
|
||||||
{"jr", "R", 0xe820, 0xffff, UBD, RD_31, I1, 0, 0 },
|
{"jr", "R", 0xe820, 0xffff, UBD, RD_31, I1, 0, 0 },
|
||||||
{"j", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1, 0, 0 },
|
{"j", "x", 0xe800, 0xf8ff, RD_1|UBD, 0, I1, 0, 0 },
|
||||||
{"j", "R", 0xe820, 0xffff, UBD, RD_31, I1, 0, 0 },
|
{"j", "R", 0xe820, 0xffff, UBD, RD_31, I1, 0, 0 },
|
||||||
/* MIPS16e compact branches. We keep them near the ordinary branches
|
/* MIPS16e compact branches. We keep them near the ordinary branches
|
||||||
so that we easily find them when converting a normal branch to a
|
so that we easily find them when converting a normal branch to a
|
||||||
compact one. */
|
compact one. */
|
||||||
{"jalrc", "x", 0xe8c0, 0xf8ff, WR_31|RD_x|NODS, UBR, I32, 0, 0 },
|
{"jalrc", "x", 0xe8c0, 0xf8ff, RD_1|WR_31|NODS, UBR, I32, 0, 0 },
|
||||||
{"jalrc", "R,x", 0xe8c0, 0xf8ff, WR_31|RD_x|NODS, UBR, I32, 0, 0 },
|
{"jalrc", "R,x", 0xe8c0, 0xf8ff, RD_2|WR_31|NODS, UBR, I32, 0, 0 },
|
||||||
{"jrc", "x", 0xe880, 0xf8ff, RD_x|NODS, UBR, I32, 0, 0 },
|
{"jrc", "x", 0xe880, 0xf8ff, RD_1|NODS, UBR, I32, 0, 0 },
|
||||||
{"jrc", "R", 0xe8a0, 0xffff, NODS, UBR|RD_31, I32, 0, 0 },
|
{"jrc", "R", 0xe8a0, 0xffff, NODS, RD_31|UBR, I32, 0, 0 },
|
||||||
{"lb", "y,5(x)", 0x8000, 0xf800, WR_y|RD_x, 0, I1, 0, 0 },
|
{"lb", "y,5(x)", 0x8000, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"lbu", "y,5(x)", 0xa000, 0xf800, WR_y|RD_x, 0, I1, 0, 0 },
|
{"lbu", "y,5(x)", 0xa000, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"ld", "y,D(x)", 0x3800, 0xf800, WR_y|RD_x, 0, I3, 0, 0 },
|
{"ld", "y,D(x)", 0x3800, 0xf800, WR_1|RD_3, 0, I3, 0, 0 },
|
||||||
{"ld", "y,B", 0xfc00, 0xff00, WR_y, RD_PC, I3, 0, 0 },
|
{"ld", "y,B", 0xfc00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
|
||||||
{"ld", "y,D(P)", 0xfc00, 0xff00, WR_y, RD_PC, I3, 0, 0 },
|
{"ld", "y,D(P)", 0xfc00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
|
||||||
{"ld", "y,D(S)", 0xf800, 0xff00, WR_y|RD_SP, 0, I3, 0, 0 },
|
{"ld", "y,D(S)", 0xf800, 0xff00, WR_1, RD_SP, I3, 0, 0 },
|
||||||
{"lh", "y,H(x)", 0x8800, 0xf800, WR_y|RD_x, 0, I1, 0, 0 },
|
{"lh", "y,H(x)", 0x8800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"lhu", "y,H(x)", 0xa800, 0xf800, WR_y|RD_x, 0, I1, 0, 0 },
|
{"lhu", "y,H(x)", 0xa800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"li", "x,U", 0x6800, 0xf800, WR_x, 0, I1, 0, 0 },
|
{"li", "x,U", 0x6800, 0xf800, WR_1, 0, I1, 0, 0 },
|
||||||
{"lw", "y,W(x)", 0x9800, 0xf800, WR_y|RD_x, 0, I1, 0, 0 },
|
{"lw", "y,W(x)", 0x9800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"lw", "x,A", 0xb000, 0xf800, WR_x, RD_PC, I1, 0, 0 },
|
{"lw", "x,A", 0xb000, 0xf800, WR_1, RD_PC, I1, 0, 0 },
|
||||||
{"lw", "x,V(P)", 0xb000, 0xf800, WR_x, RD_PC, I1, 0, 0 },
|
{"lw", "x,V(P)", 0xb000, 0xf800, WR_1, RD_PC, I1, 0, 0 },
|
||||||
{"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP, 0, I1, 0, 0 },
|
{"lw", "x,V(S)", 0x9000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
|
||||||
{"lwu", "y,W(x)", 0xb800, 0xf800, WR_y|RD_x, 0, I3, 0, 0 },
|
{"lwu", "y,W(x)", 0xb800, 0xf800, WR_1|RD_3, 0, I3, 0, 0 },
|
||||||
{"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI, 0, I1, 0, 0 },
|
{"mfhi", "x", 0xe810, 0xf8ff, WR_1|RD_HI, 0, I1, 0, 0 },
|
||||||
{"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO, 0, I1, 0, 0 },
|
{"mflo", "x", 0xe812, 0xf8ff, WR_1|RD_LO, 0, I1, 0, 0 },
|
||||||
{"move", "y,X", 0x6700, 0xff00, WR_y|RD_X, 0, I1, 0, 0 },
|
{"move", "y,X", 0x6700, 0xff00, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z, 0, I1, 0, 0 },
|
{"move", "Y,Z", 0x6500, 0xff00, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1, 0, 0 },
|
{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"mult", "x,y", 0xe818, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"multu", "x,y", 0xe819, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"neg", "x,w", 0xe80b, 0xf81f, WR_x|RD_y, 0, I1, 0, 0 },
|
{"neg", "x,w", 0xe80b, 0xf81f, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"not", "x,w", 0xe80f, 0xf81f, WR_x|RD_y, 0, I1, 0, 0 },
|
{"not", "x,w", 0xe80f, 0xf81f, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"or", "x,y", 0xe80d, 0xf81f, WR_x|RD_x|RD_y, 0, I1, 0, 0 },
|
{"or", "x,y", 0xe80d, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"rem", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"rem", "0,x,y", 0xe81a, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"remu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1, 0, 0 },
|
{"remu", "0,x,y", 0xe81b, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, 0, I1, 0, 0 },
|
||||||
{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO, 0, I1, 0, 0 },
|
{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"sb", "y,5(x)", 0xc000, 0xf800, RD_y|RD_x, 0, I1, 0, 0 },
|
{"sb", "y,5(x)", 0xc000, 0xf800, RD_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"sd", "y,D(x)", 0x7800, 0xf800, RD_y|RD_x, 0, I3, 0, 0 },
|
{"sd", "y,D(x)", 0x7800, 0xf800, RD_1|RD_3, 0, I3, 0, 0 },
|
||||||
{"sd", "y,D(S)", 0xf900, 0xff00, RD_y, RD_PC, I3, 0, 0 },
|
{"sd", "y,D(S)", 0xf900, 0xff00, RD_1, RD_PC, I3, 0, 0 },
|
||||||
{"sd", "R,C(S)", 0xfa00, 0xff00, 0, RD_PC|RD_31, I1, 0, 0 },
|
{"sd", "R,C(S)", 0xfa00, 0xff00, 0, RD_31|RD_PC, I1, 0, 0 },
|
||||||
{"sh", "y,H(x)", 0xc800, 0xf800, RD_y|RD_x, 0, I1, 0, 0 },
|
{"sh", "y,H(x)", 0xc800, 0xf800, RD_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"sllv", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"sllv", "y,x", 0xe804, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"sll", "x,w,<", 0x3000, 0xf803, WR_x|RD_y, 0, I1, 0, 0 },
|
{"sll", "x,w,<", 0x3000, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"sll", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"sll", "y,x", 0xe804, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"slti", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"slti", "x,8", 0x5000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"slt", "x,y", 0xe802, 0xf81f, WR_T|RD_x|RD_y, 0, I1, 0, 0 },
|
{"slt", "x,y", 0xe802, 0xf81f, RD_1|RD_2|WR_T, 0, I1, 0, 0 },
|
||||||
{"slt", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"slt", "x,8", 0x5000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"sltiu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"sltiu", "x,8", 0x5800, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"sltu", "x,y", 0xe803, 0xf81f, WR_T|RD_x|RD_y, 0, I1, 0, 0 },
|
{"sltu", "x,y", 0xe803, 0xf81f, RD_1|RD_2|WR_T, 0, I1, 0, 0 },
|
||||||
{"sltu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1, 0, 0 },
|
{"sltu", "x,8", 0x5800, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
|
||||||
{"srav", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"srav", "y,x", 0xe807, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"sra", "x,w,<", 0x3003, 0xf803, WR_x|RD_y, 0, I1, 0, 0 },
|
{"sra", "x,w,<", 0x3003, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"sra", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"sra", "y,x", 0xe807, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"srlv", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"srlv", "y,x", 0xe806, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y, 0, I1, 0, 0 },
|
{"srl", "x,w,<", 0x3002, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1, 0, 0 },
|
{"srl", "y,x", 0xe806, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y, 0, I1, 0, 0 },
|
{"subu", "z,v,y", 0xe003, 0xf803, WR_1|RD_2|RD_3, 0, I1, 0, 0 },
|
||||||
{"subu", "y,x,I", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1, 0, 0 },
|
{"subu", "y,x,I", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"subu", "x,I", 0, (int) M_SUBU_I_2, INSN_MACRO, 0, I1, 0, 0 },
|
{"subu", "x,I", 0, (int) M_SUBU_I_2, INSN_MACRO, 0, I1, 0, 0 },
|
||||||
{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x, 0, I1, 0, 0 },
|
{"sw", "y,W(x)", 0xd800, 0xf800, RD_1|RD_3, 0, I1, 0, 0 },
|
||||||
{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP, 0, I1, 0, 0 },
|
{"sw", "x,V(S)", 0xd000, 0xf800, RD_1, RD_SP, I1, 0, 0 },
|
||||||
{"sw", "R,V(S)", 0x6200, 0xff00, RD_SP, RD_31, I1, 0, 0 },
|
{"sw", "R,V(S)", 0x6200, 0xff00, 0, RD_31|RD_SP, I1, 0, 0 },
|
||||||
{"xor", "x,y", 0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0, I1, 0, 0 },
|
{"xor", "x,y", 0xe80e, 0xf81f, MOD_1|RD_2, 0, I1, 0, 0 },
|
||||||
/* MIPS16e additions */
|
/* MIPS16e additions */
|
||||||
{"restore", "M", 0x6400, 0xff80, WR_31|NODS, MOD_SP, I32, 0, 0 },
|
{"restore", "M", 0x6400, 0xff80, WR_31|NODS, MOD_SP, I32, 0, 0 },
|
||||||
{"save", "m", 0x6480, 0xff80, NODS, MOD_SP|RD_31, I32, 0, 0 },
|
{"save", "m", 0x6480, 0xff80, NODS, RD_31|MOD_SP, I32, 0, 0 },
|
||||||
{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, I32, 0, 0 },
|
{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, I32, 0, 0 },
|
||||||
{"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, I32, 0, 0 },
|
{"seb", "x", 0xe891, 0xf8ff, MOD_1, 0, I32, 0, 0 },
|
||||||
{"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, I32, 0, 0 },
|
{"seh", "x", 0xe8b1, 0xf8ff, MOD_1, 0, I32, 0, 0 },
|
||||||
{"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I64, 0, 0 },
|
{"sew", "x", 0xe8d1, 0xf8ff, MOD_1, 0, I64, 0, 0 },
|
||||||
{"zeb", "x", 0xe811, 0xf8ff, WR_x|RD_x, 0, I32, 0, 0 },
|
{"zeb", "x", 0xe811, 0xf8ff, MOD_1, 0, I32, 0, 0 },
|
||||||
{"zeh", "x", 0xe831, 0xf8ff, WR_x|RD_x, 0, I32, 0, 0 },
|
{"zeh", "x", 0xe831, 0xf8ff, MOD_1, 0, I32, 0, 0 },
|
||||||
{"zew", "x", 0xe851, 0xf8ff, WR_x|RD_x, 0, I64, 0, 0 },
|
{"zew", "x", 0xe851, 0xf8ff, MOD_1, 0, I64, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const int bfd_mips16_num_opcodes =
|
const int bfd_mips16_num_opcodes =
|
||||||
|
|
Loading…
Reference in New Issue