aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2017-05-15 13:26:01 +0100
committerMaciej W. Rozycki <macro@imgtec.com>2017-05-15 13:57:10 +0100
commit25499ac7ee92bca177c9436383ee167d6a220066 (patch)
tree6c9e60dc1c4e7a5f4f55b382600043e60280bb95 /opcodes
parent20c59b843a90300e5f9e07add83f5c72c8f994a6 (diff)
downloadgdb-25499ac7ee92bca177c9436383ee167d6a220066.zip
gdb-25499ac7ee92bca177c9436383ee167d6a220066.tar.gz
gdb-25499ac7ee92bca177c9436383ee167d6a220066.tar.bz2
MIPS16e2: Add MIPS16e2 ASE support
Add MIPS16e2 ASE support as per the architecture specification[1], including in particular: 1. A new ELF ASE flag to mark MIPS16e2 binaries. 2. MIPS16e2 instruction assembly support, including a relaxation update to use LUI rather than an LI/SLL instruction pair for loading the high part of 32-bit addresses. 3. MIPS16e2 instruction disassembly support, including updated rules for extended forms of instructions that are now subdecoded and therefore do not alias to the original MIPS16 ISA revision instructions even for encodings that are not valid in the MIPS16e2 instruction set. Add `-mmips16e2' and `-mno-mips16e2' GAS command-line options and their corresponding `mips16e2' and `no-mips16e2' settings for the `.set' and `.module' pseudo-ops. Control the availability of the MT ASE subset of the MIPS16e2 instruction set with a combination of these controls and the preexisting MT ASE controls. Parts of this change by Matthew Fortune and Andrew Bennett. References: [1] "MIPS32 Architecture for Programmers: MIPS16e2 Application-Specific Extension Technical Reference Manual", Imagination Technologies Ltd., Document Number: MD01172, Revision 01.00, April 26, 2016 include/ * elf/mips.h (AFL_ASE_MIPS16E2): New macro. (AFL_ASE_MASK): Adjust accordingly. * opcode/mips.h: Document new operand codes defined. (mips_operand_type): Add OP_REG28 enum value. (INSN2_SHORT_ONLY): Update description. (ASE_MIPS16E2, ASE_MIPS16E2_MT): New macros. bfd/ * elfxx-mips.c (print_mips_ases): Handle MIPS16e2 ASE. opcodes/ * mips-dis.c (mips_arch_choices): Add ASE_MIPS16E2 and ASE_MIPS16E2_MT flags to the unnamed MIPS16 entry. (mips_convert_abiflags_ases): Handle the AFL_ASE_MIPS16E2 flag. (print_insn_arg) <OP_REG28>: Add handler. (validate_insn_args) <OP_REG28>: Handle. (print_mips16_insn_arg): Handle MIPS16 instructions that require 32-bit encoding and 9-bit immediates. (print_insn_mips16): Handle MIPS16 instructions that require 32-bit encoding and MFC0/MTC0 operand decoding. * mips16-opc.c (decode_mips16_operand) <'>', '9', 'G', 'N', 'O'> <'Q', 'T', 'b', 'c', 'd', 'r', 'u'>: Add handlers. (RD_C0, WR_C0, E2, E2MT): New macros. (mips16_opcodes): Add entries for MIPS16e2 instructions: GP-relative "addiu" and its "addu" spelling, "andi", "cache", "di", "ehb", "ei", "ext", "ins", GP-relative "lb", "lbu", "lh", "lhu", and "lw" instructions, "ll", "lui", "lwl", "lwr", "mfc0", "movn", "movtn", "movtz", "movz", "mtc0", "ori", "pause", "pref", "rdhwr", "sc", GP-relative "sb", "sh" and "sw" instructions, "swl", "swr", "sync" and its "sync_acquire", "sync_mb", "sync_release", "sync_rmb" and "sync_wmb" aliases, "xori", "dmt", "dvpe", "emt" and "evpe". Add split regular/extended entries for original MIPS16 ISA revision instructions whose extended forms are subdecoded in the MIPS16e2 ISA revision: "li", "sll" and "srl". binutils/ * readelf.c (print_mips_ases): Handle MIPS16e2 ASE. * NEWS: Mention MIPS16e2 ASE support. gas/ * config/tc-mips.c (RELAX_MIPS16_ENCODE): Add `e2' flag. (RELAX_MIPS16_E2): New macro. (RELAX_MIPS16_PIC, RELAX_MIPS16_SYM32, RELAX_MIPS16_NOMACRO) (RELAX_MIPS16_USER_SMALL, RELAX_MIPS16_USER_EXT) (RELAX_MIPS16_DSLOT, RELAX_MIPS16_JAL_DSLOT) (RELAX_MIPS16_EXTENDED, RELAX_MIPS16_MARK_EXTENDED) (RELAX_MIPS16_CLEAR_EXTENDED, RELAX_MIPS16_ALWAYS_EXTENDED) (RELAX_MIPS16_MARK_ALWAYS_EXTENDED) (RELAX_MIPS16_CLEAR_ALWAYS_EXTENDED, RELAX_MIPS16_MACRO) (RELAX_MIPS16_MARK_MACRO, RELAX_MIPS16_CLEAR_MACRO): Shift bits. (mips16_immed_extend): New prototype. (options): Add OPTION_MIPS16E2 and OPTION_NO_MIPS16E2 enum values. (md_longopts): Add "mmips16e2" and "mno-mips16e2" options. (mips_ases): Add "mips16e2" entry. (mips_set_ase): Handle MIPS16e2 ASE. (insn_insert_operand): Explicitly handle immediates with MIPS16 instructions that require 32-bit encoding. (is_opcode_valid_16): Pass enabled ASE bitmask on to `opcode_is_member'. (validate_mips_insn): Explicitly handle immediates with MIPS16 instructions that require 32-bit encoding. (operand_reg_mask) <OP_REG28>: Add handler. (match_reg28_operand): New function. (match_operand) <OP_REG28>: Add handler. (append_insn): Pass ASE_MIPS16E2 setting to RELAX_MIPS16_ENCODE. (match_mips16_insn): Handle MIPS16 instructions that require 32-bit encoding and `V' and `u' operand codes. (mips16_ip): Allow any characters except from `.' in opcodes. (mips16_immed_extend): Handle 9-bit immediates. Do not shuffle immediates whose width is not one of these listed. (md_estimate_size_before_relax): Handle MIPS16e2 relaxation. (mips_relax_frag): Likewise. (md_convert_frag): Likewise. (mips_convert_ase_flags): Handle MIPS16e2 ASE. * doc/as.texinfo (Target MIPS options): Add `-mmips16e2' and `-mno-mips16e2' options. (-mmips16e2, -mno-mips16e2): New options. * doc/c-mips.texi (MIPS Options): Add `-mmips16e2' and `-mno-mips16e2' options. (MIPS ASE Instruction Generation Overrides): Add `.set mips16e2' and `.set nomips16e2'.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog28
-rw-r--r--opcodes/mips-dis.c88
-rw-r--r--opcodes/mips16-opc.c98
3 files changed, 198 insertions, 16 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 4816a4e..7c819d3 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,4 +1,32 @@
2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
+ Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * mips-dis.c (mips_arch_choices): Add ASE_MIPS16E2 and
+ ASE_MIPS16E2_MT flags to the unnamed MIPS16 entry.
+ (mips_convert_abiflags_ases): Handle the AFL_ASE_MIPS16E2 flag.
+ (print_insn_arg) <OP_REG28>: Add handler.
+ (validate_insn_args) <OP_REG28>: Handle.
+ (print_mips16_insn_arg): Handle MIPS16 instructions that require
+ 32-bit encoding and 9-bit immediates.
+ (print_insn_mips16): Handle MIPS16 instructions that require
+ 32-bit encoding and MFC0/MTC0 operand decoding.
+ * mips16-opc.c (decode_mips16_operand) <'>', '9', 'G', 'N', 'O'>
+ <'Q', 'T', 'b', 'c', 'd', 'r', 'u'>: Add handlers.
+ (RD_C0, WR_C0, E2, E2MT): New macros.
+ (mips16_opcodes): Add entries for MIPS16e2 instructions:
+ GP-relative "addiu" and its "addu" spelling, "andi", "cache",
+ "di", "ehb", "ei", "ext", "ins", GP-relative "lb", "lbu", "lh",
+ "lhu", and "lw" instructions, "ll", "lui", "lwl", "lwr", "mfc0",
+ "movn", "movtn", "movtz", "movz", "mtc0", "ori", "pause",
+ "pref", "rdhwr", "sc", GP-relative "sb", "sh" and "sw"
+ instructions, "swl", "swr", "sync" and its "sync_acquire",
+ "sync_mb", "sync_release", "sync_rmb" and "sync_wmb" aliases,
+ "xori", "dmt", "dvpe", "emt" and "evpe". Add split
+ regular/extended entries for original MIPS16 ISA revision
+ instructions whose extended forms are subdecoded in the MIPS16e2
+ ISA revision: "li", "sll" and "srl".
+
+2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
* mips-dis.c (print_insn_args) <default>: Remove an MT ASE
reference in CP0 move operand decoding.
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index ab92add..8caae81 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -658,7 +658,8 @@ const struct mips_arch_choice mips_arch_choices[] =
/* This entry, mips16, is here only for ISA/processor selection; do
not print its name. */
- { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64, 0,
+ { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
+ ASE_MIPS16E2 | ASE_MIPS16E2_MT,
mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
mips_hwr_names_numeric },
};
@@ -795,6 +796,11 @@ mips_convert_abiflags_ases (unsigned long afl_ases)
opcode_ases |= ASE_XPA;
if (afl_ases & AFL_ASE_DSPR3)
opcode_ases |= ASE_DSPR3;
+ if (afl_ases & AFL_ASE_MIPS16E2)
+ opcode_ases |= ASE_MIPS16E2;
+ if ((afl_ases & (AFL_ASE_MIPS16E2 | AFL_ASE_MT))
+ == (AFL_ASE_MIPS16E2 | AFL_ASE_MT))
+ opcode_ases |= ASE_MIPS16E2_MT;
return opcode_ases;
}
@@ -1462,6 +1468,10 @@ print_insn_arg (struct disassemble_info *info,
infprintf (is, "$pc");
break;
+ case OP_REG28:
+ print_reg (info, opcode, OP_REG_GP, 28);
+ break;
+
case OP_VU0_SUFFIX:
case OP_VU0_MATCH_SUFFIX:
print_vu0_channel (info, operand, uval);
@@ -1575,6 +1585,7 @@ validate_insn_args (const struct mips_opcode *opcode,
case OP_REPEAT_PREV_REG:
case OP_REPEAT_DEST_REG:
case OP_PC:
+ case OP_REG28:
case OP_VU0_SUFFIX:
case OP_VU0_MATCH_SUFFIX:
case OP_IMM_INDEX:
@@ -1933,7 +1944,9 @@ print_mips16_insn_arg (struct disassemble_info *info,
if (use_extend)
{
ext_operand = decode_mips16_operand (type, TRUE);
- if (ext_operand != operand)
+ if (ext_operand != operand
+ || (operand->type == OP_INT && operand->lsb == 0
+ && mips_opcode_32bit_p (opcode)))
{
ext_size = ext_operand->size;
operand = ext_operand;
@@ -1941,7 +1954,7 @@ print_mips16_insn_arg (struct disassemble_info *info,
}
if (operand->size == 26)
uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
- else if (ext_size == 16)
+ else if (ext_size == 16 || ext_size == 9)
uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
else if (ext_size == 15)
uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
@@ -1949,6 +1962,8 @@ print_mips16_insn_arg (struct disassemble_info *info,
uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
else
uval = mips_extract_operand (operand, (extend << 16) | insn);
+ if (ext_size == 9)
+ uval &= (1U << ext_size) - 1;
baseaddr = memaddr + 2;
if (operand->type == OP_PCREL)
@@ -2034,6 +2049,7 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
struct mips_print_arg_state state;
void *is = info->stream;
bfd_boolean have_second;
+ bfd_boolean extend_only;
unsigned int second;
unsigned int first;
unsigned int full;
@@ -2077,6 +2093,8 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
return -1;
}
+ extend_only = FALSE;
+
if (info->endian == BFD_ENDIAN_BIG)
first = bfd_getb16 (buffer);
else
@@ -2128,9 +2146,17 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
}
else if ((first & 0xf800) == 0xf000
&& have_second
- && !(op->pinfo2 & INSN2_SHORT_ONLY)
+ && !extend_only
&& (second & op->mask) == op->match)
- match = MATCH_FULL;
+ {
+ if (op->pinfo2 & INSN2_SHORT_ONLY)
+ {
+ match = MATCH_NONE;
+ extend_only = TRUE;
+ }
+ else
+ match = MATCH_FULL;
+ }
else
match = MATCH_NONE;
@@ -2161,19 +2187,49 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
++s;
continue;
}
- switch (match)
+ if (s[0] == 'N'
+ && s[1] == ','
+ && s[2] == 'O'
+ && op->name[strlen (op->name) - 1] == '0')
{
- case MATCH_FULL:
- print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
- second, TRUE, first, s[1] == '(');
- break;
- case MATCH_SHORT:
- print_mips16_insn_arg (info, &state, op, *s, memaddr,
- first, FALSE, 0, s[1] == '(');
- break;
- case MATCH_NONE: /* Stop the compiler complaining. */
- break;
+ /* Coprocessor register 0 with sel field. */
+ const struct mips_cp0sel_name *n;
+ const struct mips_operand *operand;
+ unsigned int reg, sel;
+
+ operand = decode_mips16_operand (*s, TRUE);
+ reg = mips_extract_operand (operand, (first << 16) | second);
+ s += 2;
+ operand = decode_mips16_operand (*s, TRUE);
+ sel = mips_extract_operand (operand, (first << 16) | second);
+
+ /* CP0 register including 'sel' code for mftc0, to be
+ printed textually if known. If not known, print both
+ CP0 register name and sel numerically since CP0 register
+ with sel 0 may have a name unrelated to register being
+ printed. */
+ n = lookup_mips_cp0sel_name (mips_cp0sel_names,
+ mips_cp0sel_names_len,
+ reg, sel);
+ if (n != NULL)
+ infprintf (is, "%s", n->name);
+ else
+ infprintf (is, "$%d,%d", reg, sel);
}
+ else
+ switch (match)
+ {
+ case MATCH_FULL:
+ print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
+ second, TRUE, first, s[1] == '(');
+ break;
+ case MATCH_SHORT:
+ print_mips16_insn_arg (info, &state, op, *s, memaddr,
+ first, FALSE, 0, s[1] == '(');
+ break;
+ case MATCH_NONE: /* Stop the compiler complaining. */
+ break;
+ }
}
/* Figure out branch instruction type and delay slot information. */
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index 29e9d9d..83663ad 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -50,6 +50,7 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
switch (type)
{
case '.': MAPPED_REG (0, 0, GP, reg_0_map);
+ case '>': HINT (5, 22);
case '0': HINT (5, 0);
case '1': HINT (3, 5);
@@ -57,22 +58,33 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
case '3': HINT (5, 16);
case '4': HINT (3, 21);
case '6': HINT (6, 5);
+ case '9': SINT (9, 0);
+ case 'G': SPECIAL (0, 0, REG28);
case 'L': SPECIAL (6, 5, ENTRY_EXIT_LIST);
case 'M': SPECIAL (7, 0, SAVE_RESTORE_LIST);
+ case 'N': REG (5, 0, COPRO);
+ case 'O': UINT (3, 21);
+ case 'Q': REG (5, 16, HW);
case 'P': SPECIAL (0, 0, PC);
case 'R': MAPPED_REG (0, 0, GP, reg_31_map);
case 'S': MAPPED_REG (0, 0, GP, reg_29_map);
+ case 'T': HINT (5, 16);
case 'X': REG (5, 0, GP);
case 'Y': MAPPED_REG (5, 3, GP, reg32r_map);
case 'Z': MAPPED_REG (3, 0, GP, reg_m16_map);
case 'a': JUMP (26, 0, 2);
+ case 'b': BIT (5, 22, 0); /* (0 .. 31) */
+ case 'c': MSB (5, 16, 1, TRUE, 32); /* (1 .. 32) */
+ case 'd': MSB (5, 16, 1, FALSE, 32); /* (1 .. 32) */
case 'e': HINT (11, 0);
case 'i': JALX (26, 0, 2);
case 'l': SPECIAL (6, 5, ENTRY_EXIT_LIST);
case 'm': SPECIAL (7, 0, SAVE_RESTORE_LIST);
+ case 'r': MAPPED_REG (3, 16, GP, reg_m16_map);
case 's': HINT (3, 24);
+ case 'u': HINT (16, 0);
case 'v': OPTIONAL_MAPPED_REG (3, 8, GP, reg_m16_map);
case 'w': OPTIONAL_MAPPED_REG (3, 5, GP, reg_m16_map);
case 'x': MAPPED_REG (3, 8, GP, reg_m16_map);
@@ -162,6 +174,9 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
#define WR_T INSN_WRITE_GPR_24
#define WR_31 INSN_WRITE_GPR_31
+#define RD_C0 INSN_COP
+#define WR_C0 INSN_COP
+
#define WR_HI INSN_WRITE_HI
#define WR_LO INSN_WRITE_LO
#define RD_HI INSN_READ_HI
@@ -187,6 +202,9 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
#define I64 INSN_ISA64
#define T3 INSN_3900
+#define E2 ASE_MIPS16E2
+#define E2MT ASE_MIPS16E2_MT
+
const struct mips_opcode mips16_opcodes[] =
{
/* name, args, match, mask, pinfo, pinfo2, membership, ase, exclusions */
@@ -198,15 +216,22 @@ const struct mips_opcode mips16_opcodes[] =
{"addiu", "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_1, RD_PC, I1, 0, 0 },
+{"addiu", "x,S,V", 0x0000, 0xf800, WR_1, SH|RD_SP, 0, E2, 0 },
{"addiu", "x,S,V", 0x0000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
+{"addiu", "x,S,V", 0xf0000000, 0xf800f8e0, WR_1, RD_SP, 0, E2, 0 },
+{"addiu", "x,G,V", 0xf0000020, 0xf800f8e0, WR_1|RD_2, 0, 0, E2, 0 },
{"addu", "z,v,y", 0xe001, 0xf803, WR_1|RD_2|RD_3, SH, I1, 0, 0 },
{"addu", "y,x,F", 0x4000, 0xf810, WR_1|RD_2, 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,S,K", 0x6300, 0xff00, 0, MOD_SP, I1, 0, 0 },
{"addu", "x,P,V", 0x0800, 0xf800, WR_1, RD_PC, I1, 0, 0 },
+{"addu", "x,S,V", 0x0000, 0xf800, WR_1, SH|RD_SP, 0, E2, 0 },
{"addu", "x,S,V", 0x0000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
+{"addu", "x,S,V", 0xf0000000, 0xf800f8e0, WR_1, RD_SP, 0, E2, 0 },
+{"addu", "x,G,V", 0xf0000020, 0xf800f8e0, WR_1|RD_2, 0, 0, E2, 0 },
{"and", "x,y", 0xe80c, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
+{"andi", "x,u", 0xf0006860, 0xf800f8e0, WR_1, 0, 0, E2, 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,I,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1, 0, 0 },
@@ -234,6 +259,7 @@ const struct mips_opcode mips16_opcodes[] =
{"break", "6", 0xe805, 0xf81f, TRAP, SH, I1, 0, 0 },
{"bteqz", "p", 0x6000, 0xff00, RD_T, CBR, I1, 0, 0 },
{"btnez", "p", 0x6100, 0xff00, RD_T, CBR, I1, 0, 0 },
+{"cache", "T,9(x)", 0xf000d0a0, 0xfe00f8e0, RD_3, 0, 0, E2, 0 },
{"cmpi", "x,U", 0x7000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
{"cmp", "x,y", 0xe80a, 0xf81f, RD_1|RD_2|WR_T, SH, I1, 0, 0 },
{"cmp", "x,U", 0x7000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
@@ -255,6 +281,9 @@ const struct mips_opcode mips16_opcodes[] =
{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, I3, 0, 0 },
{"ddivu", ".,x,y", 0xe81f, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, SH, I3, 0, 0 },
{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I3, 0, 0 },
+{"di", "", 0xf006670c, 0xffffffff, WR_C0, 0, 0, E2, 0 },
+{"di", ".", 0xf006670c, 0xffffffff, WR_C0, 0, 0, E2, 0 },
+{"di", "y", 0xf002670c, 0xffffff1f, WR_1|WR_C0, 0, 0, E2, 0 },
{"div", ".,x,y", 0xe81a, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, SH, I1, 0, 0 },
{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, I1, 0, 0 },
{"divu", ".,x,y", 0xe81b, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, SH, I1, 0, 0 },
@@ -278,12 +307,19 @@ const struct mips_opcode mips16_opcodes[] =
{"dsubu", "z,v,y", 0xe002, 0xf803, WR_1|RD_2|RD_3, SH, I3, 0, 0 },
{"dsubu", "y,x,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I3, 0, 0 },
{"dsubu", "y,I", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I3, 0, 0 },
+{"ehb", "", 0xf0c03010, 0xffffffff, 0, 0, 0, E2, 0 },
+{"ei", "", 0xf007670c, 0xffffffff, WR_C0, 0, 0, E2, 0 },
+{"ei", ".", 0xf007670c, 0xffffffff, WR_C0, 0, 0, E2, 0 },
+{"ei", "y", 0xf003670c, 0xffffff1f, WR_1|WR_C0, 0, 0, E2, 0 },
{"exit", "L", 0xed09, 0xff1f, TRAP, SH, I1, 0, 0 },
{"exit", "L", 0xee09, 0xff1f, TRAP, SH, I1, 0, 0 },
{"exit", "", 0xef09, 0xffff, TRAP, SH, I1, 0, 0 },
{"exit", "L", 0xef09, 0xff1f, TRAP, SH, I1, 0, 0 },
{"entry", "", 0xe809, 0xffff, TRAP, SH, I1, 0, 0 },
{"entry", "l", 0xe809, 0xf81f, TRAP, SH, I1, 0, 0 },
+{"ext", "y,x,b,d", 0xf0203008, 0xf820f81f, WR_1|RD_2, 0, 0, E2, 0 },
+{"ins", "y,.,b,c", 0xf0003004, 0xf820ff1f, WR_1, 0, 0, E2, 0 },
+{"ins", "y,x,b,c", 0xf0203004, 0xf820f81f, WR_1|RD_2, 0, 0, E2, 0 },
{"jalr", "x", 0xe840, 0xf8ff, RD_1|WR_31|UBD, SH, I1, 0, 0 },
{"jalr", "R,x", 0xe840, 0xf8ff, RD_2|WR_31|UBD, SH, I1, 0, 0 },
{"jal", "x", 0xe840, 0xf8ff, RD_1|WR_31|UBD, SH, I1, 0, 0 },
@@ -302,40 +338,74 @@ const struct mips_opcode mips16_opcodes[] =
{"jrc", "x", 0xe880, 0xf8ff, RD_1|NODS, SH|UBR, I32, 0, 0 },
{"jrc", "R", 0xe8a0, 0xffff, NODS, SH|RD_31|UBR, I32, 0, 0 },
{"lb", "y,5(x)", 0x8000, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
+{"lb", "x,V(G)", 0xf0009060, 0xf800f8e0, WR_1|RD_3, 0, 0, E2, 0 },
{"lbu", "y,5(x)", 0xa000, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
+{"lbu", "x,V(G)", 0xf00090a0, 0xf800f8e0, WR_1|RD_3, 0, 0, E2, 0 },
{"ld", "y,D(x)", 0x3800, 0xf800, WR_1|RD_3, 0, I3, 0, 0 },
{"ld", "y,B", 0xfc00, 0xff00, WR_1, RD_PC|AL, I3, 0, 0 },
{"ld", "y,D(P)", 0xfc00, 0xff00, WR_1, RD_PC, I3, 0, 0 },
{"ld", "y,D(S)", 0xf800, 0xff00, WR_1, RD_SP, I3, 0, 0 },
{"lh", "y,H(x)", 0x8800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
+{"lh", "x,V(G)", 0xf0009040, 0xf800f8e0, WR_1|RD_3, 0, 0, E2, 0 },
{"lhu", "y,H(x)", 0xa800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
+{"lhu", "x,V(G)", 0xf0009080, 0xf800f8e0, WR_1|RD_3, 0, 0, E2, 0 },
+{"li", "x,U", 0x6800, 0xf800, WR_1, SH, 0, E2, 0 },
{"li", "x,U", 0x6800, 0xf800, WR_1, 0, I1, 0, 0 },
+{"li", "x,U", 0xf0006800, 0xf800f8e0, WR_1, 0, 0, E2, 0 },
+{"ll", "x,9(r)", 0xf00090c0, 0xfe18f8e0, WR_1|RD_3, 0, 0, E2, 0 },
+{"lui", "x,u", 0xf0006820, 0xf800f8e0, WR_1, 0, 0, E2, 0 },
{"lw", "y,W(x)", 0x9800, 0xf800, WR_1|RD_3, 0, I1, 0, 0 },
{"lw", "x,A", 0xb000, 0xf800, WR_1, RD_PC|AL, I1, 0, 0 },
{"lw", "x,V(P)", 0xb000, 0xf800, WR_1, RD_PC, I1, 0, 0 },
+{"lw", "x,V(S)", 0x9000, 0xf800, WR_1, SH|RD_SP, 0, E2, 0 },
{"lw", "x,V(S)", 0x9000, 0xf800, WR_1, RD_SP, I1, 0, 0 },
+{"lw", "x,V(S)", 0xf0009000, 0xf800f8e0, WR_1, RD_SP, 0, E2, 0 },
+{"lw", "x,V(G)", 0xf0009020, 0xf800f8e0, WR_1|RD_3, 0, 0, E2, 0 },
+{"lwl", "x,9(r)", 0xf00090e0, 0xfe18f8e0, WR_1|RD_3, 0, 0, E2, 0 },
+{"lwr", "x,9(r)", 0xf01090e0, 0xfe18f8e0, WR_1|RD_3, 0, 0, E2, 0 },
{"lwu", "y,W(x)", 0xb800, 0xf800, WR_1|RD_3, 0, I3, 0, 0 },
+{"mfc0", "y,N", 0xf0006700, 0xffffff00, WR_1|RD_C0, 0, 0, E2, 0 },
+{"mfc0", "y,N,O", 0xf0006700, 0xff1fff00, WR_1|RD_C0, 0, 0, E2, 0 },
{"mfhi", "x", 0xe810, 0xf8ff, WR_1|RD_HI, SH, I1, 0, 0 },
{"mflo", "x", 0xe812, 0xf8ff, WR_1|RD_LO, SH, I1, 0, 0 },
{"move", "y,X", 0x6700, 0xff00, WR_1|RD_2, SH, I1, 0, 0 },
{"move", "Y,Z", 0x6500, 0xff00, WR_1|RD_2, SH, I1, 0, 0 },
+{"movn", "x,.,w", 0xf000300a, 0xfffff81f, WR_1|RD_2|RD_3, 0, 0, E2, 0 },
+{"movn", "x,r,w", 0xf020300a, 0xfff8f81f, WR_1|RD_2|RD_3, 0, 0, E2, 0 },
+{"movtn", "x,.", 0xf000301a, 0xfffff8ff, WR_1|RD_2|RD_T, 0, 0, E2, 0 },
+{"movtn", "x,r", 0xf020301a, 0xfff8f8ff, WR_1|RD_2|RD_T, 0, 0, E2, 0 },
+{"movtz", "x,.", 0xf0003016, 0xfffff8ff, WR_1|RD_2|RD_T, 0, 0, E2, 0 },
+{"movtz", "x,r", 0xf0203016, 0xfff8f8ff, WR_1|RD_2|RD_T, 0, 0, E2, 0 },
+{"movz", "x,.,w", 0xf0003006, 0xfffff81f, WR_1|RD_2|RD_3, 0, 0, E2, 0 },
+{"movz", "x,r,w", 0xf0203006, 0xfff8f81f, WR_1|RD_2|RD_3, 0, 0, E2, 0 },
+{"mtc0", "y,N", 0xf0016700, 0xffffff00, RD_1|WR_C0, 0, 0, E2, 0 },
+{"mtc0", "y,N,O", 0xf0016700, 0xff1fff00, RD_1|WR_C0, 0, 0, E2, 0 },
{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1, 0, 0 },
{"mult", "x,y", 0xe818, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, SH, I1, 0, 0 },
{"multu", "x,y", 0xe819, 0xf81f, RD_1|RD_2|WR_HI|WR_LO, SH, I1, 0, 0 },
{"neg", "x,w", 0xe80b, 0xf81f, WR_1|RD_2, SH, I1, 0, 0 },
{"not", "x,w", 0xe80f, 0xf81f, WR_1|RD_2, SH, I1, 0, 0 },
{"or", "x,y", 0xe80d, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
+{"ori", "x,u", 0xf0006840, 0xf800f8e0, WR_1, 0, 0, E2, 0 },
+{"pause", "", 0xf1403018, 0xffffffff, 0, 0, 0, E2, 0 },
+{"pref", "T,9(x)", 0xf000d080, 0xfe00f8e0, RD_3, 0, 0, E2, 0 },
+{"rdhwr", "y,Q", 0xf000300c, 0xffe0ff1f, WR_1, 0, 0, E2, 0 },
{"rem", ".,x,y", 0xe81a, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, SH, I1, 0, 0 },
{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, I1, 0, 0 },
{"remu", ".,x,y", 0xe81b, 0xf81f, RD_2|RD_3|WR_HI|WR_LO, SH, 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_1|RD_3, 0, I1, 0, 0 },
+{"sb", "x,V(G)", 0xf000d060, 0xf800f8e0, RD_1|RD_3, 0, 0, E2, 0 },
+{"sc", "x,9(r)", 0xf000d0c0, 0xfe18f8e0, RD_1|RD_3, 0, 0, E2, 0 },
{"sd", "y,D(x)", 0x7800, 0xf800, RD_1|RD_3, 0, I3, 0, 0 },
{"sd", "y,D(S)", 0xf900, 0xff00, RD_1, RD_SP, I3, 0, 0 },
{"sd", "R,C(S)", 0xfa00, 0xff00, 0, RD_31|RD_SP, I3, 0, 0 },
{"sh", "y,H(x)", 0xc800, 0xf800, RD_1|RD_3, 0, I1, 0, 0 },
+{"sh", "x,V(G)", 0xf000d040, 0xf800f8e0, RD_1|RD_3, 0, 0, E2, 0 },
{"sllv", "y,x", 0xe804, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
+{"sll", "x,w,<", 0x3000, 0xf803, WR_1|RD_2, SH, 0, E2, 0 },
{"sll", "x,w,<", 0x3000, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
+{"sll", "x,w,<", 0xf0003000, 0xf83ff81f, WR_1|RD_2, 0, 0, E2, 0 },
{"sll", "y,x", 0xe804, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
{"slti", "x,8", 0x5000, 0xf800, RD_1|WR_T, 0, I1, 0, 0 },
{"slt", "x,y", 0xe802, 0xf81f, RD_1|RD_2|WR_T, SH, I1, 0, 0 },
@@ -347,15 +417,30 @@ const struct mips_opcode mips16_opcodes[] =
{"sra", "x,w,<", 0x3003, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
{"sra", "y,x", 0xe807, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
{"srlv", "y,x", 0xe806, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
+{"srl", "x,w,<", 0x3002, 0xf803, WR_1|RD_2, SH, 0, E2, 0 },
{"srl", "x,w,<", 0x3002, 0xf803, WR_1|RD_2, 0, I1, 0, 0 },
+{"srl", "x,w,<", 0xf0003002, 0xf83ff81f, WR_1|RD_2, 0, 0, E2, 0 },
{"srl", "y,x", 0xe806, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
{"subu", "z,v,y", 0xe003, 0xf803, WR_1|RD_2|RD_3, SH, 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 },
{"sw", "y,W(x)", 0xd800, 0xf800, RD_1|RD_3, 0, I1, 0, 0 },
+{"sw", "x,V(S)", 0xd000, 0xf800, RD_1, SH|RD_SP, 0, E2, 0 },
{"sw", "x,V(S)", 0xd000, 0xf800, RD_1, RD_SP, I1, 0, 0 },
+{"sw", "x,V(S)", 0xf000d000, 0xf800f8e0, RD_1, RD_SP, 0, E2, 0 },
{"sw", "R,V(S)", 0x6200, 0xff00, 0, RD_31|RD_SP, I1, 0, 0 },
+{"sw", "x,V(G)", 0xf000d020, 0xf800f8e0, RD_1|RD_3, 0, 0, E2, 0 },
+{"swl", "x,9(r)", 0xf000d0e0, 0xfe18f8e0, RD_1|RD_3, 0, 0, E2, 0 },
+{"swr", "x,9(r)", 0xf010d0e0, 0xfe18f8e0, RD_1|RD_3, 0, 0, E2, 0 },
+{"sync_acquire", "", 0xf4403014, 0xffffffff, 0, AL, 0, E2, 0 },
+{"sync_mb", "", 0xf4003014, 0xffffffff, 0, AL, 0, E2, 0 },
+{"sync_release", "", 0xf4803014, 0xffffffff, 0, AL, 0, E2, 0 },
+{"sync_rmb", "", 0xf4c03014, 0xffffffff, 0, AL, 0, E2, 0 },
+{"sync_wmb", "", 0xf1003014, 0xffffffff, 0, AL, 0, E2, 0 },
+{"sync", "", 0xf0003014, 0xffffffff, 0, 0, 0, E2, 0 },
+{"sync", ">", 0xf0003014, 0xf83fffff, 0, 0, 0, E2, 0 },
{"xor", "x,y", 0xe80e, 0xf81f, MOD_1|RD_2, SH, I1, 0, 0 },
+{"xori", "x,u", 0xf0006880, 0xf800f8e0, WR_1, 0, 0, E2, 0 },
/* MIPS16e additions; see above for compact jumps. */
{"restore", "M", 0x6400, 0xff80, WR_31|NODS, MOD_SP, I32, 0, 0 },
{"save", "m", 0x6480, 0xff80, NODS, RD_31|MOD_SP, I32, 0, 0 },
@@ -367,6 +452,19 @@ const struct mips_opcode mips16_opcodes[] =
{"zeb", "x", 0xe811, 0xf8ff, MOD_1, SH, I32, 0, 0 },
{"zeh", "x", 0xe831, 0xf8ff, MOD_1, SH, I32, 0, 0 },
{"zew", "x", 0xe851, 0xf8ff, MOD_1, SH, I64, 0, 0 },
+ /* MIPS16e2 MT ASE instructions. */
+{"dmt", "", 0xf0266701, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"dmt", ".", 0xf0266701, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"dmt", "y", 0xf0226701, 0xffffff1f, WR_1|WR_C0, 0, 0, E2MT, 0 },
+{"dvpe", "", 0xf0266700, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"dvpe", ".", 0xf0266700, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"dvpe", "y", 0xf0226700, 0xffffff1f, WR_1|WR_C0, 0, 0, E2MT, 0 },
+{"emt", "", 0xf0276701, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"emt", ".", 0xf0276701, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"emt", "y", 0xf0236701, 0xffffff1f, WR_1|WR_C0, 0, 0, E2MT, 0 },
+{"evpe", "", 0xf0276700, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"evpe", ".", 0xf0276700, 0xffffffff, WR_C0, 0, 0, E2MT, 0 },
+{"evpe", "y", 0xf0236700, 0xffffff1f, WR_1|WR_C0, 0, 0, E2MT, 0 },
/* Place asmacro at the bottom so that it catches any implementation
specific macros that didn't match anything. */
{"asmacro", "s,0,1,2,3,4", 0xf000e000, 0xf800f800, 0, 0, I32, 0, 0 },