summaryrefslogtreecommitdiffstats
path: root/toolchain/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain/binutils')
-rw-r--r--toolchain/binutils/patches/2.20.1/902-rlx.patch1985
1 files changed, 1985 insertions, 0 deletions
diff --git a/toolchain/binutils/patches/2.20.1/902-rlx.patch b/toolchain/binutils/patches/2.20.1/902-rlx.patch
new file mode 100644
index 000000000..53cb9a65e
--- /dev/null
+++ b/toolchain/binutils/patches/2.20.1/902-rlx.patch
@@ -0,0 +1,1985 @@
+Index: binutils/opcodes/mips-opc.c
+===================================================================
+--- binutils.orig/opcodes/mips-opc.c
++++ binutils/opcodes/mips-opc.c
+@@ -163,6 +163,18 @@
+ #define D33 INSN_DSPR2
+ #define D64 INSN_DSP64
+
++#define RLX0 INSN_4180
++#define RLX1 INSN_5280
++#define RLX2 INSN_4181|INSN_5181
++#define RLX3 INSN_4281|INSN_5281
++
++#define RLXA (RLX0|RLX1|RLX2|RLX3)
++#define RLXB (RLX1|RLX2|RLX3)
++
++#define RAD1 INSN_5181|INSN_5280|INSN_5281
++#define RAD2 INSN_5281
++
++
+ /* MIPS MT ASE support. */
+ #define MT32 INSN_MT
+
+@@ -188,7 +200,7 @@ const struct mips_opcode mips_builtin_op
+ {"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4_32|G3 },
+ {"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S, 0, I4_33 },
+ {"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */
+-{"ssnop", "", 0x00000040, 0xffffffff, 0, INSN2_ALIAS, I32|N55 }, /* sll */
++{"ssnop", "", 0x00000040, 0xffffffff, 0, INSN2_ALIAS, I32|N55|RLX3 }, /* sll */
+ {"ehb", "", 0x000000c0, 0xffffffff, 0, INSN2_ALIAS, I33 }, /* sll */
+ {"li", "t,j", 0x24000000, 0xffe00000, WR_t, INSN2_ALIAS, I1 }, /* addiu */
+ {"li", "t,i", 0x34000000, 0xffe00000, WR_t, INSN2_ALIAS, I1 }, /* ori */
+@@ -509,14 +521,16 @@ const struct mips_opcode mips_builtin_op
+ {"flushd", "", 0xbc020000, 0xffffffff, 0, 0, L1 },
+ {"flushid", "", 0xbc030000, 0xffffffff, 0, 0, L1 },
+ {"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, 0, L1 },
+-{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3_32|T3},
++{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3_32|T3|RLXB},
+ {"cache", "k,A(b)", 0, (int) M_CACHE_AB, INSN_MACRO, 0, I3_32|T3},
+ {"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 },
+ {"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 },
+ {"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 },
+ {"ceil.w.s", "D,S", 0x4600000e, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
+ {"cfc0", "t,G", 0x40400000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 },
++{"cfc0", "t,G,#H", 0x40400000, 0xffe007c0, LCD|WR_t|RD_C0, 0, RLX3 },
+ {"cfc1", "t,G", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 },
++{"cfc1", "t,G,#H", 0x44400000, 0xffe007c0, LCD|WR_t|RD_C1|FP_S, 0, RLX3 },
+ {"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 },
+ /* cfc2 is at the bottom of the table. */
+ /* cfc3 is at the bottom of the table. */
+@@ -529,7 +543,9 @@ const struct mips_opcode mips_builtin_op
+ {"clo", "U,s", 0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 },
+ {"clz", "U,s", 0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 },
+ {"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 },
++{"ctc0", "t,G,#H", 0x40c00000, 0xffe007c0, COD|RD_t|WR_CC, 0, RLX3 },
+ {"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 },
++{"ctc1", "t,G,#H", 0x44c00000, 0xffe007c0, COD|RD_t|WR_CC|FP_S, 0, RLX3 },
+ {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 },
+ /* ctc2 is at the bottom of the table. */
+ /* ctc3 is at the bottom of the table. */
+@@ -567,7 +583,7 @@ const struct mips_opcode mips_builtin_op
+ /* dctr and dctw are used on the r5000. */
+ {"dctr", "o(b)", 0xbc050000, 0xfc1f0000, RD_b, 0, I3 },
+ {"dctw", "o(b)", 0xbc090000, 0xfc1f0000, RD_b, 0, I3 },
+-{"deret", "", 0x4200001f, 0xffffffff, 0, 0, I32|G2 },
++{"deret", "", 0x4200001f, 0xffffffff, 0, 0, I32|G2|RLXA },
+ {"dext", "t,r,I,+I", 0, (int) M_DEXT, INSN_MACRO, 0, I65 },
+ {"dext", "t,r,+A,+C", 0x7c000003, 0xfc00003f, WR_t|RD_s, 0, I65 },
+ {"dextm", "t,r,+A,+G", 0x7c000001, 0xfc00003f, WR_t|RD_s, 0, I65 },
+@@ -777,8 +793,8 @@ const struct mips_opcode mips_builtin_op
+ {"li.d", "T,L", 0, (int) M_LI_DD, INSN_MACRO, INSN2_M_FP_D, I1 },
+ {"li.s", "t,f", 0, (int) M_LI_S, INSN_MACRO, INSN2_M_FP_S, I1 },
+ {"li.s", "T,l", 0, (int) M_LI_SS, INSN_MACRO, INSN2_M_FP_S, I1 },
+-{"ll", "t,o(b)", 0xc0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2 },
+-{"ll", "t,A(b)", 0, (int) M_LL_AB, INSN_MACRO, 0, I2 },
++{"ll", "t,o(b)", 0xc0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2|RLX2|RLX3 },
++{"ll", "t,A(b)", 0, (int) M_LL_AB, INSN_MACRO, 0, I2|RLX2|RLX3 },
+ {"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 },
+ {"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 },
+ {"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 },
+@@ -822,8 +838,8 @@ const struct mips_opcode mips_builtin_op
+ {"maccu", "d,s,t", 0x00000068, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 },
+ {"maccu", "d,s,t", 0x00000159, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 },
+ {"maccus", "d,s,t", 0x00000468, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 },
+-{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3 },
+-{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3 },
++{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3|RLXA },
++{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3|RLXA },
+ {"madd.d", "D,R,S,T", 0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4_33 },
+ {"madd.d", "D,S,T", 0x46200018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E },
+ {"madd.d", "D,S,T", 0x72200018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F },
+@@ -871,10 +887,12 @@ const struct mips_opcode mips_builtin_op
+ {"mftlo", "d,*", 0x41000021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 },
+ {"mftr", "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d, 0, MT32 },
+ {"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1|IOCT },
++{"mfc0", "t,G,#H", 0x40000000, 0xffe007c0, LCD|WR_t|RD_C0, 0, RLX3 },
+ {"mfc0", "t,+D", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32|IOCT},
+ {"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32|IOCT},
+ {"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 },
+ {"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 },
++{"mfc1", "t,G,#H", 0x44000000, 0xffe007c0, LCD|WR_t|RD_S|FP_S, 0, RLX3 },
+ {"mfhc1", "t,S", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 },
+ {"mfhc1", "t,G", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 },
+ /* mfc2 is at the bottom of the table. */
+@@ -902,7 +920,7 @@ const struct mips_opcode mips_builtin_op
+ {"movf.l", "X,Y,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 },
+ {"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 },
+ {"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 },
+-{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F },
++{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F|RLXB },
+ {"movnz", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IL2E|IL2F },
+ {"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s, 0, L1 },
+ {"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 },
+@@ -916,7 +934,7 @@ const struct mips_opcode mips_builtin_op
+ {"movt.l", "X,Y,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 },
+ {"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 },
+ {"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 },
+-{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F },
++{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F|RLXB },
+ {"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s, 0, L1 },
+ {"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 },
+ {"movz.l", "D,S,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 },
+@@ -944,17 +962,19 @@ const struct mips_opcode mips_builtin_op
+ {"msub.ps", "D,S,T", 0x45600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E },
+ {"msub.ps", "D,S,T", 0x71600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F },
+ {"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 },
+-{"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 },
++{"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55|RLXA },
+ {"msub", "7,s,t", 0x70000004, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 },
+ {"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 },
+-{"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 },
++{"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55|RLXA },
+ {"msubu", "7,s,t", 0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 },
+ {"mtpc", "t,P", 0x4080c801, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 },
+ {"mtps", "t,P", 0x4080c800, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 },
+ {"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I1|IOCT },
++{"mtc0", "t,G,#H", 0x40800000, 0xffe007c0, COD|RD_t|WR_C0|WR_CC, 0, RLX3 },
+ {"mtc0", "t,+D", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32|IOCT},
+ {"mtc0", "t,G,H", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32|IOCT},
+ {"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 },
++{"mtc1", "t,G,#H", 0x44800000, 0xffe007c0, COD|RD_t|WR_S|FP_S, 0, RLX3 },
+ {"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 },
+ {"mthc1", "t,S", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 },
+ {"mthc1", "t,G", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 },
+@@ -1172,8 +1192,8 @@ const struct mips_opcode mips_builtin_op
+ {"rzu.qh", "X,Q", 0x78200020, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX },
+ {"sb", "t,o(b)", 0xa0000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 },
+ {"sb", "t,A(b)", 0, (int) M_SB_AB, INSN_MACRO, 0, I1 },
+-{"sc", "t,o(b)", 0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, 0, I2 },
+-{"sc", "t,A(b)", 0, (int) M_SC_AB, INSN_MACRO, 0, I2 },
++{"sc", "t,o(b)", 0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, 0, I2|RLX2|RLX3 },
++{"sc", "t,A(b)", 0, (int) M_SC_AB, INSN_MACRO, 0, I2|RLX2|RLX3 },
+ {"scd", "t,o(b)", 0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, 0, I3 },
+ {"scd", "t,A(b)", 0, (int) M_SCD_AB, INSN_MACRO, 0, I3 },
+ {"sd", "t,o(b)", 0xfc000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 },
+@@ -1182,8 +1202,8 @@ const struct mips_opcode mips_builtin_op
+ {"sdbbp", "", 0x0000000e, 0xffffffff, TRAP, 0, G2 },
+ {"sdbbp", "c", 0x0000000e, 0xfc00ffff, TRAP, 0, G2 },
+ {"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, 0, G2 },
+-{"sdbbp", "", 0x7000003f, 0xffffffff, TRAP, 0, I32 },
+-{"sdbbp", "B", 0x7000003f, 0xfc00003f, TRAP, 0, I32 },
++{"sdbbp", "", 0x7000003f, 0xffffffff, TRAP, 0, I32|RLXA },
++{"sdbbp", "B", 0x7000003f, 0xfc00003f, TRAP, 0, I32|RLXA },
+ {"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 },
+ {"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 },
+ {"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 },
+@@ -1338,7 +1358,8 @@ const struct mips_opcode mips_builtin_op
+ {"syncs", "", 0x0000018f, 0xffffffff, INSN_SYNC, 0, IOCT },
+ {"syncw", "", 0x0000010f, 0xffffffff, INSN_SYNC, 0, IOCT },
+ {"syncws", "", 0x0000014f, 0xffffffff, INSN_SYNC, 0, IOCT },
+-{"sync", "", 0x0000000f, 0xffffffff, INSN_SYNC, 0, I2|G1 },
++{"sync", "", 0x0000000f, 0xffffffff, INSN_SYNC, 0, I2|G1|RLX3 },
++{"sync", "#I", 0x0000000f, 0xfffff83f, INSN_SYNC, 0, RLX3 },
+ {"sync", "1", 0x0000000f, 0xfffff83f, INSN_SYNC, 0, I32 },
+ {"sync.p", "", 0x0000040f, 0xffffffff, INSN_SYNC, 0, I2 },
+ {"sync.l", "", 0x0000000f, 0xffffffff, INSN_SYNC, 0, I2 },
+@@ -1433,26 +1454,32 @@ const struct mips_opcode mips_builtin_op
+ {"udi0", "s,t,+2", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi0", "s,+3", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi0", "+4", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi0", "d,v,t", 0x00000038, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi1", "s,t,d,+1",0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi1", "s,t,+2", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi1", "s,+3", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi1", "+4", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi1", "d,v,t", 0x0000003a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi2", "s,t,d,+1",0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi2", "s,t,+2", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi2", "s,+3", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi2", "+4", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi2", "d,v,t", 0x0000003b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi3", "s,t,d,+1",0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi3", "s,t,+2", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi3", "s,+3", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi3", "+4", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi3", "d,v,t", 0x0000003c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi4", "s,t,d,+1",0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi4", "s,t,+2", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi4", "s,+3", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi4", "+4", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi4", "d,v,t", 0x0000003e, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi5", "s,t,d,+1",0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi5", "s,t,+2", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi5", "s,+3", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi5", "+4", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
++{"udi5", "d,v,t", 0x0000003f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, RLXB },
+ {"udi6", "s,t,d,+1",0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi6", "s,t,+2", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+ {"udi6", "s,+3", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 },
+@@ -1505,7 +1532,9 @@ const struct mips_opcode mips_builtin_op
+ {"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 },
+ {"bc2tl", "N,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, I32 },
+ {"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 },
++{"cfc2", "t,G,#H", 0x48400000, 0xffe007c0, LCD|WR_t|RD_C2, 0, RLX3 },
+ {"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 },
++{"ctc2", "t,G,#H", 0x48c00000, 0xffe007c0, COD|RD_t|WR_CC, 0, RLX3 },
+ {"dmfc2", "t,i", 0x48200000, 0xffe00000, LCD|WR_t|RD_C2, 0, IOCT },
+ {"dmfc2", "t,G", 0x48200000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I3 },
+ {"dmfc2", "t,G,H", 0x48200000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I64 },
+@@ -1513,11 +1542,13 @@ const struct mips_opcode mips_builtin_op
+ {"dmtc2", "t,G", 0x48a00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I3 },
+ {"dmtc2", "t,G,H", 0x48a00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I64 },
+ {"mfc2", "t,G", 0x48000000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 },
++{"mfc2", "t,G,#H", 0x48000000, 0xffe007c0, LCD|WR_t|RD_C2, 0, RLX3 },
+ {"mfc2", "t,G,H", 0x48000000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I32 },
+ {"mfhc2", "t,G", 0x48600000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I33 },
+ {"mfhc2", "t,G,H", 0x48600000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I33 },
+ {"mfhc2", "t,i", 0x48600000, 0xffe00000, LCD|WR_t|RD_C2, 0, I33 },
+ {"mtc2", "t,G", 0x48800000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I1 },
++{"mtc2", "t,G,#H", 0x48800000, 0xffe007c0, COD|RD_t|WR_C2|WR_CC, 0, RLX3 },
+ {"mtc2", "t,G,H", 0x48800000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I32 },
+ {"mthc2", "t,G", 0x48e00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I33 },
+ {"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33 },
+@@ -1530,12 +1561,16 @@ const struct mips_opcode mips_builtin_op
+ {"bc3t", "p", 0x4d010000, 0xffff0000, CBD|RD_CC, 0, I1 },
+ {"bc3tl", "p", 0x4d030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 },
+ {"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 },
++{"cfc3", "t,G,#H", 0x4c400000, 0xffe007c0, LCD|WR_t|RD_C3, 0, RLX3 },
+ {"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 },
++{"ctc3", "t,G,#H", 0x4cc00000, 0xffe007c0, COD|RD_t|WR_CC, 0, RLX3 },
+ {"dmfc3", "t,G", 0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I3 },
+ {"dmtc3", "t,G", 0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I3 },
+ {"mfc3", "t,G", 0x4c000000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 },
++{"mfc3", "t,G,#H", 0x4c000000, 0xffe007c0, LCD|WR_t|RD_C3, 0, RLX3 },
+ {"mfc3", "t,G,H", 0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I32 },
+ {"mtc3", "t,G", 0x4c800000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I1 },
++{"mtc3", "t,G,#H", 0x4c800000, 0xffe007c0, COD|RD_t|WR_C3|WR_CC, 0, RLX3 },
+ {"mtc3", "t,G,H", 0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I32 },
+
+ /* Conflicts with the 4650's "mul" instruction. Nobody's using the
+@@ -1561,6 +1596,7 @@ const struct mips_opcode mips_builtin_op
+ {"addu_s.qb", "d,s,t", 0x7c000110, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 },
+ {"addwc", "d,s,t", 0x7c000450, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 },
+ {"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 },
++{"bitrev", "d,t,s", 0x7c00000c, 0xFC0007FF, RD_s|RD_t|WR_d, 0, RAD1 },
+ {"bposge32", "p", 0x041c0000, 0xffff0000, CBD, 0, D32 },
+ {"bposge64", "p", 0x041d0000, 0xffff0000, CBD, 0, D64 },
+ {"cmp.eq.ph", "s,t", 0x7c000211, 0xfc00ffff, RD_s|RD_t, 0, D32 },
+@@ -1984,7 +2020,176 @@ const struct mips_opcode mips_builtin_op
+ {"cop0", "C", 0, (int) M_COP0, INSN_MACRO, 0, I1 },
+ {"cop1", "C", 0, (int) M_COP1, INSN_MACRO, INSN2_M_FP_S, I1 },
+ {"cop2", "C", 0, (int) M_COP2, INSN_MACRO, 0, I1 },
+-{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, 0, I1 }
++{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, 0, I1 },
++
++/* dbb: modified for supporting radiax instructions */
++/* 2006-01-19 tonywu: cleanup radiax instructions definition */
++/* 2008-07-12 tonywu: add taroko support */
++/* 2008-08-31 tonywu: add rad type */
++/* d1: m0(3), m1(7), m2(11), m3(15) */
++/* d2: m0l, m0h, m0 ~ m3l, m3h, m3 */
++/* d3: m0l, m0h, ~ m3l, m3h */
++/* d4: LXC0 */
++{"mta2", "s,#d2", 0x7C00005D, 0xFC1F07ff, RD_s, 0, RAD1},
++{"mta2.g", "s,#d2", 0x7C00015D, 0xFC1F07ff, RD_s, 0, RAD1},
++{"mfa", "d,#t3", 0x7C00001C, 0xFFE007FF, WR_d, 0, RAD1},
++{"mfa", "d,#t3,##", 0x7C00001C, 0xFFE0007F, WR_d, 0, RAD1},
++{"mfa2", "d,#t1", 0x7C00005C, 0xFFE007FF, WR_d, 0, RAD1},
++{"mfa2", "d,#t1,##", 0x7C00005C, 0xFFE0007F, WR_d, 0, RAD1},
++{"diva", "#d1,s,t", 0x7C00001A, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"divau", "#d1,s,t", 0x7C00021A, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"multa", "#d1,s,t", 0x7C000112, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"multau", "#d1,s,t", 0x7C000312, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imulta", "#d1,s,t", 0x7C000102, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"imultau", "#d1,s,t", 0x7C000302, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmulta", "#d1,s,t", 0x7C000502, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"multa2", "#d2,s,t", 0x7C000152, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imulta2", "#d2,s,t", 0x7C000142, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmulta2", "#d2,s,t", 0x7C000542, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"mulna2", "#d2,s,t", 0x7C000153, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imulna2", "#d2,s,t", 0x7C000143, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmulna2", "#d2,s,t", 0x7C000543, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"cmulta", "#d1,s,t", 0x7C00001B, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"icmulta", "#d1,s,t", 0x7C00011B, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qcmulta", "#d1,s,t", 0x7C00051B, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"madda", "#d1,s,t", 0x7C000012, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"maddau", "#d1,s,t", 0x7C000212, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imadda", "#d1,s,t", 0x7C000002, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"imaddau", "#d1,s,t", 0x7C000202, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmadda", "#d1,s,t", 0x7C000402, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"madda2", "#d2,s,t", 0x7C000052, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imadda2", "#d2,s,t", 0x7C000042, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmadda2", "#d2,s,t", 0x7C000442, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"madda2.s", "#d2,s,t", 0x7C0000D2, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imadda2.s32", "#d2,s,t", 0x7C0000C2, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmadda2.s32", "#d2,s,t", 0x7C0004C2, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"imadda2.s40", "#d2,s,t", 0x7C0001C2, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmadda2.s40", "#d2,s,t", 0x7C0005C2, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"msuba", "#d1,s,t", 0x7C000013, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"msubau", "#d1,s,t", 0x7C000213, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imsuba", "#d1,s,t", 0x7C000003, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"imsubau", "#d1,s,t", 0x7C000203, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmsuba", "#d1,s,t", 0x7C000403, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"msuba2", "#d2,s,t", 0x7C000053, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imsuba2", "#d2,s,t", 0x7C000043, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmsuba2", "#d2,s,t", 0x7C000443, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"msuba2.s", "#d2,s,t", 0x7C0000D3, 0xFC0007FF, RD_t | RD_s, 0, RAD1},
++{"imsuba2.s32", "#d2,s,t", 0x7C0000C3, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmsuba2.s32", "#d2,s,t", 0x7C0004C3, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"imsuba2.s40", "#d2,s,t", 0x7C0001C3, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"qmsuba2.s40", "#d2,s,t", 0x7C0005C3, 0xFC0007FF, RD_t | RD_s, 0, RAD2},
++{"addma", "#d3,#s3,#t3", 0x7C00001E, 0xFC0007FF, 0, 0, RAD1},
++{"addma.s", "#d3,#s3,#t3", 0x7C00009E, 0xFC0007FF, 0, 0, RAD1},
++{"addma.s32", "#d3,#s3,#t3", 0x7C00041E, 0xFC0007FF, 0, 0, RAD2},
++{"addma.s40", "#d3,#s3,#t3", 0x7C00049E, 0xFC0007FF, 0, 0, RAD2},
++{"subma", "#d3,#s3,#t3", 0x7C00001F, 0xFC0007FF, 0, 0, RAD1},
++{"subma.s", "#d3,#s3,#t3", 0x7C00009F, 0xFC0007FF, 0, 0, RAD1},
++{"subma.s32", "#d3,#s3,#t3", 0x7C00041F, 0xFC0007FF, 0, 0, RAD2},
++{"subma.s40", "#d3,#s3,#t3", 0x7C00049F, 0xFC0007FF, 0, 0, RAD2},
++{"rnda2", "#t2", 0x7C000056, 0xFFE0FFFF, 0, 0, RAD1},
++{"rnda2", "#t2,##", 0x7C000056, 0xFFE0F87F, 0, 0, RAD1},
++{"lt", "#`,#@(b)", 0x7C000036, 0xFC00003F, LDD | RD_b | WR_t, 0, RAD1},
++{"st", "#`,#@(b)", 0x7C00003E, 0xFC00003F, SM | RD_t | RD_b, 0, RAD1},
++{"ltp", "#`,(b)#~", 0x7C0000f2, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"ltp.c0", "#`,(b)#~", 0x7C000032, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"ltp.c1", "#`,(b)#~", 0x7C000072, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"ltp.c2", "#`,(b)#~", 0x7C0000b2, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lwp", "t,(b)#~", 0x7C0000f3, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lwp.c0", "t,(b)#~", 0x7C000033, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lwp.c1", "t,(b)#~", 0x7C000073, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lwp.c2", "t,(b)#~", 0x7C0000b3, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhp", "t,(b)#~", 0x7C0000f1, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhp.c0", "t,(b)#~", 0x7C000031, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhp.c1", "t,(b)#~", 0x7C000071, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhp.c2", "t,(b)#~", 0x7C0000b1, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhpu", "t,(b)#~", 0x7C0000f5, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhpu.c0", "t,(b)#~", 0x7C000035, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhpu.c1", "t,(b)#~", 0x7C000075, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lhpu.c2", "t,(b)#~", 0x7C0000b5, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbp", "t,(b)#~", 0x7C0000f0, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbp.c0", "t,(b)#~", 0x7C000030, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbp.c1", "t,(b)#~", 0x7C000070, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbp.c2", "t,(b)#~", 0x7C0000b0, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbpu", "t,(b)#~", 0x7C0000f4, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbpu.c0", "t,(b)#~", 0x7C000034, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbpu.c1", "t,(b)#~", 0x7C000074, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"lbpu.c2", "t,(b)#~", 0x7C0000b4, 0xFC0000FF, LDD | WR_t | RD_b, 0, RAD1},
++{"stp", "#`,(b)#~", 0x7C0000fa, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"stp.c0", "#`,(b)#~", 0x7C00003a, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"stp.c1", "#`,(b)#~", 0x7C00007a, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"stp.c2", "#`,(b)#~", 0x7C0000ba, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"swp", "t,(b)#~", 0x7C0000fb, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"swp.c0", "t,(b)#~", 0x7C00003b, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"swp.c1", "t,(b)#~", 0x7C00007b, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"swp.c2", "t,(b)#~", 0x7C0000bb, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"shp", "t,(b)#~", 0x7C0000f9, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"shp.c0", "t,(b)#~", 0x7C000039, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"shp.c1", "t,(b)#~", 0x7C000079, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"shp.c2", "t,(b)#~", 0x7C0000b9, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"sbp", "t,(b)#~", 0x7C0000f8, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"sbp.c0", "t,(b)#~", 0x7C000038, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"sbp.c1", "t,(b)#~", 0x7C000078, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"sbp.c2", "t,(b)#~", 0x7C0000b8, 0xFC0000FF, WR_t | RD_b, 0, RAD1},
++{"mtru", "t,#u", 0x7C000025, 0xFFE007FF, RD_t, 0, RAD1},
++{"mfru", "t,#u", 0x7C000024, 0xFFE007FF, RD_t, 0, RAD1},
++{"mtrk", "t,#k", 0x7C0000A5, 0xFFE007FF, RD_t, 0, RAD1},
++{"mfrk", "t,#k", 0x7C0000A4, 0xFFE007FF, RD_t, 0, RAD1},
++{"sllv2", "d,t,s", 0x7C000044, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"srlv2", "d,t,s", 0x7C000046, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"srav2", "d,t,s", 0x7C000047, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"addr", "d,s,t", 0x7C000021, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"addr.s", "d,s,t", 0x7C0000A1, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"addr2", "d,s,t", 0x7C000061, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"addr2.s", "d,s,t", 0x7C0000E1, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"subr", "d,s,t", 0x7C000023, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"subr.s", "d,s,t", 0x7C0000A3, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"subr2", "d,s,t", 0x7C000063, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"subr2.s", "d,s,t", 0x7C0000E3, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"sltr2", "d,s,t", 0x7C00006A, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"min", "d,s,t", 0x7C000028, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"min2", "d,s,t", 0x7C000068, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"max", "d,s,t", 0x7C000029, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"max2", "d,s,t", 0x7C000069, 0xFC0007FF, RD_t | RD_s | WR_d, 0, RAD1},
++{"absr", "d,t", 0x7C00000F, 0xFFE007FF, RD_t | WR_d, 0, RAD1},
++{"absr.s", "d,t", 0x7C00008F, 0xFFE007FF, RD_t | WR_d, 0, RAD1},
++{"absr2", "d,t", 0x7C00004F, 0xFFE007FF, RD_t | WR_d, 0, RAD1},
++{"absr2.s", "d,t", 0x7C0000CF, 0xFFE007FF, RD_t | WR_d, 0, RAD1},
++{"mux2.hh", "d,s,t", 0x7C00064D, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"mux2.hl", "d,s,t", 0x7C00044D, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"mux2.lh", "d,s,t", 0x7C00024D, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"mux2.ll", "d,s,t", 0x7C00004D, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cls", "d,t", 0x7C00000E, 0xFFE007FF, RD_t | WR_d, 0, RAD1},
++{"cmveqz", "d,s,t", 0x7C000001, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cmveqz.h", "d,s,t", 0x7C000081, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cmveqz.l", "d,s,t", 0x7C000101, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cmvnez", "d,s,t", 0x7C000041, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cmvnez.h", "d,s,t", 0x7C0000c1, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++{"cmvnez.l", "d,s,t", 0x7C000141, 0xFC0007FF, RD_s | RD_t | WR_d, 0, RAD1},
++
++
++/* Coprocessor 0 operations */
++{"mflxc0", "t,#d4", 0x40600000, 0xFFE007FF, LCD | WR_t | RD_C0, 0, RLXB},
++{"mflxc0", "t,#d4,#H", 0x40600000, 0xFFE007C0, LCD | WR_t | RD_C0, 0, RLX3},
++{"mtlxc0", "t,#d4", 0x40E00000, 0xFFE007FF, COD | RD_t | WR_C0 | WR_CC, 0, RLXB},
++{"mtlxc0", "t,#d4,#H", 0x40E00000, 0xFFE007C0, COD | RD_t | WR_C0 | WR_CC, 0, RLX3},
++/*MAC-DIV*/
++{"sleep", "", 0x42000038, 0xffffffff, 0, 0, RLXA},
++{"sleep", "#I", 0x42000038, 0xfffff83f, 0, 0, RLX3},
++{"madh", "s,t", 0xF0000000, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"madl", "s,t", 0xF0000002, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"mazh", "s,t", 0xF0000004, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"mazl", "s,t", 0xF0000006, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"msbh", "s,t", 0xF0000010, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"msbl", "s,t", 0xF0000012, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"mszh", "s,t", 0xF0000014, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"mszl", "s,t", 0xF0000016, 0xFC00FFFF, RD_s | RD_t, 0, RLXA},
++{"ltw", "#`,#-(b)", 0x7800003C, 0xFC00003F, LDD | RD_b | WR_t, 0, INSN_4181 | INSN_4281},
++/* Lexra opcode extensions. Register mode */
++/* Lexra opcode extensions. Immediate mode */
++{"udi0i", "t,r,j", 0x60000000, 0xfc000000, WR_t | RD_s, 0, RLXB},
++{"udi1i", "t,r,j", 0x64000000, 0xfc000000, WR_t | RD_s, 0, RLXB},
++{"udi2i", "t,r,j", 0x68000000, 0xfc000000, WR_t | RD_s, 0, RLXB},
++{"udi3i", "t,r,j", 0x6c000000, 0xfc000000, WR_t | RD_s, 0, RLXB},
+ };
+
+ #define MIPS_NUM_OPCODES \
+Index: binutils/bfd/bfd-in2.h
+===================================================================
+--- binutils.orig/bfd/bfd-in2.h
++++ binutils/bfd/bfd-in2.h
+@@ -1828,11 +1828,17 @@ enum bfd_architecture
+ #define bfd_mach_mips4100 4100
+ #define bfd_mach_mips4111 4111
+ #define bfd_mach_mips4120 4120
++#define bfd_mach_mips4180 4180
++#define bfd_mach_mips4181 4181
++#define bfd_mach_mips4281 4281
+ #define bfd_mach_mips4300 4300
+ #define bfd_mach_mips4400 4400
+ #define bfd_mach_mips4600 4600
+ #define bfd_mach_mips4650 4650
+ #define bfd_mach_mips5000 5000
++#define bfd_mach_mips5181 5181
++#define bfd_mach_mips5280 5280
++#define bfd_mach_mips5281 5281
+ #define bfd_mach_mips5400 5400
+ #define bfd_mach_mips5500 5500
+ #define bfd_mach_mips6000 6000
+@@ -2189,7 +2195,8 @@ typedef enum bfd_reloc_status
+ generated only when linking i960 coff files with i960 b.out
+ symbols. If this type is returned, the error_message argument
+ to bfd_perform_relocation will be set. */
+- bfd_reloc_dangerous
++ bfd_reloc_dangerous,
++ bfd_reloc_notmultipleof8_ltw
+ }
+ bfd_reloc_status_type;
+
+@@ -4680,6 +4687,7 @@ value in a word. The relocation is rela
+ /* This is used to tell the dynamic linker to copy the value out of
+ the dynamic object into the runtime process image. */
+ BFD_RELOC_MICROBLAZE_COPY,
++ BFD_RELOC_OFF6A,
+ BFD_RELOC_UNUSED };
+ typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+ reloc_howto_type *bfd_reloc_type_lookup
+Index: binutils/bfd/cpu-mips.c
+===================================================================
+--- binutils.orig/bfd/cpu-mips.c
++++ binutils/bfd/cpu-mips.c
+@@ -67,11 +67,17 @@ enum
+ I_mips4100,
+ I_mips4111,
+ I_mips4120,
++ I_mips4180,
++ I_mips4181,
++ I_mips4281,
+ I_mips4300,
+ I_mips4400,
+ I_mips4600,
+ I_mips4650,
+ I_mips5000,
++ I_mips5181,
++ I_mips5280,
++ I_mips5281,
+ I_mips5400,
+ I_mips5500,
+ I_mips6000,
+@@ -106,11 +112,17 @@ static const bfd_arch_info_type arch_inf
+ N (64, 64, bfd_mach_mips4100, "mips:4100", FALSE, NN(I_mips4100)),
+ N (64, 64, bfd_mach_mips4111, "mips:4111", FALSE, NN(I_mips4111)),
+ N (64, 64, bfd_mach_mips4120, "mips:4120", FALSE, NN(I_mips4120)),
++ N (32, 32, bfd_mach_mips4180, "mips:4180", FALSE, NN(I_mips4180)),
++ N (32, 32, bfd_mach_mips4181, "mips:4181", FALSE, NN(I_mips4181)),
++ N (32, 32, bfd_mach_mips4281, "mips:4281", FALSE, NN(I_mips4281)),
+ N (64, 64, bfd_mach_mips4300, "mips:4300", FALSE, NN(I_mips4300)),
+ N (64, 64, bfd_mach_mips4400, "mips:4400", FALSE, NN(I_mips4400)),
+ N (64, 64, bfd_mach_mips4600, "mips:4600", FALSE, NN(I_mips4600)),
+ N (64, 64, bfd_mach_mips4650, "mips:4650", FALSE, NN(I_mips4650)),
+ N (64, 64, bfd_mach_mips5000, "mips:5000", FALSE, NN(I_mips5000)),
++ N (32, 32, bfd_mach_mips5181, "mips:5181", FALSE, NN(I_mips5181)),
++ N (32, 32, bfd_mach_mips5280, "mips:5280", FALSE, NN(I_mips5280)),
++ N (32, 32, bfd_mach_mips5281, "mips:5281", FALSE, NN(I_mips5281)),
+ N (64, 64, bfd_mach_mips5400, "mips:5400", FALSE, NN(I_mips5400)),
+ N (64, 64, bfd_mach_mips5500, "mips:5500", FALSE, NN(I_mips5500)),
+ N (32, 32, bfd_mach_mips6000, "mips:6000", FALSE, NN(I_mips6000)),
+Index: binutils/opcodes/mips-dis.c
+===================================================================
+--- binutils.orig/opcodes/mips-dis.c
++++ binutils/opcodes/mips-dis.c
+@@ -32,6 +32,28 @@
+ symbol table is available when this code runs out in an embedded
+ system as when it is used for disassembler support in a monitor. */
+
++int is_rlx_insn = 0;
++int des_reg_type = 0;
++/* the des reg is:
++ * 0 gr,
++ * 1 accumulator,
++ * 2 Radiax User register,
++ * 3 Selects Lexra Coprocessor0 register
++ */
++int src_reg_type = 0;
++/* the src reg is:
++ * 0 gr,
++ * 1 accumulator,
++ * 2 Radiax User register
++ */
++int targ_reg_type = 0;
++/* the target reg is:
++ * 0 gr,
++ * 1 accumulator,
++ * 2 Radiax User register
++ */
++
++
+ #if !defined(EMBEDDED_ENV)
+ #define SYMTAB_AVAILABLE 1
+ #include "elf-bfd.h"
+@@ -84,6 +106,16 @@ static const char * const mips_gpr_names
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+ };
+
++static const char *const mips_accumulator_names_alias[16] = {
++ "reserve", "m0l", "m0h", "m0", "reserve", "m1l", "m1h", "m1",
++ "reserve", "m2l", "m2h", "m2", "reserve", "m3l", "m3h", "m3"
++};
++
++static const char *const mips_radreg_names_alias[14] = {
++ "cbs0", "cbs1", "cbs2", "reserved", "cbe0", "cbe1", "cbe2", "reserved",
++ "lps0", "lpe0", "lpc0", "reserved", "mmd", "reserved"
++};
++
+ static const char * const mips_fpr_names_numeric[32] =
+ {
+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+@@ -433,6 +465,12 @@ const struct mips_arch_choice mips_arch_
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+ { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "4180", 1, bfd_mach_mips4180, CPU_LX4180, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
++ { "4181", 1, bfd_mach_mips4181, CPU_RLX4181, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
++ { "4281", 1, bfd_mach_mips4281, CPU_RLX4281, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
+ { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+ { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
+@@ -443,6 +481,12 @@ const struct mips_arch_choice mips_arch_
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+ { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "5181", 1, bfd_mach_mips5181, CPU_RLX5181, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
++ { "5281", 1, bfd_mach_mips5281, CPU_RLX5281, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
++ { "5280", 1, bfd_mach_mips5280, CPU_LX5280, ISA_MIPS1,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric},
+ { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+ { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
+@@ -815,6 +859,7 @@ print_insn_args (const char *d,
+ {
+ int op, delta;
+ unsigned int lsb, msb, msbd;
++ int tmp_regno;
+
+ lsb = 0;
+
+@@ -1074,13 +1119,22 @@ print_insn_args (const char *d,
+ case 'b':
+ case 'r':
+ case 'v':
+- (*info->fprintf_func) (info->stream, "%s",
++ if (src_reg_type == 1)
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_accumulator_names_alias[(l >> OP_SH_RS) & OP_MASK_RS]);
++ else
++ (*info->fprintf_func) (info->stream, "%s",
+ mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
++
+ break;
+
+ case 't':
+ case 'w':
+- (*info->fprintf_func) (info->stream, "%s",
++ if (targ_reg_type == 1)
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_accumulator_names_alias[(l >> OP_SH_RT) & OP_MASK_RT]);
++ else
++ (*info->fprintf_func) (info->stream, "%s",
+ mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+ break;
+
+@@ -1131,8 +1185,50 @@ print_insn_args (const char *d,
+ break;
+
+ case 'd':
+- (*info->fprintf_func) (info->stream, "%s",
++ switch(des_reg_type) {
++ case 1:
++ tmp_regno = (l >> OP_SH_RD) & OP_MASK_RD;
++ if (tmp_regno >= 16 || tmp_regno < 0)
++ (*info->fprintf_func) (info->stream, "INVALID");
++ else
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_accumulator_names_alias
++ [tmp_regno]);
++ break;
++ case 2:
++ tmp_regno = (l >> OP_SH_RD) & OP_MASK_RD;
++ if (tmp_regno <= 7)
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_radreg_names_alias[tmp_regno]);
++ else if ((16 <= tmp_regno) && (tmp_regno <= 19))
++ {
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_radreg_names_alias[tmp_regno -
++ 8]);
++ }
++ else if (tmp_regno == 24)
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_radreg_names_alias[12]);
++ else
++ (*info->fprintf_func) (info->stream, "%s",
++ mips_radreg_names_alias[13]);
++ break;
++ case 3:
++ tmp_regno = (l >> OP_SH_RD) & OP_MASK_RD;
++ if (tmp_regno == 0)
++ (*info->fprintf_func) (info->stream, "estatus");
++ else if (tmp_regno == 1)
++ (*info->fprintf_func) (info->stream, "ecause");
++ else if (tmp_regno == 2)
++ (*info->fprintf_func) (info->stream, "intvec");
++ else
++ (*info->fprintf_func) (info->stream, "reserved");
++ break;
++ default:
++ (*info->fprintf_func) (info->stream, "%s",
+ mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
++ break;
++ }
+ break;
+
+ case 'U':
+@@ -1329,6 +1425,40 @@ print_insn_args (const char *d,
+ (l >> OP_SH_FT) & OP_MASK_FT);
+ break;
+
++ case '#':
++ (*info->fprintf_func) (info->stream, "%i",
++ (l >> OP_SH_IMMIDATE74) &
++ OP_MASK_IMMIDATE74);
++ break;
++
++ /* 8 bits immediate ,used in lbp,stp,etc(OP_*_IMMIDATE88) */
++ case '~':
++ delta = (l >> OP_SH_IMMIDATE88) & OP_MASK_IMMIDATE88;
++ if (delta & 0x80)
++ delta |= ~0xff;
++
++ (*info->fprintf_func) (info->stream, "%i", delta);
++ break;
++
++ /* even register,used in lt,st,ltp,stp (OP_*_EVENREG) */
++ case '`':
++ delta = (l >> OP_SH_EVENREG) & OP_MASK_EVENREG;
++ if ((delta % 2) != 0)
++ delta--; /* for "lt" insn */
++ (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[delta]);
++ break;
++
++ /* 10 bits offset,used in ltw(OP_*_OFFSET6A) */
++ case '-':
++ delta = (l >> OP_SH_OFFSET6A) & OP_MASK_OFFSET6A;
++ if (delta & 0x200)
++ delta |= ~0x3ff;
++ /* 2006-02-08 tonywu: fix ltw objdump displacement */
++ delta <<= 3;
++ (*info->fprintf_func) (info->stream, "%d", delta);
++
++ break;
++
+ default:
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream,
+@@ -1426,6 +1556,80 @@ print_insn_mips (bfd_vma memaddr,
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+
+ d = op->args;
++
++ des_reg_type = 0;
++ src_reg_type = 0;
++ targ_reg_type = 0;
++
++ if ((op->membership & INSN_4181) ||
++ (op->membership & INSN_4281) ||
++ (op->membership & INSN_5181) ||
++ (op->membership & INSN_5281) ||
++ (op->membership & INSN_5280))
++ {
++ is_rlx_insn = 1;
++ if (strncmp (op->name, "mta2", 4) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if ((strncmp (op->name, "mflxc0", 6) == 0)
++ || (strncmp (op->name, "mtlxc0", 6) == 0))
++ {
++ des_reg_type = 3;
++ }
++ else if (strncmp (op->name, "mfa", 3) == 0)
++ {
++ targ_reg_type = 1;
++ }
++ else if (strncmp (op->name, "diva", 4) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "multa", 5) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "mulna2", 6) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "cmulta", 6) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "madda", 5) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "msuba", 5) == 0)
++ {
++ des_reg_type = 1;
++ }
++ else if (strncmp (op->name, "addma", 5) == 0)
++ {
++ des_reg_type = 1;
++ src_reg_type = 1;
++ targ_reg_type = 1;
++ }
++ else if (strncmp (op->name, "subma", 5) == 0)
++ {
++ des_reg_type = 1;
++ src_reg_type = 1;
++ targ_reg_type = 1;
++ }
++ else if (strncmp (op->name, "rnda2", 5) == 0)
++ {
++ targ_reg_type = 1;
++ }
++ else if (strncmp (op->name, "mtru", 4) == 0)
++ {
++ des_reg_type = 2;
++ }
++ else if (strncmp (op->name, "mfru", 4) == 0)
++ {
++ des_reg_type = 2;
++ }
++ }
+ if (d != NULL && *d != '\0')
+ {
+ (*info->fprintf_func) (info->stream, "\t");
+Index: binutils/opcodes/mips16-opc.c
+===================================================================
+--- binutils.orig/opcodes/mips16-opc.c
++++ binutils/opcodes/mips16-opc.c
+@@ -65,6 +65,11 @@
+ #define I64 INSN_ISA64
+ #define T3 INSN_3900
+
++#define RLX1 INSN_4180 | INSN_4181 | INSN_4281 | INSN_5181 | INSN_5280 | INSN_5281
++#define RLX2 INSN_4181 | INSN_4281 | INSN_5181 | INSN_5280 | INSN_5281
++#define RLX3 INSN_4181 | INSN_4281 | INSN_5181 | INSN_5281
++#define RLX4 INSN_5181 | INSN_5280 | INSN_5281
++
+ const struct mips_opcode mips16_opcodes[] =
+ {
+ /* name, args, match, mask, pinfo, pinfo2, membership */
+@@ -109,6 +114,7 @@ const struct mips_opcode mips16_opcodes[
+ {"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 },
+ {"bnez", "x,p", 0x2800, 0xf800, BR|RD_x, 0, I1 },
+ {"break", "6", 0xe805, 0xf81f, TRAP, 0, I1 },
++{"break", "", 0xe805, 0xffff, TRAP, 0, RLX1},
+ {"bteqz", "p", 0x6000, 0xff00, BR|RD_T, 0, I1 },
+ {"btnez", "p", 0x6100, 0xff00, BR|RD_T, 0, I1 },
+ {"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1 },
+@@ -184,10 +190,18 @@ const struct mips_opcode mips16_opcodes[
+ {"lw", "x,V(P)", 0xb000, 0xf800, WR_x|RD_PC, 0, I1 },
+ {"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP, 0, I1 },
+ {"lwu", "y,W(x)", 0xb800, 0xf800, WR_y|RD_x, 0, I3 },
++{"madh", "x,y", 0xf800, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"madl", "x,y", 0xf802, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"mazh", "x,y", 0xf804, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"mazl", "x,y", 0xf806, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
+ {"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI, 0, I1 },
+ {"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO, 0, I1 },
+ {"move", "y,X", 0x6700, 0xff00, WR_y|RD_X, 0, I1 },
+ {"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z, 0, I1 },
++{"msbh", "x,y", 0xf810, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"msbl", "x,y", 0xf812, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"mszh", "x,y", 0xf814, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
++{"mszl", "x,y", 0xf816, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RLX1},
+ {"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1 },
+ {"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 },
+ {"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 },
+Index: binutils/include/opcode/mips.h
+===================================================================
+--- binutils.orig/include/opcode/mips.h
++++ binutils/include/opcode/mips.h
+@@ -58,6 +58,22 @@ Software Foundation, 51 Franklin Street
+
+ The general coprocessor instructions use COPZ. */
+
++#define OP_MASK_IMMIDATE74 0xf /* used in MFA,MFA2,RNDA2 */
++#define OP_SH_IMMIDATE74 7 /* used in MFA,MFA2,RNDA2 */
++#define OP_MASK_IMMIDATE6b 0x7ff /* used in lt,st */
++#define OP_SH_IMMIDATE6b 6 /* used in lt,st */
++#define OP_MASK_IMMIDATE88 0xff /* used in lbp,stp,etc */
++#define OP_SH_IMMIDATE88 8 /* used in lbp,stp,etc */
++#define OP_MASK_EVENREG 0x1f /* used in lt,st,ltp,stp */
++#define OP_SH_EVENREG 16 /* used in lt,st,ltp,stp */
++#define OP_MASK_OFFSET6A 0x3ff /* used in ltw */
++#define OP_SH_OFFSET6A 6 /* used in ltw */
++
++#define OP_MASK_RLX_SEL 0x3f
++#define OP_SH_RLX_SEL 0
++#define OP_MASK_RLX_STYPE 0x3f
++#define OP_SH_RLX_STYPE 6
++
+ #define OP_MASK_OP 0x3f
+ #define OP_SH_OP 26
+ #define OP_MASK_RS 0x1f
+@@ -274,6 +290,13 @@ struct mips_opcode
+ "j" 16 bit signed immediate (OP_*_DELTA)
+ "k" 5 bit cache opcode in target register position (OP_*_CACHE)
+ Also used for immediate operands in vr5400 vector insns.
++*********************** dbb modified for supporting radiax instructions **************************
++ "@" 11 bits immediate used in lt,st (OP_*_IMMIDATE6b),in fact it is 14 bits,mutiple of 8;
++ "#" 4 bits immediate from 0 to 8,used in MFA,MFA2,RNDA2 (OP_*_IMMIDATE74)
++ "~" 8 bits immediate ,used in lbp,stp,etc(OP_*_IMMIDATE88)
++ "`" even register,used in lt,st,ltp,stp (OP_*_EVENREG)
++ "-" 10 bits offset,used in ltw(OP_*_OFFSET6A)
++*********************** dbb modified for supporting radiax instructions **************************
+ "o" 16 bit signed offset (OP_*_DELTA)
+ "p" 16 bit PC relative branch target address (OP_*_DELTA)
+ "q" 10 bit extra breakpoint code (OP_*_CODE2)
+@@ -571,15 +594,18 @@ static const unsigned int mips_isa_table
+ #define INSN_10000 0x00100000
+ /* Broadcom SB-1 instruction. */
+ #define INSN_SB1 0x00200000
++
+ /* NEC VR4111/VR4181 instruction. */
+ #define INSN_4111 0x00400000
+ /* NEC VR4120 instruction. */
+ #define INSN_4120 0x00800000
++
++
++#if 0 //JMM - break all these badly sorry!
+ /* NEC VR5400 instruction. */
+ #define INSN_5400 0x01000000
+ /* NEC VR5500 instruction. */
+ #define INSN_5500 0x02000000
+-
+ /* MDMX ASE */
+ #define INSN_MDMX 0x04000000
+ /* MT ASE */
+@@ -592,6 +618,35 @@ static const unsigned int mips_isa_table
+ #define INSN_LOONGSON_2E 0x40000000
+ /* ST Microelectronics Loongson 2F. */
+ #define INSN_LOONGSON_2F 0x80000000
++#else
++
++#define INSN_4180 0x01000000
++#define INSN_4181 0x02000000
++#define INSN_4281 0x04000000
++#define INSN_5181 0x08000000
++#define INSN_5280 0x10000000
++#define INSN_5281 0x20000000
++
++#define INSN_DONT_CARE 0x80000000
++/* NEC VR5400 instruction. */
++#define INSN_5400 INSN_DONT_CARE
++/* NEC VR5500 instruction. */
++#define INSN_5500 INSN_DONT_CARE
++/* MDMX ASE */
++#define INSN_MDMX INSN_DONT_CARE
++/* MT ASE */
++#define INSN_MT INSN_DONT_CARE
++/* SmartMIPS ASE */
++#define INSN_SMARTMIPS INSN_DONT_CARE
++/* DSP R2 ASE */
++#define INSN_DSPR2 INSN_DONT_CARE
++/* ST Microelectronics Loongson 2E. */
++#define INSN_LOONGSON_2E INSN_DONT_CARE
++/* ST Microelectronics Loongson 2F. */
++#define INSN_LOONGSON_2F INSN_DONT_CARE
++#endif
++
++
+ /* RMI Xlr instruction */
+ #define INSN_XLR 0x00000020
+
+@@ -621,11 +676,17 @@ static const unsigned int mips_isa_table
+ #define CPU_VR4100 4100
+ #define CPU_R4111 4111
+ #define CPU_VR4120 4120
++#define CPU_LX4180 4180 /* LX4180 */
++#define CPU_RLX4181 4181 /* RLX4181 */
++#define CPU_RLX4281 4281 /* RLX4281 */
+ #define CPU_R4300 4300
+ #define CPU_R4400 4400
+ #define CPU_R4600 4600
+ #define CPU_R4650 4650
+ #define CPU_R5000 5000
++#define CPU_RLX5181 5181 /* RLX5181 */
++#define CPU_RLX5281 5281 /* RLX5281 */
++#define CPU_LX5280 5280 /* LX5280 */
+ #define CPU_VR5400 5400
+ #define CPU_VR5500 5500
+ #define CPU_R6000 6000
+@@ -681,6 +742,12 @@ static const unsigned int mips_isa_table
+ || (cpu == CPU_OCTEON \
+ && ((insn)->membership & INSN_OCTEON) != 0) \
+ || (cpu == CPU_XLR && ((insn)->membership & INSN_XLR) != 0) \
++ || (cpu == CPU_LX4180 && ((insn)->membership & INSN_4180) != 0) \
++ || (cpu == CPU_RLX4181 && ((insn)->membership & INSN_4181) != 0) \
++ || (cpu == CPU_RLX4281 && ((insn)->membership & INSN_4281) != 0) \
++ || (cpu == CPU_RLX5181 && ((insn)->membership & INSN_5181) != 0) \
++ || (cpu == CPU_LX5280 && ((insn)->membership & INSN_5280) != 0) \
++ || (cpu == CPU_RLX5281 && ((insn)->membership & INSN_5281) != 0) \
+ || 0) /* Please keep this term for easier source merging. */
+
+ /* This is a list of macro expanded instructions.
+Index: binutils/gas/config/tc-mips.c
+===================================================================
+--- binutils.orig/gas/config/tc-mips.c
++++ binutils/gas/config/tc-mips.c
+@@ -99,6 +99,32 @@ static char *mips_regmask_frag;
+ #define FP 30
+ #define RA 31
+
++#define M0L 1
++#define M0H 2
++#define M0 3
++#define M1L 5
++#define M1H 6
++#define M1 7
++#define M2L 9
++#define M2H 10
++#define M2 11
++#define M3L 13
++#define M3H 14
++#define M3 15
++#define ESTATUS 0
++#define ECAUSE 1
++#define INTVEC 2
++#define CBS0 0
++#define CBS1 1
++#define CBS2 2
++#define CBE0 4
++#define CBE1 5
++#define CBE2 6
++#define LPS0 16
++#define LPE0 17
++#define LPC0 18
++#define MMD 24
++
+ #define ILLEGAL_REG (32)
+
+ #define AT mips_opts.at
+@@ -272,6 +298,8 @@ static struct mips_set_options mips_opts
+ /* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE
+ };
+
++static const struct mips_opcode dummy_opcode = { NULL, NULL, 0, 0, 0, 0, 0 };
++
+ /* These variables are filled in with the masks of registers used.
+ The object format code reads them and puts them in the appropriate
+ place. */
+@@ -497,7 +525,10 @@ static int mips_32bitmode = 0;
+ level I. */
+ #define gpr_interlocks \
+ (mips_opts.isa != ISA_MIPS1 \
+- || mips_opts.arch == CPU_R3900)
++ || mips_opts.arch == CPU_R3900 \
++ || mips_opts.arch == CPU_RLX4281 \
++ || mips_opts.arch == CPU_LX5280 \
++ || mips_opts.arch == CPU_RLX5281 )
+
+ /* Whether the processor uses hardware interlocks to avoid delays
+ required by coprocessor instructions, and thus does not require
+@@ -1102,6 +1133,11 @@ static void s_mips_loc (int);
+ static bfd_boolean pic_need_relax (symbolS *, asection *);
+ static int relaxed_branch_length (fragS *, asection *, int);
+ static int validate_mips_insn (const struct mips_opcode *);
++static inline int rlx_nops_for_new_insn (const struct mips_cl_insn *, const struct mips_cl_insn *);
++static inline int rlx_is_insn_lt (const struct mips_cl_insn *, const struct mips_cl_insn *);
++static inline int rlx_is_insn_st (const struct mips_cl_insn *, const struct mips_cl_insn *);
++static inline int rlx_is_insn_swappable (const struct mips_cl_insn *, const struct mips_cl_insn *);
++
+
+ /* Table and functions used to map between CPU/ISA names, and
+ ISA levels, and CPU numbers. */
+@@ -1683,6 +1719,34 @@ struct regname {
+ #define MIPS16_SPECIAL_REGISTER_NAMES \
+ {"$pc", RTYPE_PC | 0}
+
++#define RLX_REGISTER_ALIAS_NAMES \
++ {"$m0l", RTYPE_GP | 1}, \
++ {"$m0h", RTYPE_GP | 2}, \
++ {"$m0", RTYPE_GP | 3}, \
++ {"$m1l", RTYPE_GP | 5}, \
++ {"$m1h", RTYPE_GP | 6}, \
++ {"$m1", RTYPE_GP | 7}, \
++ {"$m2l", RTYPE_GP | 9}, \
++ {"$m2h", RTYPE_GP | 10}, \
++ {"$m2", RTYPE_GP | 11}, \
++ {"$m3l", RTYPE_GP | 13}, \
++ {"$m3l", RTYPE_GP | 14}, \
++ {"$m3", RTYPE_GP | 15}, \
++ {"$estatus", RTYPE_GP | 0}, \
++ {"$ecause", RTYPE_GP | 1}, \
++ {"$intvec", RTYPE_GP | 2}, \
++ {"$mmd", RTYPE_GP | 24}, \
++ {"$cbs0", RTYPE_GP | 0}, \
++ {"$cbs1", RTYPE_GP | 1}, \
++ {"$cbs2", RTYPE_GP | 2}, \
++ {"$cbe0", RTYPE_GP | 4}, \
++ {"$cbe1", RTYPE_GP | 5}, \
++ {"$cbe2", RTYPE_GP | 6}, \
++ {"$lps0", RTYPE_GP | 16}, \
++ {"$lpe0", RTYPE_GP | 17}, \
++ {"$lpc0", RTYPE_GP | 18}
++
++
+ #define MDMX_VECTOR_REGISTER_NAMES \
+ /* {"$v0", RTYPE_VEC | 0}, clash with REG 2 above */ \
+ /* {"$v1", RTYPE_VEC | 1}, clash with REG 3 above */ \
+@@ -1736,6 +1800,7 @@ static const struct regname reg_names[]
+ SYMBOLIC_REGISTER_NAMES,
+
+ MIPS16_SPECIAL_REGISTER_NAMES,
++ RLX_REGISTER_ALIAS_NAMES,
+ MDMX_VECTOR_REGISTER_NAMES,
+ MIPS_DSP_ACCUMULATOR_NAMES,
+ {0, 0}
+@@ -2556,6 +2621,13 @@ insns_between (const struct mips_cl_insn
+ || (!cop_interlocks && (pinfo1 & INSN_LOAD_COPROC_DELAY)))
+ {
+ know (pinfo1 & INSN_WRITE_GPR_T);
++
++ /* 2006-01-06 tonywu: insn2 == NULL => mips_optimize = 0 */
++ /* 2006-10-16 tonywu: fix lt nop bug */
++ if (rlx_is_insn_lt (insn1, insn2) || rlx_is_insn_st (insn1, insn2))
++ return 1;
++ /* 2006-10-16 tonywu: fix lt nop bug */
++
+ if (INSN2_USES_REG (EXTRACT_OPERAND (RT, *insn1), MIPS_GR_REG))
+ return 1;
+ }
+@@ -2613,7 +2685,7 @@ insns_between (const struct mips_cl_insn
+
+ #undef INSN2_USES_REG
+
+- return 0;
++ return rlx_nops_for_new_insn (insn1, insn2);
+ }
+
+ /* Return the number of nops that would be needed to work around the
+@@ -2687,6 +2759,36 @@ nops_for_insn (const struct mips_cl_insn
+ return nops;
+ }
+
++/* 2006-01-09 tonywu: fix branch delay slot filling bug */
++static inline int
++rlx_is_insn_swappable (const struct mips_cl_insn *history,
++ const struct mips_cl_insn *insn)
++{
++
++ unsigned long pinfo1, pinfo2;
++
++ pinfo1 = history[0].insn_mo->pinfo;
++ pinfo2 = history[1].insn_mo->pinfo;
++
++ if (pinfo1 & INSN_LOAD_MEMORY_DELAY || pinfo1 & INSN_WRITE_GPR_T)
++ {
++ if (insn_uses_reg (insn, EXTRACT_OPERAND (RT, history[0]), MIPS_GR_REG))
++ {
++ return 1;
++ }
++ }
++
++ if (pinfo2 & INSN_LOAD_MEMORY_DELAY || pinfo1 & INSN_WRITE_GPR_T)
++ {
++ if (insn_uses_reg (insn, EXTRACT_OPERAND (RT, history[1]), MIPS_GR_REG))
++ {
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
+ /* The variable arguments provide NUM_INSNS extra instructions that
+ might be added to HISTORY. Return the largest number of nops that
+ would be needed after the extended sequence. */
+@@ -3193,13 +3295,16 @@ append_insn (struct mips_cl_insn *ip, ex
+ /* We do not swap with a trap instruction, since it
+ complicates trap handlers to have the trap
+ instruction be in a delay slot. */
++ || rlx_is_insn_swappable (history, ip) > 0
+ || (prev_pinfo & INSN_TRAP)
+ /* If the branch reads a register that the previous
+ instruction sets, we can not swap. */
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_T)
+ && insn_uses_reg (ip, EXTRACT_OPERAND (RT, history[0]),
+- MIPS_GR_REG))
++ MIPS_GR_REG)
++ /* 2006-01-06 tonywu: add for lt/ltw */
++ && (rlx_is_insn_lt (history, ip)))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_D)
+ && insn_uses_reg (ip, EXTRACT_OPERAND (RD, history[0]),
+@@ -8555,6 +8660,32 @@ validate_mips_insn (const struct mips_op
+ case '1': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case '2': USE_BITS (OP_MASK_BP, OP_SH_BP); break;
+ case '3': USE_BITS (OP_MASK_SA3, OP_SH_SA3); break;
++ /* 2006-01-04 tonywu: merged from 2.14 to 2.16 */
++ case '#':
++ switch (c = *p++)
++ {
++ /* dbb: new instructions support */
++ case '`': USE_BITS (OP_MASK_EVENREG, OP_SH_EVENREG); break;
++ case '~': USE_BITS (OP_MASK_IMMIDATE88, OP_SH_IMMIDATE88); break;
++ case '#': USE_BITS (OP_MASK_IMMIDATE74, OP_SH_IMMIDATE74); break;
++ case '@': USE_BITS (OP_MASK_IMMIDATE6b, OP_SH_IMMIDATE6b); break;
++ case '-': USE_BITS (OP_MASK_OFFSET6A, OP_SH_OFFSET6A); break;
++ /* dbb: new instructions support */
++ /* 2008-07-08 tonywu: add for taroko processor */
++ case 'H': USE_BITS (OP_MASK_RLX_SEL, OP_SH_RLX_SEL); break;
++ case 'I': USE_BITS (OP_MASK_RLX_STYPE, OP_SH_RLX_STYPE); break;
++ case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); p++; break;
++ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); p++; break;
++ case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); p++; break;
++ case 'u': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
++ case 'k': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
++ /* 2008-07-08 tonywu: add for taroko processor */
++ default:
++ as_bad (_("internal: bad rlx opcode (unknown extension operand type `#%c'): %s %s"),
++ c, opc->name, opc->args);
++ return 0;
++ }
++ break;
+ case '4': USE_BITS (OP_MASK_SA4, OP_SH_SA4); break;
+ case '5': USE_BITS (OP_MASK_IMM8, OP_SH_IMM8); break;
+ case '6': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+@@ -8576,6 +8707,7 @@ validate_mips_insn (const struct mips_op
+ return 0;
+ }
+ #undef USE_BITS
++ if (strcmp (opc->name, "sleep") != 0)
+ if (used_bits != 0xffffffff)
+ {
+ as_bad (_("internal: bad mips opcode (bits 0x%lx undefined): %s %s"),
+@@ -8652,6 +8784,7 @@ mips_ip (char *str, struct mips_cl_insn
+ char *s;
+ const char *args;
+ char c = 0;
++ char t = 0;
+ struct mips_opcode *insn;
+ char *argsStart;
+ unsigned int regno;
+@@ -8661,6 +8794,7 @@ mips_ip (char *str, struct mips_cl_insn
+ char *s_reset;
+ char save_c = 0;
+ offsetT min_range, max_range;
++ int multipletype;
+ int argnum;
+ unsigned int rtype;
+
+@@ -9446,6 +9580,339 @@ do_msbd:
+ else
+ break;
+
++ case '#':
++ switch (*++args)
++ {
++ case 'd':
++ case 's':
++ case 't':
++ s_reset = s;
++ regno = 32;
++ if (s[0] == '$')
++ {
++ reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &regno);
++ }
++
++ /* 2006-11-28 tonywu: add radiax alias name */
++ c = *args;
++ t = *++args;
++
++ /* Now that we have assembled one operand, we use the args string
++ * to figure out where it goes in the instruction. */
++ switch (t)
++ {
++ case '1': /* m0(3), m1(7), m2(11), m3(15) */
++ if (regno <= 0 || regno > 15 || (regno & 3) != 3)
++ as_bad (_
++ ("RADIAX: illegal register (%d) in %s type d%c"),
++ regno, str, t);
++ break;
++
++ case '2': /* m0l, m0h, m0 ~ m3l, m3h, m3 */
++ if (regno <= 0 || regno > 15 || (regno & 3) == 0)
++ as_bad (_
++ ("RADIAX: illegal register (%d) in %s type d%c"),
++ regno, str, t);
++ break;
++
++ case '3': /* m0l, m0h, ~ m3l, m3h */
++ if (regno <= 0 || regno > 15
++ || (regno & 3) == 0 || (regno & 3) == 3)
++ as_bad (_
++ ("RADIAX: illegal register (%d) in %s type d%c"),
++ regno, str, t);
++ break;
++
++ case '4': /* LXC0 registers */
++ if (regno > 31)
++ as_bad (_
++ ("RLX: illegal register (%d) in %s type d%c"),
++ regno, str, t);
++ break;
++
++ default:
++ as_bad (_("RLX: illegal register type d%c in %s"), t,
++ str);
++ break;
++ }
++
++ switch (c)
++ {
++ case 'd':
++ INSERT_OPERAND (RD, *ip, regno);
++ break;
++ case 's':
++ INSERT_OPERAND (RS, *ip, regno);
++ break;
++ case 't':
++ INSERT_OPERAND (RT, *ip, regno);
++ break;
++ }
++
++ lastregno = regno;
++ continue;
++
++ case 'u':
++ case 'k':
++ s_reset = s;
++ regno = 32;
++ if (s[0] == '$')
++ {
++ reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &regno);
++ }
++ /* 2006-11-28 tonywu: add radiax alias name */
++ c = *args;
++
++ /* Now that we have assembled one operand, we use the args string
++ * to figure out where it goes in the instruction. */
++ if (regno == 32)
++ as_bad (_("RLX: illegal register (%d) in %s"), regno,
++ str);
++
++ switch (c)
++ {
++ case 'u':
++ INSERT_OPERAND (RD, *ip, regno);
++ break;
++ case 'k':
++ INSERT_OPERAND (RD, *ip, regno);
++ break;
++ }
++
++ lastregno = regno;
++ continue;
++
++ case '-':
++ /* 10bits offset used in ltw (OP_*_OFFSET6A),
++ * in fact it is 13 bits,multiple of 8; */
++ if (*s == '(' && strchr (s + 1, '(') == 0)
++ {
++ imm_expr.X_op = O_constant;
++ imm_expr.X_add_number = 0;
++ continue;
++ }
++
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if (imm_expr.X_op == O_constant)
++ {
++ if ((imm_expr.X_add_number % 8) != 0)
++ as_bad (_("(%d) is not multiple of 8"),
++ (int) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 4096) & ~0x1FFF) != 0)
++ as_bad (_("(%d) is too large to fit in 13 bits"),
++ (int) imm_expr.X_add_number);
++ ip->insn_opcode |=
++ (((imm_expr.X_add_number >> 3) & OP_MASK_OFFSET6A) <<
++ OP_SH_OFFSET6A);
++ imm_expr.X_op = O_absent;
++ }
++ else
++ {
++ *imm_reloc = BFD_RELOC_OFF6A;
++ }
++ s = expr_end;
++ continue;
++ /* 11 bits immediate used in lt,st (OP_*_IMMIDATE6b),
++ * in fact it is 14 bits, multiple of 8; */
++ case '@':
++ if (*s == '(' && strchr (s + 1, '(') == 0)
++ {
++ imm_expr.X_op = O_constant;
++ imm_expr.X_add_number = 0;
++ continue;
++ }
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if (imm_expr.X_add_number % 8 != 0)
++ as_bad (_("(%d) is not multiple of 8"),
++ (int) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 8192) & ~0x3FFF) != 0)
++ as_bad (_("(%d) is too large to fit in 14 bits"),
++ (int) imm_expr.X_add_number);
++ ip->insn_opcode |=
++ (((imm_expr.X_add_number >> 3) & OP_MASK_IMMIDATE6b) <<
++ OP_SH_IMMIDATE6b);
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++
++ /* 4 bits immediate from 0 to 8,used in MFA,MFA2,RNDA2 (OP_*_IMMIDATE74) */
++ case '#':
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if (imm_expr.X_add_number > 8 || imm_expr.X_add_number < 0)
++ as_bad (_("(%d) is out of range 0-8"),
++ (int) imm_expr.X_add_number);
++ ip->insn_opcode |=
++ ((imm_expr.X_add_number & OP_MASK_IMMIDATE74) <<
++ OP_SH_IMMIDATE74);
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++ /* 8 bits immediate ,used in lbp,stp,etc(OP_*_IMMIDATE88) */
++ case '~':
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if ((strncmp (str, "lbp", 3) == 0)
++ || (strncmp (str, "sbp", 3) == 0))
++ multipletype = 0;
++ else if ((strncmp (str, "lhp", 3) == 0)
++ || (strncmp (str, "shp", 3) == 0))
++ multipletype = 2;
++ else if ((strncmp (str, "lwp", 3) == 0)
++ || (strncmp (str, "swp", 3) == 0))
++ multipletype = 4;
++ else
++ multipletype = 8;
++
++ switch (multipletype)
++ {
++ case 0:
++ if (((imm_expr.X_add_number + 128) & ~0xff) != 0)
++ as_bad (_("(%d) is too large to fit in 8 bits"),
++ (int) imm_expr.X_add_number);
++ break;
++
++ case 2:
++ if ((imm_expr.X_add_number % 2) != 0)
++ as_bad (_("(%d) is not multiple of 2"),
++ (int) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 256) & ~0x1FF) != 0)
++ as_bad (_("(%d) is too large to fit in 8 bits"),
++ (int) imm_expr.X_add_number);
++ imm_expr.X_add_number = imm_expr.X_add_number >> 1;
++ break;
++
++ case 4:
++ if ((imm_expr.X_add_number % 4) != 0)
++ as_bad (_("(%d) is not multiple of 4"),
++ (int) imm_expr.X_add_number);
++
++ if (((imm_expr.X_add_number + 512) & ~0x3FF) != 0)
++ as_bad (_("(%d) is too large to fit in 8 bits"),
++ (int) imm_expr.X_add_number);
++ imm_expr.X_add_number = imm_expr.X_add_number >> 2;
++ break;
++
++ case 8:
++ if ((imm_expr.X_add_number % 8) != 0)
++ as_bad (_("(%d) is not multiple of 8"),
++ (int) imm_expr.X_add_number);
++
++ if (((imm_expr.X_add_number + 1024) & ~0x7FF) != 0)
++ as_bad (_("(%d) is too large to fit in 8 bits"),
++ (int) imm_expr.X_add_number);
++
++ imm_expr.X_add_number = imm_expr.X_add_number >> 3;
++ break;
++ }
++ ip->insn_opcode |=
++ ((imm_expr.
++ X_add_number & OP_MASK_IMMIDATE88) << OP_SH_IMMIDATE88);
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++
++ /* even register,used in lt,st,ltp,stp (OP_*_EVENREG) */
++ case '`':
++ if (s[0] == '$')
++ {
++ regno = 0;
++ if (ISDIGIT (s[1]))
++ {
++ ++s;
++ do
++ {
++ regno *= 10;
++ regno += *s - '0';
++ ++s;
++ }
++ while (ISDIGIT (*s));
++
++ }
++ else if ((s[1] == 'f') && (s[2] == 'p'))
++ {
++ regno = 30;
++ s += 3;
++ }
++ else if ((s[1] == 'a') && (s[2] == 't'))
++ {
++ regno = 1;
++ s += 3;
++ }
++ else
++ {
++ insn_error = "register needed!";
++ return;
++ }
++ }
++ else
++ {
++ insn_error = "register needed!";
++ return;
++ }
++
++ if (regno > 31)
++ as_bad (_("invalid register number (%d)"), regno);
++
++ if (regno % 2 != 0)
++ as_bad (_("not an even register number(%d) "), regno);
++
++ ip->insn_opcode |=
++ (regno & OP_MASK_EVENREG) << OP_SH_EVENREG;
++ continue;
++
++ case 'H':
++ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
++ s += 2;
++ if (ISDIGIT (*s))
++ {
++ c = 0;
++ do
++ {
++ c *= 10;
++ c += *s - '0';
++ ++s;
++ }
++ while (ISDIGIT (*s));
++ }
++ else
++ c = 64; /* Invalid sel or stype value. */
++
++ if (c > 63)
++ as_bad (_("invalid coprocessor sel value (0-63)"));
++
++ ip->insn_opcode |= (c & OP_MASK_RLX_SEL) << OP_SH_RLX_SEL;
++ continue;
++
++ case 'I':
++ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
++ s += 2;
++
++ if (ISDIGIT (*s))
++ {
++ c = 0;
++ do
++ {
++ c *= 10;
++ c += *s - '0';
++ ++s;
++ }
++ while (ISDIGIT (*s));
++ }
++ else
++ c = 64; /* Invalid sel value. */
++
++ if (c > 63)
++ as_bad (_("invalid coprocessor stype value (0-63)"));
++
++ ip->insn_opcode |=
++ (c & OP_MASK_RLX_STYPE) << OP_SH_RLX_STYPE;
++ continue;
++ }
++ break;
++
+ case 'b': /* base register */
+ case 'd': /* destination register */
+ case 's': /* source register */
+@@ -9467,8 +9934,32 @@ do_msbd:
+ ok = reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &regno);
+ if (regno == AT && mips_opts.at)
+ {
+- if (mips_opts.at == ATREG)
+- as_warn (_("used $at without \".set noat\""));
++ if (mips_opts.at == ATREG) {
++ if ((strncmp (ip->insn_mo->name, "mta2", 4) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "mfa", 3) != 0
++ || *args != 't')
++ && (strncmp (ip->insn_mo->name, "diva", 4) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "mtru", 4) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "mfru", 4) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "multa", 5) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "mulna2", 6) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "cmulta", 6) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "madda", 5) != 0
++ || *args != 'd')
++ && (strncmp (ip->insn_mo->name, "msuba", 5) != 0
++ || *args != 'd')
++ && strncmp (ip->insn_mo->name, "addma", 5) != 0
++ && strncmp (ip->insn_mo->name, "subma", 5) != 0
++ && strncmp (ip->insn_mo->name, "rnda2", 5) != 0)
++ as_warn (_("used $at without \".set noat\""));
++ }
+ else
+ as_warn (_("used $%u with \".set at=$%u\""),
+ regno, mips_opts.at);
+@@ -9511,11 +10002,53 @@ do_msbd:
+ {
+ case 'r':
+ case 's':
++ if (strncmp (ip->insn_mo->name, "addma", 5) == 0
++ || strncmp (ip->insn_mo->name, "subma", 5) == 0)
++ {
++ if ((regno & 3) == 0 || (regno & 3) == 3)
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++ }
+ case 'v':
+ case 'b':
+ INSERT_OPERAND (RS, *ip, regno);
+ break;
+ case 'd':
++ if (strncmp (ip->insn_mo->name, "addma", 5) == 0
++ || strncmp (ip->insn_mo->name, "subma", 5) == 0)
++ {
++ if (((regno & 3) == 0) || ((regno & 3) == 3))
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++ }
++
++ if (strncmp (ip->insn_mo->name, "diva", 4) == 0
++ || (strlen (ip->insn_mo->name) == 5
++ && strncmp (ip->insn_mo->name, "multa", 5) == 0)
++ || strncmp (ip->insn_mo->name, "multau", 6) == 0
++ || strncmp (ip->insn_mo->name, "cmulta", 6) == 0
++ || (strlen (ip->insn_mo->name) == 5
++ && strncmp (ip->insn_mo->name, "madda", 5) == 0)
++ || strncmp (ip->insn_mo->name, "maddau", 6) == 0
++ || (strlen (ip->insn_mo->name) == 5
++ && strncmp (ip->insn_mo->name, "msuba", 5) == 0)
++ || strncmp (ip->insn_mo->name, "msubau", 6) == 0)
++ {
++ if ((regno & 3) != 3)
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++ }
++
++ if (strncmp (ip->insn_mo->name, "multa2", 6) == 0
++ || strncmp (ip->insn_mo->name, "mulna2", 6) == 0
++ || strncmp (ip->insn_mo->name, "rnadda2", 6) == 0
++ || strncmp (ip->insn_mo->name, "msuba2", 6) == 0
++ || strncmp (ip->insn_mo->name, "mta2", 4) == 0)
++ {
++ if ((regno & 3) == 0)
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++ }
+ case 'G':
+ case 'K':
+ case 'g':
+@@ -9527,6 +10060,25 @@ do_msbd:
+ break;
+ case 'w':
+ case 't':
++ if (strncmp (ip->insn_mo->name, "addma", 5) == 0 ||
++ strncmp (ip->insn_mo->name, "subma", 5) == 0 ||
++ strncmp (ip->insn_mo->name, "mfa",
++ strlen (ip->insn_mo->name)) == 0)
++ {
++ if (((regno & 3) == 0) || ((regno & 3) == 3))
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++ }
++
++ if (strncmp (ip->insn_mo->name, "mfa2", 4) == 0)
++ if ((regno & 3) != 3)
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
++
++ if (strncmp (ip->insn_mo->name, "rnda2", 5) == 0)
++ if ((regno & 3) == 0)
++ as_bad (_("Illegal reg number (%d) in %s"), regno,
++ str);
+ case 'E':
+ INSERT_OPERAND (RT, *ip, regno);
+ break;
+@@ -11855,6 +12407,9 @@ mips_after_parse_args (void)
+ if (mips_arch_string != 0)
+ arch_info = mips_parse_cpu ("-march", mips_arch_string);
+
++ if (mips_tune_string != 0)
++ mips_set_architecture (mips_parse_cpu ("-mtune", mips_tune_string));
++
+ if (file_mips_isa != ISA_UNKNOWN)
+ {
+ /* Handle -mipsN. At this point, file_mips_isa contains the
+@@ -12422,6 +12977,40 @@ md_apply_fix (fixS *fixP, valueT *valP,
+ fixP->fx_done = 0;
+ break;
+
++ case BFD_RELOC_OFF6A:
++ if (fixP->fx_done)
++ {
++ valueT tmp_value;
++ valueT org_value;
++
++ buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
++ tmp_value =
++ *(valueT *) (fixP->fx_frag->fr_literal + fixP->fx_where);
++ org_value = *valP;
++
++ if (target_big_endian)
++ {
++ tmp_value =
++ (((tmp_value & 0xff) << 24) |
++ ((tmp_value & 0xff00) << 8) |
++ (((tmp_value & 0xff0000) >> 8)) |
++ (((tmp_value & 0xff000000) >> 24)));
++ }
++
++ if ((org_value % 8) != 0)
++ as_bad (_("(%d) is not multiple of 8"), (int) org_value);
++
++ if ((org_value & ~0x1FFF) != 0)
++ as_bad (_("(%d) is too large to stay in 13 bits"),
++ (int) org_value);
++
++ tmp_value |=
++ (((org_value >> 3) & OP_MASK_OFFSET6A) << OP_SH_OFFSET6A);
++ md_number_to_chars ((char *) buf, tmp_value, 4);
++ }
++ break;
++
++
+ default:
+ internalError ();
+ }
+@@ -15190,6 +15779,12 @@ static const struct mips_cpu_info mips_c
+ { "r3000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r2000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r3900", 0, ISA_MIPS1, CPU_R3900 },
++ {"lx4180", 0, ISA_MIPS1, CPU_LX4180},
++ {"rlx4181", 0, ISA_MIPS1, CPU_RLX4181},
++ {"rlx4281", 0, ISA_MIPS1, CPU_RLX4281},
++ {"rlx5181", 0, ISA_MIPS1, CPU_RLX5181},
++ {"lx5280", 0, ISA_MIPS1, CPU_LX5280},
++ {"rlx5281", 0, ISA_MIPS1, CPU_RLX5281},
+
+ /* MIPS II */
+ { "r6000", 0, ISA_MIPS2, CPU_R6000 },
+@@ -15353,14 +15948,28 @@ mips_matching_cpu_name_p (const char *ca
+
+ /* If not, try comparing based on numerical designation alone.
+ See if GIVEN is an unadorned number, or 'r' followed by a number. */
+- if (TOLOWER (*given) == 'r')
++
++ /* 2006-01-19 tonywu: add to parse LX/RLX CPUs */
++ if (TOLOWER (given[0]) == 'l' && TOLOWER (given[1]) == 'x')
++ given += 2;
++ else if (TOLOWER (given[0]) == 'r' &&
++ TOLOWER (given[1]) == 'l' && TOLOWER (given[2]) == 'x')
++ given += 3;
++ else if (TOLOWER (*given) == 'r')
+ given++;
++
+ if (!ISDIGIT (*given))
+ return FALSE;
+
+ /* Skip over some well-known prefixes in the canonical name,
+ hoping to find a number there too. */
+- if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
++ /* 2006-01-19 tonywu: add to parse LX/RLX CPUs */
++ if (TOLOWER (canonical[0]) == 'l' && TOLOWER (canonical[1]) == 'x')
++ canonical += 2;
++ else if (TOLOWER (canonical[0]) == 'r' &&
++ TOLOWER (canonical[1]) == 'l' && TOLOWER (canonical[2]) == 'x')
++ canonical += 3;
++ else if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
+ canonical += 2;
+ else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
+ canonical += 2;
+@@ -15624,3 +16233,83 @@ tc_mips_regname_to_dw2regnum (char *regn
+
+ return regnum;
+ }
++
++static inline int
++rlx_is_insn_lt (const struct mips_cl_insn *insn1,
++ const struct mips_cl_insn *insn2)
++{
++ int is_lt = 0;
++
++ if (insn1 == NULL || insn2 == NULL)
++ return 0;
++
++ if (strncmp (insn1->insn_mo->name, "lt", 2) == 0)
++ is_lt = 1;
++ else if (strncmp (insn1->insn_mo->name, "ltw", 3) == 0)
++ is_lt = 1;
++
++ if (is_lt == 0)
++ return 0;
++
++ int regno1 = EXTRACT_OPERAND (RT, *insn1);
++ int regno2 = regno1 + 1;
++
++ if (insn_uses_reg (insn2, regno1, MIPS_GR_REG) ||
++ insn_uses_reg (insn2, regno2, MIPS_GR_REG))
++ return 1;
++
++ return 0;
++}
++
++static inline int
++rlx_is_insn_st (const struct mips_cl_insn *insn1,
++ const struct mips_cl_insn *insn2)
++{
++ int is_st = 0;
++
++ if (insn1 == NULL || insn2 == NULL)
++ return 0;
++
++ if (strncmp (insn2->insn_mo->name, "st", 2) == 0)
++ is_st = 1;
++
++ if (is_st == 0)
++ return 0;
++
++ int regno1 = EXTRACT_OPERAND (RT, *insn1);
++ int regno2 = 0;
++
++ if (regno1 % 2 == 0)
++ regno2 = regno1 + 1;
++ else
++ regno2 = regno1 - 1;
++
++ if (insn_uses_reg (insn2, regno1, MIPS_GR_REG) ||
++ insn_uses_reg (insn2, regno2, MIPS_GR_REG))
++ return 1;
++
++ return 0;
++}
++
++/* 2006-01-05 tonywu: merged from 2.14 */
++static inline int
++rlx_nops_for_new_insn (const struct mips_cl_insn *pre,
++ const struct mips_cl_insn *now)
++{
++ if ((pre == NULL) || (now == NULL))
++ return 0;
++
++ if ((pre->insn_mo->match == 0 && pre->insn_mo->mask == 0xffffffff) ||
++ (now->insn_mo->match == 0 && now->insn_mo->mask == 0xffffffff))
++ return 0;
++
++ if (pre->insn_mo == &dummy_opcode || now->insn_mo == &dummy_opcode)
++ return 0;
++
++ if (strcmp (pre->insn_mo->name, "madda") == 0 &&
++ strcmp (now->insn_mo->name, "mfa") == 0 &&
++ EXTRACT_OPERAND (RD, *pre) == EXTRACT_OPERAND (RT, *now))
++ return 2;
++
++ return 0;
++}
+Index: binutils/bfd/elf32-mips.c
+===================================================================
+--- binutils.orig/bfd/elf32-mips.c
++++ binutils/bfd/elf32-mips.c
+@@ -717,6 +717,20 @@ static reloc_howto_type elf_mips_howto_t
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
++ /* relocation added by dbb */
++ HOWTO (R_RELOC_OFF6A, /* type */
++ 3, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 10, /* bitsize */
++ FALSE, /* pc_relative */
++ 6, /* bitpos */
++ complain_overflow_dont, /* complain_on_overflow */
++ NULL, /* special_function */
++ "R_RELOC_OFF6A", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000FFC0, /* src_mask */
++ 0x0000FFC0, /* dst_mask */
++ FALSE), /* pcrel_offset */
+ };
+
+ /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
+@@ -1274,7 +1288,8 @@ static const struct elf_reloc_map mips_r
+ { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
+ { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
+ { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
+- { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
++ { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
++ { BFD_RELOC_OFF6A, R_RELOC_OFF6A}
+ };
+
+ static const struct elf_reloc_map mips16_reloc_map[] =
+Index: binutils/bfd/elfxx-mips.c
+===================================================================
+--- binutils.orig/bfd/elfxx-mips.c
++++ binutils/bfd/elfxx-mips.c
+@@ -5361,6 +5361,12 @@ mips_elf_calculate_relocation (bfd *abfd
+ }
+ break;
+
++ case R_RELOC_OFF6A:
++ value = (symbol + ((addend >> 6) << 3));
++ if ((value % 8) != 0)
++ return bfd_reloc_notmultipleof8_ltw;
++ value = ((value >> 3) << 6) & howto->dst_mask;
++ break;
+ case R_MIPS_LITERAL:
+ /* Because we don't merge literal sections, we can handle this
+ just like R_MIPS_GPREL16. In the long run, we should merge
+@@ -9156,6 +9162,12 @@ _bfd_mips_elf_relocate_section (bfd *out
+ }
+ break;
+
++ case bfd_reloc_notmultipleof8_ltw:
++ msg = _("offset in ltw instruction is not multiple of 8");
++ info->callbacks->warning
++ (info, msg, name, input_bfd, input_section, rel->r_offset);
++ return FALSE;
++
+ case bfd_reloc_ok:
+ break;
+
+Index: binutils/bfd/libbfd.h
+===================================================================
+--- binutils.orig/bfd/libbfd.h
++++ binutils/bfd/libbfd.h
+@@ -2126,6 +2126,7 @@ static const char *const bfd_reloc_code_
+ "BFD_RELOC_MICROBLAZE_64_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_32_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_COPY",
++ "BFD_RELOC_OFF6A",
+ "@@overflow: BFD_RELOC_UNUSED@@",
+ };
+ #endif
+Index: binutils/bfd/reloc.c
+===================================================================
+--- binutils.orig/bfd/reloc.c
++++ binutils/bfd/reloc.c
+@@ -52,6 +52,7 @@ SECTION
+ #include "bfd.h"
+ #include "bfdlink.h"
+ #include "libbfd.h"
++#include "elf/mips.h"
+ /*
+ DOCDD
+ INODE
+@@ -1215,6 +1216,15 @@ space consuming. For each target:
+ }
+ */
+
++
++ switch (howto->type)
++ {
++ case R_RELOC_OFF6A:
++ if ((relocation % 8) != 0)
++ return bfd_reloc_notmultipleof8_ltw;
++ break;
++ }
++
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used. */
+Index: binutils/gas/write.c
+===================================================================
+--- binutils.orig/gas/write.c
++++ binutils/gas/write.c
+@@ -1133,6 +1133,9 @@ install_reloc (asection *sec, arelent *r
+ case bfd_reloc_outofrange:
+ as_bad_where (file, line, _("relocation out of range"));
+ break;
++ case bfd_reloc_notmultipleof8_ltw:
++ as_bad_where (file, line, _("offset in ltw instruction is not multiple of 8"));
++ break;
+ default:
+ as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
+ file, line, s);
+Index: binutils/include/elf/mips.h
+===================================================================
+--- binutils.orig/include/elf/mips.h
++++ binutils/include/elf/mips.h
+@@ -88,7 +88,8 @@ START_RELOC_NUMBERS (elf_mips_reloc_type
+ RELOC_NUMBER (R_MIPS_TLS_TPREL_HI16, 49)
+ RELOC_NUMBER (R_MIPS_TLS_TPREL_LO16, 50)
+ RELOC_NUMBER (R_MIPS_GLOB_DAT, 51)
+- FAKE_RELOC (R_MIPS_max, 52)
++ RELOC_NUMBER (R_RELOC_OFF6A, 52)
++ FAKE_RELOC (R_MIPS_max, 53)
+ /* These relocs are used for the mips16. */
+ FAKE_RELOC (R_MIPS16_min, 100)
+ RELOC_NUMBER (R_MIPS16_26, 100)