summaryrefslogtreecommitdiffstats
path: root/toolchain/binutils/patches/2.22
diff options
context:
space:
mode:
authorArtur Artamonov <freeartman@wechall.net>2013-10-05 21:50:08 +0300
committerArtur Artamonov <freeartman@wechall.net>2013-10-05 21:50:08 +0300
commit7493fdef815f96da8852bd1c7abccc9a33aa969e (patch)
tree7a907ce6d22d12a5dffd8fa473b7073e6067e3b9 /toolchain/binutils/patches/2.22
parentef827ecd68db25c4f3e99712b1df313bbc296952 (diff)
binutils: main ported code
Diffstat (limited to 'toolchain/binutils/patches/2.22')
-rw-r--r--toolchain/binutils/patches/2.22/999_realtek_2_22.patch2385
1 files changed, 2385 insertions, 0 deletions
diff --git a/toolchain/binutils/patches/2.22/999_realtek_2_22.patch b/toolchain/binutils/patches/2.22/999_realtek_2_22.patch
new file mode 100644
index 000000000..f8b3713d1
--- /dev/null
+++ b/toolchain/binutils/patches/2.22/999_realtek_2_22.patch
@@ -0,0 +1,2385 @@
+diff -rupN ./bu.orig/bfd/bfd-in2.h ./bu.new/bfd/bfd-in2.h
+--- a/bfd/bfd-in2.h 2011-09-16 04:15:18.000000000 +0300
++++ b/bfd/bfd-in2.h 2013-09-26 20:51:04.437639632 +0300
+@@ -1889,6 +1889,13 @@ enum bfd_architecture
+ #define bfd_mach_mipsisa64 64
+ #define bfd_mach_mipsisa64r2 65
+ #define bfd_mach_mips_micromips 96
++#define bfd_mach_mips_rlx4081 4081
++#define bfd_mach_mips_rlx4180 4180
++#define bfd_mach_mips_rlx4181 4181
++#define bfd_mach_mips_rlx4281 4281
++#define bfd_mach_mips_rlx5181 5181
++#define bfd_mach_mips_rlx5280 5280
++#define bfd_mach_mips_rlx5281 5281
+ bfd_arch_i386, /* Intel 386 */
+ #define bfd_mach_i386_intel_syntax (1 << 0)
+ #define bfd_mach_i386_i8086 (1 << 1)
+@@ -2239,7 +2246,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;
+
+@@ -2780,6 +2788,16 @@ to compensate for the borrow when the lo
+ /* MIPS16 low 16 bits. */
+ BFD_RELOC_MIPS16_LO16,
+
++/* MIPS16 TLS relocations */
++ BFD_RELOC_MIPS16_TLS_GD,
++ BFD_RELOC_MIPS16_TLS_LDM,
++ BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++ BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++ BFD_RELOC_MIPS16_TLS_GOTTPREL,
++ BFD_RELOC_MIPS16_TLS_TPREL_HI16,
++ BFD_RELOC_MIPS16_TLS_TPREL_LO16,
++ BFD_RELOC_RLX_OFF6A,
++
+ /* Relocation against a MIPS literal section. */
+ BFD_RELOC_MIPS_LITERAL,
+ BFD_RELOC_MICROMIPS_LITERAL,
+diff -rupN ./bu.orig/bfd/cpu-mips.c ./bu.new/bfd/cpu-mips.c
+--- a/bfd/cpu-mips.c 2011-07-24 17:20:05.000000000 +0300
++++ b/bfd/cpu-mips.c 2013-09-20 11:26:11.114532953 +0300
+@@ -94,7 +94,15 @@ enum
+ I_loongson_3a,
+ I_mipsocteon,
+ I_xlr,
+- I_micromips
++ I_micromips,
++ I_mipsrlx4081,
++ I_mipsrlx4180,
++ I_mipsrlx4181,
++ I_mipsrlx4281,
++ I_mipsrlx5181,
++ I_mipsrlx5280,
++ I_mipsrlx5281,
++
+ };
+
+ #define NN(index) (&arch_info_struct[(index) + 1])
+@@ -135,7 +143,14 @@ static const bfd_arch_info_type arch_inf
+ N (64, 64, bfd_mach_mips_loongson_3a, "mips:loongson_3a", FALSE, NN(I_loongson_3a)),
+ N (64, 64, bfd_mach_mips_octeon,"mips:octeon", FALSE, NN(I_mipsocteon)),
+ N (64, 64, bfd_mach_mips_xlr, "mips:xlr", FALSE, NN(I_xlr)),
+- N (64, 64, bfd_mach_mips_micromips,"mips:micromips",FALSE,0)
++ N (64, 64, bfd_mach_mips_micromips,"mips:micromips",FALSE,0),
++ N (32, 32, bfd_mach_mips_rlx4081,"mips:rlx4081",FALSE,NN(I_mipsrlx4081)),
++ N (32, 32, bfd_mach_mips_rlx4180,"mips:rlx4180",FALSE,NN(I_mipsrlx4180)),
++ N (32, 32, bfd_mach_mips_rlx4181,"mips:rlx4181",FALSE,NN(I_mipsrlx4181)),
++ N (32, 32, bfd_mach_mips_rlx4281,"mips:rlx4281",FALSE,NN(I_mipsrlx4281)),
++ N (32, 32, bfd_mach_mips_rlx5181,"mips:rlx5181",FALSE,NN(I_mipsrlx5181)),
++ N (32, 32, bfd_mach_mips_rlx5280,"mips:rlx5280",FALSE,NN(I_mipsrlx5280)),
++ N (32, 32, bfd_mach_mips_rlx5281,"mips:rlx5281",FALSE,NN(I_mipsrlx5281))
+ };
+
+ /* The default architecture is mips:3000, but with a machine number of
+diff -rupN ./bu.orig/bfd/elf32-mips.c ./bu.new/bfd/elf32-mips.c
+--- a/bfd/elf32-mips.c 2011-07-24 17:20:05.000000000 +0300
++++ b/bfd/elf32-mips.c 2013-09-26 19:52:44.694112357 +0300
+@@ -717,6 +717,21 @@ static reloc_howto_type elf_mips_howto_t
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
++
++ /* relocation added by dbb */
++ HOWTO (R_RELOC_RLX_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_RLX_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
+@@ -830,6 +845,112 @@ static reloc_howto_type elf_mips16_howto
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS general dynamic variable reference. */
++ HOWTO (R_MIPS16_TLS_GD, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_GD", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS local dynamic variable reference. */
++ HOWTO (R_MIPS16_TLS_LDM, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_LDM", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS local dynamic offset. */
++ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_DTPREL_HI16", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS local dynamic offset. */
++ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_DTPREL_LO16", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS thread pointer offset. */
++ HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_GOTTPREL", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS thread pointer offset. */
++ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_TPREL_HI16", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
++ /* MIPS16 TLS thread pointer offset. */
++ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
++ 0, /* rightshift */
++ 2, /* size (0 = byte, 1 = short, 2 = long) */
++ 16, /* bitsize */
++ FALSE, /* pc_relative */
++ 0, /* bitpos */
++ complain_overflow_signed, /* complain_on_overflow */
++ _bfd_mips_elf_generic_reloc, /* special_function */
++ "R_MIPS16_TLS_TPREL_LO16", /* name */
++ TRUE, /* partial_inplace */
++ 0x0000ffff, /* src_mask */
++ 0x0000ffff, /* dst_mask */
++ FALSE), /* pcrel_offset */
++
+ };
+
+ static reloc_howto_type elf_micromips_howto_table_rel[] =
+@@ -1785,7 +1906,9 @@ 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_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
++ { BFD_RELOC_RLX_OFF6A, R_RELOC_RLX_OFF6A },
+ };
+
+ static const struct elf_reloc_map mips16_reloc_map[] =
+@@ -1796,6 +1919,16 @@ static const struct elf_reloc_map mips16
+ { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++ R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++ R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
++ { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
++
+ };
+
+ static const struct elf_reloc_map micromips_reloc_map[] =
+diff -rupN ./bu.orig/bfd/libbfd.h ./bu.new/bfd/libbfd.h
+--- a/bfd/libbfd.h 2011-08-17 03:39:39.000000000 +0300
++++ b/bfd/libbfd.h 2013-09-26 20:01:45.170808974 +0300
+@@ -1086,6 +1086,14 @@ static const char *const bfd_reloc_code_
+ "BFD_RELOC_MIPS16_HI16",
+ "BFD_RELOC_MIPS16_HI16_S",
+ "BFD_RELOC_MIPS16_LO16",
++ "BFD_RELOC_MIPS16_TLS_GD",
++ "BFD_RELOC_MIPS16_TLS_LDM",
++ "BFD_RELOC_MIPS16_TLS_DTPREL_HI16",
++ "BFD_RELOC_MIPS16_TLS_DTPREL_LO16",
++ "BFD_RELOC_MIPS16_TLS_GOTTPREL",
++ "BFD_RELOC_MIPS16_TLS_TPREL_HI16",
++ "BFD_RELOC_MIPS16_TLS_TPREL_LO16",
++ "BFD_RELOC_RLX_OFF6A",
+ "BFD_RELOC_MIPS_LITERAL",
+ "BFD_RELOC_MICROMIPS_LITERAL",
+ "BFD_RELOC_MICROMIPS_7_PCREL_S1",
+diff -rupN ./bu.orig/bfd/reloc.c ./bu.new/bfd/reloc.c
+--- a/bfd/reloc.c 2011-07-24 17:20:06.000000000 +0300
++++ b/bfd/reloc.c 2013-09-26 20:54:56.957652516 +0300
+@@ -2246,6 +2246,24 @@ ENUM
+ ENUMDOC
+ MIPS16 low 16 bits.
+
++ ENUM
++ BFD_RELOC_MIPS16_TLS_GD
++ENUMX
++ BFD_RELOC_MIPS16_TLS_LDM
++ENUMX
++ BFD_RELOC_MIPS16_TLS_DTPREL_HI16
++ENUMX
++ BFD_RELOC_MIPS16_TLS_DTPREL_LO16
++ENUMX
++ BFD_RELOC_MIPS16_TLS_GOTTPREL
++ENUMX
++ BFD_RELOC_MIPS16_TLS_TPREL_HI16
++ENUMX
++ BFD_RELOC_MIPS16_TLS_TPREL_LO16
++ENUMDOC
++ MIPS16 TLS relocations
++
++
+ ENUM
+ BFD_RELOC_MIPS_LITERAL
+ ENUMX
+diff -rupN ./bu.orig/gas/config/tc-mips.c ./bu.new/gas/config/tc-mips.c
+--- a/gas/config/tc-mips.c 2011-11-21 11:29:32.000000000 +0200
++++ b/gas/config/tc-mips.c 2013-10-04 19:45:05.374380048 +0300
+@@ -104,6 +104,35 @@ static char *mips_regmask_frag;
+
+ #define ILLEGAL_REG (32)
+
++/* 2006-11-28 tonywu: add radiax alias name translation */
++#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
++/* 2006-11-28 tonywu: add radiax alias name translation */
++
++
+ #define AT mips_opts.at
+
+ /* Allow override of standard little-endian ECOFF format. */
+@@ -299,6 +328,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. */
+@@ -362,6 +393,10 @@ static int file_ase_dspr2;
+ #define ISA_SUPPORTS_DSPR2_ASE (mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS64R2)
+
++/* True if ISA supports RLX */
++#define ISA_IS_RLX ((mips_opts.isa & INSN_RLX_MASK) != 0)
++
++
+ /* True if -mmt was passed or implied by arguments passed on the
+ command line (e.g., by -march). */
+ static int file_ase_mt;
+@@ -521,6 +556,7 @@ static int mips_32bitmode = 0;
+ || mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS64 \
+ || mips_opts.isa == ISA_MIPS64R2 \
++ || ISA_IS_RLX \
+ || mips_opts.arch == CPU_R4010 \
+ || mips_opts.arch == CPU_R10000 \
+ || mips_opts.arch == CPU_R12000 \
+@@ -531,16 +567,27 @@ static int mips_32bitmode = 0;
+ || mips_opts.micromips \
+ )
+
++/* Whether the processor support dual-issue. */
++#define dual_issue \
++ (mips_opts.arch == CPU_RLX4281 \
++ || mips_opts.arch == CPU_RLX5280 \
++ || mips_opts.arch == CPU_RLX5281 \
++ )
++
+ /* Whether the processor uses hardware interlocks to protect reads
+ from the GPRs after they are loaded from memory, and thus does not
+ require nops to be inserted. This applies to instructions marked
+ INSN_LOAD_MEMORY_DELAY. These nops are only required at MIPS ISA
+ level I and microMIPS mode instructions are always interlocked. */
+-#define gpr_interlocks \
+- (mips_opts.isa != ISA_MIPS1 \
+- || mips_opts.arch == CPU_R3900 \
+- || mips_opts.micromips \
+- )
++#define gpr_interlocks \
++ ((mips_opts.isa != ISA_MIPS1 \
++ && (!ISA_IS_RLX \
++ || mips_opts.arch == CPU_RLX4281 \
++ || mips_opts.arch == CPU_RLX5280 \
++ || mips_opts.arch == CPU_RLX5281)) \
++ || mips_opts.arch == CPU_R3900 \
++ || mips_opts.micromips \
++ )
+
+ /* Whether the processor uses hardware interlocks to avoid delays
+ required by coprocessor instructions, and thus does not require
+@@ -553,6 +600,13 @@ static int mips_32bitmode = 0;
+ /* Itbl support may require additional care here. */
+ #define cop_interlocks \
+ ((mips_opts.isa != ISA_MIPS1 \
++ && (!ISA_IS_RLX \
++ || mips_opts.arch == CPU_RLX4180 \
++ || mips_opts.arch == CPU_RLX4181 \
++ || mips_opts.arch == CPU_RLX4281 \
++ || mips_opts.arch == CPU_RLX5181 \
++ || mips_opts.arch == CPU_RLX5280 \
++ || mips_opts.arch == CPU_RLX5281) \
+ && mips_opts.isa != ISA_MIPS2 \
+ && mips_opts.isa != ISA_MIPS3) \
+ || mips_opts.arch == CPU_R4300 \
+@@ -601,6 +655,16 @@ static int mips_big_got = 0;
+ instructions. */
+ static int mips_trap = 0;
+
++/* 1 if we should avoid put load in branch delay slot */
++static int fix_bdsl = 1;
++
++/* 1 if we want to warn for possible load-use in branch & jump delay slot */
++static int warn_possible_load_use = 0;
++
++/* 1 if we want to warn for missing delay slot at the end of noreorder section */
++static int warn_missing_delay_slot = 0;
++
++
+ /* 1 if double width floating point constants should not be constructed
+ by assembling two single width halves into two single width floating
+ point registers which just happen to alias the double width destination
+@@ -1352,6 +1416,8 @@ static void s_cprestore (int);
+ static void s_cpreturn (int);
+ static void s_dtprelword (int);
+ static void s_dtpreldword (int);
++static void s_tprelword (int);
++static void s_tpreldword (int);
+ static void s_gpvalue (int);
+ static void s_gpword (int);
+ static void s_gpdword (int);
+@@ -1373,6 +1439,14 @@ static int validate_mips_insn (const str
+ static int validate_micromips_insn (const struct mips_opcode *);
+ static int relaxed_micromips_16bit_branch_length (fragS *, asection *, int);
+ static int relaxed_micromips_32bit_branch_length (fragS *, asection *, int);
++static inline int rlx_nops_for_new_insn(const struct mips_cl_insn *, const struct mips_cl_insn *);
++static inline int rlx_is_tword_use(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 *);
++
++/* raise warning for load-use case (for processors without gpr-interlocks). */
++static void rlx_warn_load_use (struct mips_cl_insn *, struct mips_cl_insn *, char *, int);
++/* raise warning for bdsl at noreorder section (for bug of taroko < 1.3) */
++static void rlx_warn_bdsl (const struct mips_cl_insn *);
+
+ /* Table and functions used to map between CPU/ISA names, and
+ ISA levels, and CPU numbers. */
+@@ -1436,6 +1510,8 @@ static const pseudo_typeS mips_pseudo_ta
+ {"gpdword", s_gpdword, 0},
+ {"cpadd", s_cpadd, 0},
+ {"insn", s_insn, 0},
++ {"tprelword", s_tprelword, 0},
++ {"tpreldword", s_tpreldword, 0},
+
+ /* Relatively generic pseudo-ops that happen to be used on MIPS
+ chips. */
+@@ -1836,7 +1912,8 @@ struct regname {
+ unsigned int num;
+ };
+
+-#define RTYPE_MASK 0x1ff00
++//#define RTYPE_MASK 0x1ff00
++#define RTYPE_MASK 0x5ff00
+ #define RTYPE_NUM 0x00100
+ #define RTYPE_FPU 0x00200
+ #define RTYPE_FCC 0x00400
+@@ -1848,6 +1925,7 @@ struct regname {
+ #define RTYPE_CCC 0x10000
+ #define RNUM_MASK 0x000ff
+ #define RWARN 0x80000
++#define RTYPE_RAD 0x40000
+
+ #define GENERIC_REGISTER_NUMBERS \
+ {"$0", RTYPE_NUM | 0}, \
+@@ -2039,8 +2117,37 @@ struct regname {
+ {"$ac2", RTYPE_ACC | 2}, \
+ {"$ac3", RTYPE_ACC | 3}
+
++#define RLX_RADIAX_REGISTER_NAMES \
++ {"$m0l", RTYPE_RAD | 1}, \
++ {"$m0h", RTYPE_RAD | 2}, \
++ {"$m0", RTYPE_RAD | 3}, \
++ {"$m1l", RTYPE_RAD | 5}, \
++ {"$m1h", RTYPE_RAD | 6}, \
++ {"$m1", RTYPE_RAD | 7}, \
++ {"$m2l", RTYPE_RAD | 9}, \
++ {"$m2h", RTYPE_RAD | 10}, \
++ {"$m2", RTYPE_RAD | 11}, \
++ {"$m3l", RTYPE_RAD | 13}, \
++ {"$m3h", RTYPE_RAD | 14}, \
++ {"$m3", RTYPE_RAD | 15}, \
++ {"$estatus", RTYPE_RAD | 0}, \
++ {"$ecause", RTYPE_RAD | 1}, \
++ {"$intvec", RTYPE_RAD | 2}, \
++ {"$cbs0", RTYPE_RAD | 0}, \
++ {"$cbs1", RTYPE_RAD | 1}, \
++ {"$cbs2", RTYPE_RAD | 2}, \
++ {"$cbe0", RTYPE_RAD | 4}, \
++ {"$cbe1", RTYPE_RAD | 5}, \
++ {"$cbe2", RTYPE_RAD | 6}, \
++ {"$lps0", RTYPE_RAD | 16}, \
++ {"$lpe0", RTYPE_RAD | 17}, \
++ {"$lpc0", RTYPE_RAD | 18}, \
++ {"$mmd", RTYPE_RAD | 24}
++
++
+ static const struct regname reg_names[] = {
+ GENERIC_REGISTER_NUMBERS,
++ RLX_RADIAX_REGISTER_NAMES,
+ FPU_REGISTER_NAMES,
+ FPU_CONDITION_CODE_NAMES,
+ COPROC_CONDITION_CODE_NAMES,
+@@ -2727,6 +2834,67 @@ fixup_has_matching_lo_p (fixS *fixp)
+ && fixp->fx_offset == fixp->fx_next->fx_offset);
+ }
+
++static void
++rlx_warn_load_use (struct mips_cl_insn *insn1,
++ struct mips_cl_insn *insn2,
++ char *file, int line)
++{
++ unsigned long prev_pinfo, pinfo;
++ unsigned int wrt, rd;
++ const unsigned read_mask[2] = { INSN_READ_RAD_T, INSN_READ_RAD_S };
++ int i;
++
++
++ prev_pinfo = insn1->insn_mo->pinfo;
++ pinfo = insn2->insn_mo->pinfo;
++
++ if (gpr_interlocks || mips_opts.mips16
++ || !mips_opts.noreorder
++ || !(prev_pinfo & INSN_LOAD_MEMORY_DELAY))
++ return;
++
++ know (prev_pinfo & INSN_WRITE_GPR_T);
++ wrt = EXTRACT_OPERAND (mips_opts.micromips, RT, *insn1);
++
++ /* check RT & RS */
++ for (i = 0; i < 2; ++i) {
++ if ((pinfo & read_mask[i]) == 0) continue;
++
++ if (i == 0)
++ rd = EXTRACT_OPERAND(mips_opts.micromips, RT, *insn2);
++ else
++ rd = EXTRACT_OPERAND(mips_opts.micromips, RS, *insn2);
++
++ if (wrt == rd) {
++ as_warn_where (file, line, "LOAD-USE: regno=%d", wrt);
++ /* tword load & tword use instructions */
++ if ((insn1->insn_mo->pinfo2 & INSN2_TWORD_LOAD)
++ && (insn2->insn_mo->pinfo2 & INSN2_TWORD_USE))
++ as_warn_where (file, line, "LOAD-USE: regno=%d", wrt + 1);
++ }
++ /* tword load & use, check WR_t + 1 */
++ else if ((insn1->insn_mo->pinfo2 & INSN2_TWORD_LOAD) && (wrt + 1 == rd))
++ as_warn_where (file, line, "LOAD-USE: regno=%d", rd);
++ /* load & tword use, check RD_t + 1 */
++ else if ((insn2->insn_mo->pinfo2 & INSN2_TWORD_USE) && (wrt == rd + 1))
++ as_warn_where (file, line, "LOAD-USE: regno=%d", wrt);
++ }
++}
++/* 2010-08-06 tonywu: redo load-delay slot check */
++
++static void
++rlx_check_noreorder_insns (struct mips_cl_insn *ip)
++{
++ char *file;
++ unsigned line;
++ /* get current file & line */
++ as_where(&file, &line);
++ if (fix_bdsl)
++ rlx_warn_bdsl (ip);
++ rlx_warn_load_use (history, ip, file, line);
++}
++
++
+ /* This function returns true if modifying a register requires a
+ delay. */
+
+@@ -2992,9 +3160,9 @@ gpr_read_mask (const struct mips_cl_insn
+ {
+ if (pinfo2 & INSN2_READ_GPR_D)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
+- if (pinfo & INSN_READ_GPR_T)
++ if (pinfo & INSN_READ_RAD_T)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
+- if (pinfo & INSN_READ_GPR_S)
++ if (pinfo & INSN_READ_RAD_S)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
+ if (pinfo2 & INSN2_READ_GP)
+ mask |= 1 << GP;
+@@ -3057,9 +3225,9 @@ gpr_write_mask (const struct mips_cl_ins
+ }
+ else
+ {
+- if (pinfo & INSN_WRITE_GPR_D)
++ if (pinfo & INSN_WRITE_RAD_D)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
+- if (pinfo & INSN_WRITE_GPR_T)
++ if (pinfo & INSN_WRITE_RAD_T)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
+ if (pinfo & INSN_WRITE_GPR_S)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
+@@ -3251,6 +3419,11 @@ insns_between (const struct mips_cl_insn
+ || (!cop_interlocks && (pinfo1 & INSN_LOAD_COPROC_DELAY)))
+ {
+ know (pinfo1 & INSN_WRITE_GPR_T);
++ /* 2006-10-16 tonywu: fix lt nop bug */
++ if (ISA_IS_RLX && rlx_is_tword_use(insn1, insn2))
++ return 1;
++ /* 2006-10-16 tonywu: fix lt nop bug */
++
+ if (INSN2_USES_GPR (EXTRACT_OPERAND (0, RT, *insn1)))
+ return 1;
+ }
+@@ -3303,8 +3476,10 @@ insns_between (const struct mips_cl_insn
+ }
+
+ #undef INSN2_USES_GPR
+-
+- return 0;
++ if (ISA_IS_RLX)
++ return rlx_nops_for_new_insn(insn1, insn2);
++ else
++ return 0;
+ }
+
+ /* Return the number of nops that would be needed to work around the
+@@ -3576,6 +3751,186 @@ nops_for_insn (int ignore, const struct
+ return nops;
+ }
+
++static int
++rlx_check_regnum(char **ps)
++{
++ int regno;
++ char *s;
++
++ s = *ps;
++
++ regno = 32;
++ if (s[0] == '$')
++ {
++ if (ISDIGIT (s[1]))
++ {
++ regno = 0;
++ ++s;
++ do {
++ regno *= 10;
++ regno += *s - '0';
++ ++s;
++ }
++ while (ISDIGIT (*s));
++
++ /* 2006-11-28 tonywu: add radiax alias name */
++ }
++ else
++ {
++ if (s[1] == 'm' && s[2] == '0' && s[3] == 'l')
++ {
++ s += 4;
++ regno = M0L;
++ }
++ else if (s[1] == 'm' && s[2] == '0' && s[3] == 'h')
++ {
++ s += 4;
++ regno = M0H;
++ }
++ else if (s[1] == 'm' && s[2] == '0')
++ {
++ s += 3;
++ regno = M0;
++ }
++ else if (s[1] == 'm' && s[2] == '1' && s[3] == 'l')
++ {
++ s += 4;
++ regno = M1L;
++ }
++ else if (s[1] == 'm' && s[2] == '1' && s[3] == 'h')
++ {
++ s += 4;
++ regno = M1H;
++ }
++ else if (s[1] == 'm' && s[2] == '1')
++ {
++ s += 3;
++ regno = M1;
++ }
++ else if (s[1] == 'm' && s[2] == '2' && s[3] == 'l')
++ {
++ s += 4;
++ regno = M2L;
++ }
++ else if (s[1] == 'm' && s[2] == '2' && s[3] == 'h')
++ {
++ s += 4;
++ regno = M2H;
++ }
++ else if (s[1] == 'm' && s[2] == '2')
++ {
++ s += 3;
++ regno = M2;
++ }
++ else if (s[1] == 'm' && s[2] == '3' && s[3] == 'l')
++ {
++ s += 4;
++ regno = M3L;
++ }
++ else if (s[1] == 'm' && s[2] == '3' && s[3] == 'h')
++ {
++ s += 4;
++ regno = M3H;
++ }
++ else if (s[1] == 'm' && s[2] == '3')
++ {
++ s += 3;
++ regno = M3;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 's' && s[4] == '0')
++ {
++ s += 5;
++ regno = CBS0;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 's' && s[4] == '1')
++ {
++ s += 5;
++ regno = CBS1;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 's' && s[4] == '2')
++ {
++ s += 5;
++ regno = CBS2;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 'e' && s[4] == '0')
++ {
++ s += 5;
++ regno = CBE0;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 'e' && s[4] == '1')
++ {
++ s += 5;
++ regno = CBE1;
++ }
++ else if (s[1] == 'c' && s[2] == 'b' && s[3] == 'e' && s[4] == '2')
++ {
++ s += 5;
++ regno = CBE2;
++ }
++ else if (s[1] == 'l' && s[2] == 'p' && s[3] == 's' && s[4] == '0')
++ {
++ s += 5;
++ regno = LPS0;
++ }
++ else if (s[1] == 'l' && s[2] == 'p' && s[3] == 'e' && s[4] == '0')
++ {
++ s += 5;
++ regno = LPE0;
++ }
++ else if (s[1] == 'l' && s[2] == 'p' && s[3] == 'c' && s[4] == '0')
++ {
++ s += 5;
++ regno = LPC0;
++ }
++ else if (s[1] == 'm' && s[2] == 'm' && s[3] == 'd')
++ {
++ s += 4;
++ regno = MMD;
++ }
++ else if (s[1] == 'e' && s[2] == 's' && s[3] == 't' && s[4] == 'a' &&
++ s[5] == 't' && s[6] == 'u' && s[7] == 's')
++ {
++ s += 8;
++ regno = ESTATUS;
++ }
++ else if (s[1] == 'e' && s[2] == 'c' && s[3] == 'a' &&
++ s[4] == 'u' && s[5] == 's' && s[6] == 'e')
++ {
++ s += 7;
++ regno = ECAUSE;
++ }
++ else if (s[1] == 'i' && s[2] == 'n' && s[3] == 't' &&
++ s[4] == 'v' && s[5] == 'e' && s[6] == 'c')
++ {
++ s += 7;
++ regno = INTVEC;
++ }
++ }
++ }
++
++ *ps = s;
++ return regno;
++}
++
++/* 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)
++{
++ int swappable = 1;
++
++ if (rlx_is_tword_use(history,insn))
++ swappable = 0;
++
++ if (fix_bdsl == 1
++ && ((history->insn_mo->pinfo & INSN_LOAD_MEMORY_DELAY) != 0
++ || mips_opts.mips16))
++ swappable = 0;
++
++ return swappable;
++}
++
++
+ /* The variable arguments provide NUM_INSNS extra instructions that
+ might be added to HIST. Return the largest number of nops that
+ would be needed after the extended sequence, ignoring hazards
+@@ -3753,6 +4108,9 @@ can_swap_branch_p (struct mips_cl_insn *
+ target of the branch. */
+ if (nops_for_sequence (2, 0, history + 1, ip, history) > 0)
+ return FALSE;
++
++ if (ISA_IS_RLX && ! rlx_is_insn_swappable(history, ip) )
++ return FALSE;
+
+ /* If the branch reads a register that the previous
+ instruction sets, we can not swap. */
+@@ -4809,7 +5167,7 @@ macro_build (expressionS *ep, const char
+ warning later on. */
+ if (strcmp (fmt, amo->args) == 0
+ && amo->pinfo != INSN_MACRO
+- && is_opcode_valid (amo)
++ // && is_opcode_valid (amo)
+ && is_size_valid (amo))
+ {
+ if (is_delay_slot_valid (amo))
+@@ -5105,6 +5463,8 @@ mips16_macro_build (expressionS *ep, con
+ bfd_reloc_code_real_type r[3]
+ = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
+
++ //mips16_ext = FALSE;
++
+ mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);
+ gas_assert (mo);
+ gas_assert (strcmp (name, mo->name) == 0);
+@@ -8764,7 +9124,7 @@ macro (struct mips_cl_insn *ip)
+ s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
+ if (strcmp (s, ".lit8") == 0)
+ {
+- if (mips_opts.isa != ISA_MIPS1 || mips_opts.micromips)
++ if ((mips_opts.isa != ISA_MIPS1 && !ISA_IS_RLX) || mips_opts.micromips)
+ {
+ macro_build (&offset_expr, "ldc1", "T,o(b)", treg,
+ BFD_RELOC_MIPS_LITERAL, mips_gp_register);
+@@ -8787,7 +9147,7 @@ macro (struct mips_cl_insn *ip)
+ macro_build_lui (&offset_expr, AT);
+ }
+
+- if (mips_opts.isa != ISA_MIPS1 || mips_opts.micromips)
++ if ((mips_opts.isa != ISA_MIPS1 && !ISA_IS_RLX) || mips_opts.micromips)
+ {
+ macro_build (&offset_expr, "ldc1", "T,o(b)",
+ treg, BFD_RELOC_LO16, AT);
+@@ -8804,8 +9164,8 @@ macro (struct mips_cl_insn *ip)
+ r = BFD_RELOC_LO16;
+ dob:
+ gas_assert (!mips_opts.micromips);
+- gas_assert (mips_opts.isa == ISA_MIPS1);
+- macro_build (&offset_expr, "lwc1", "T,o(b)",
++ gas_assert (mips_opts.isa == ISA_MIPS1|| ISA_IS_RLX);
++ macro_build (&offset_expr, "if (mips_opts.isa != ISA_MIPS1)lwc1", "T,o(b)",
+ target_big_endian ? treg + 1 : treg, r, breg);
+ /* FIXME: A possible overflow which I don't know how to deal
+ with. */
+@@ -8816,7 +9176,7 @@ macro (struct mips_cl_insn *ip)
+
+ case M_S_DOB:
+ gas_assert (!mips_opts.micromips);
+- gas_assert (mips_opts.isa == ISA_MIPS1);
++ gas_assert (mips_opts.isa == ISA_MIPS1 || ISA_IS_RLX);
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when storing to memory. */
+ macro_build (&offset_expr, "swc1", "T,o(b)",
+@@ -8842,7 +9202,7 @@ macro (struct mips_cl_insn *ip)
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ fmt = "T,o(b)";
+- if (mips_opts.isa != ISA_MIPS1)
++ if (mips_opts.isa != ISA_MIPS1 && ! ISA_IS_RLX)
+ {
+ s = "ldc1";
+ goto ld_st;
+@@ -8855,7 +9215,7 @@ macro (struct mips_cl_insn *ip)
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ fmt = "T,o(b)";
+- if (mips_opts.isa != ISA_MIPS1)
++ if (mips_opts.isa != ISA_MIPS1 && ! ISA_IS_RLX)
+ {
+ s = "sdc1";
+ goto ld_st;
+@@ -9731,7 +10091,7 @@ macro (struct mips_cl_insn *ip)
+ case M_TRUNCWS:
+ case M_TRUNCWD:
+ gas_assert (!mips_opts.micromips);
+- gas_assert (mips_opts.isa == ISA_MIPS1);
++ gas_assert (mips_opts.isa == ISA_MIPS1 || ISA_IS_RLX);
+ used_at = 1;
+ sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
+ dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
+@@ -10299,6 +10659,39 @@ validate_mips_insn (const struct mips_op
+ case '\\': USE_BITS (OP_MASK_3BITPOS, OP_SH_3BITPOS); break;
+ case '~': USE_BITS (OP_MASK_OFFSET12, OP_SH_OFFSET12); break;
+ case 'g': USE_BITS (OP_MASK_RD, OP_SH_RD); 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 */
++ /* DVR taro: modified for supporting audio engine instructions */
++ case '$': USE_BITS (OP_MASK_IMMIDATEa6, OP_SH_IMMIDATEa6); break;
++ /* DVR taro: modified for supporting audio engine instructions */
++ /* DVR jacky: modified for supporting video engine instructions */
++ case '&': USE_BITS (OP_MASK_IMMIDATE6A, OP_SH_IMMIDATE6A); break;
++ case '=': USE_BITS (OP_MASK_IMMIDATE8A, OP_SH_IMMIDATE8A); break;
++ /* DVR jacky: modified for supporting video engine instructions */
++ /* 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 operand type `#%c'): %s %s"),
++ c, opc->name, opc->args);
++ return 0;
++ }
++ break;
+ default:
+ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
+ c, opc->name, opc->args);
+@@ -10583,6 +10976,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;
+@@ -10598,6 +10992,7 @@ mips_ip (char *str, struct mips_cl_insn
+ unsigned int rtype;
+ char *dot;
+ long end;
++ int multipletype;
+
+ insn_error = NULL;
+
+@@ -13160,12 +13555,13 @@ mips16_ip (char *str, struct mips_cl_ins
+ unsigned int lastregno = 0;
+ char *s_reset;
+ size_t i;
++ int multipletype;
+
+ insn_error = NULL;
+
+ forced_insn_length = 0;
+
+- for (s = str; ISLOWER (*s); ++s)
++ for (s = str; ISLOWER (*s) || *s == '0' ; ++s)
+ ;
+ switch (*s)
+ {
+@@ -13250,6 +13646,7 @@ mips16_ip (char *str, struct mips_cl_ins
+ for (args = insn->args; 1; ++args)
+ {
+ int c;
++ int t;
+
+ if (*s == ' ')
+ ++s;
+@@ -13811,8 +14208,355 @@ mips16_ip (char *str, struct mips_cl_ins
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+-
+- default:
++ /* dbb: modified for supporting radiax instructions */
++ case '#':
++ switch (*++args)
++ {
++ case 'd':
++ case 's':
++ case 't':
++ s_reset = s;
++ regno = rlx_check_regnum(&s);
++
++ c = *args;
++ t = *++args;
++
++ 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 (mips_opts.micromips,RD, *ip, regno); break;
++ case 's': INSERT_OPERAND (mips_opts.micromips,RS, *ip, regno); break;
++ case 't': INSERT_OPERAND (mips_opts.micromips,RT, *ip, regno); break;
++ }
++
++ lastregno = regno;
++ continue;
++
++ case 'u':
++ case 'k':
++ s_reset = s;
++ regno = rlx_check_regnum(&s);
++
++ /* 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 (_("RADIAX: illegal register (%d) in %s"), regno, str);
++
++ switch (c)
++ {
++ case 'u': INSERT_OPERAND (mips_opts.micromips,RD, *ip, regno); break;
++ case 'k': INSERT_OPERAND (mips_opts.micromips,RD, *ip, regno); break;
++ }
++
++ lastregno = regno;
++ continue;
++
++ /* DVR taro: modified for supporting audio engine instructions */
++ case '$': /* 6 bits immediate from 0 to 32,used in AE (OP_*_IMMIDATEa6) */
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if (imm_expr.X_add_number > 32 || imm_expr.X_add_number < 0)
++ as_bad (_("(%lu) is out of range 0-32"),
++ (unsigned long) imm_expr.X_add_number);
++
++ ip->insn_opcode |= ( (imm_expr.X_add_number & OP_MASK_IMMIDATEa6)
++ << OP_SH_IMMIDATEa6);
++
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++
++ /* DVR taro: modified for supporting audio engine instructions */
++ /* DVR jacky: modified for supporting video engine instructions */
++ case '&': /* 10 bits immediate from 0 to 32, used in VE (OP_*_IMMIDATE6A) */
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if ((imm_expr.X_add_number & ~0x3FF) != 0)
++ as_bad (_("Number (0x%lx) larger than 10 bits"),
++ (unsigned long) imm_expr.X_add_number);
++
++ ip->insn_opcode |= ((imm_expr.X_add_number & OP_MASK_IMMIDATE6A)
++ << OP_SH_IMMIDATE6A);
++
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++ /* DVR jacky: modified for supporting video engine instructions */
++
++ /* 2007-10-05 tonywu: add for IMMEDIATE8A */
++ case '=':
++ my_getExpression (&imm_expr, s);
++ check_absolute_expr (ip, &imm_expr);
++ if ((imm_expr.X_add_number & ~0xFF) != 0)
++ as_bad (_("Number (0x%lx) larger than 8 bits"),
++ (unsigned long) imm_expr.X_add_number);
++
++ ip->insn_opcode |= ((imm_expr.X_add_number & OP_MASK_IMMIDATE8A)
++ << OP_SH_IMMIDATE8A);
++
++ imm_expr.X_op = O_absent;
++ s = expr_end;
++ continue;
++ /* 2007-10-05 tonywu: add for IMMEDIATE8A */
++
++ 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 (_("(%lu) is not multiple of 8"),
++ (unsigned long) imm_expr.X_add_number);
++
++ if (((imm_expr.X_add_number + 4096) & ~0x1FFF) != 0)
++ as_bad (_("Number (0x%lx) larger than 13 bits"),
++ (unsigned long) 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_RLX_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 (_("Number (0x%lx) larger than 14 bits"),
++ (unsigned long) 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 (_("Number (0x%lx) larger than 8 bits"),
++ (unsigned long) imm_expr.X_add_number);
++ break;
++ case 2:
++ if ((imm_expr.X_add_number % 2) != 0)
++ as_bad (_("(%lu) is not multiple of 2"),
++ (unsigned long) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 256) & ~0x1FF) != 0)
++ as_bad (_("Number (0x%lx) larger than 8 bits"),
++ (unsigned long) 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 (_("(%lu) is not multiple of 4"),
++ (unsigned long) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 512) & ~0x3FF) != 0)
++ as_bad (_("Number (0x%lx) larger than 8 bits"),
++ (unsigned long) 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 (_("(%lu) is not multiple of 8"),
++ (unsigned long) imm_expr.X_add_number);
++ if (((imm_expr.X_add_number + 1024) & ~0x7FF) != 0)
++ as_bad (_("Number (0x%lx) larger than 8 bits"),
++ (unsigned long) 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 or stype 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;
++ /* dbb: radiax instructions support */
++ /* 2006-01-04 tonywu: merged from 2.14 to 2.16 */
++ default:
+ internalError ();
+ }
+ break;
+@@ -13930,6 +14674,9 @@ mips16_immed (char *file, unsigned int l
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
++ /* force extend `b 0x3ff' */
++ if (fix_bdsl && type == 'q')
++ --maxtiny;
+ }
+
+ /* Branch offsets have an implicit 0 in the lowest bit. */
+@@ -14040,7 +14787,14 @@ static const struct percent_op_match mip
+ {"%gprel", BFD_RELOC_MIPS16_GPREL},
+ {"%got", BFD_RELOC_MIPS16_GOT16},
+ {"%call16", BFD_RELOC_MIPS16_CALL16},
+- {"%hi", BFD_RELOC_MIPS16_HI16_S}
++ {"%hi", BFD_RELOC_MIPS16_HI16_S},
++ {"%tlsgd", BFD_RELOC_MIPS16_TLS_GD},
++ {"%tlsldm", BFD_RELOC_MIPS16_TLS_LDM},
++ {"%dtprel_hi", BFD_RELOC_MIPS16_TLS_DTPREL_HI16},
++ {"%dtprel_lo", BFD_RELOC_MIPS16_TLS_DTPREL_LO16},
++ {"%tprel_hi", BFD_RELOC_MIPS16_TLS_TPREL_HI16},
++ {"%tprel_lo", BFD_RELOC_MIPS16_TLS_TPREL_LO16},
++ {"%gottprel", BFD_RELOC_MIPS16_TLS_GOTTPREL}
+ };
+
+
+@@ -14209,6 +14963,7 @@ enum options
+ OPTION_MIPS64,
+ OPTION_MIPS32R2,
+ OPTION_MIPS64R2,
++ OPTION_MCE,
+ OPTION_MIPS16,
+ OPTION_NO_MIPS16,
+ OPTION_MIPS3D,
+@@ -14285,6 +15040,9 @@ enum options
+ OPTION_NO_PDR,
+ OPTION_MVXWORKS_PIC,
+ #endif /* OBJ_ELF */
++ OPTION_FIX_BDSL,
++ OPTION_WARN_POSSIBLE_LOAD_USE,
++ OPTION_WARN_MISSING_DELAY_SLOT,
+ OPTION_END_OF_ENUM
+ };
+
+@@ -14303,6 +15061,7 @@ struct option md_longopts[] =
+ {"mips64", no_argument, NULL, OPTION_MIPS64},
+ {"mips32r2", no_argument, NULL, OPTION_MIPS32R2},
+ {"mips64r2", no_argument, NULL, OPTION_MIPS64R2},
++ {"mips64r2", no_argument, NULL, OPTION_MIPS64R2},
+
+ /* Options which specify Application Specific Extensions (ASEs). */
+ {"mips16", no_argument, NULL, OPTION_MIPS16},
+@@ -14396,6 +15155,9 @@ struct option md_longopts[] =
+ {"mno-pdr", no_argument, NULL, OPTION_NO_PDR},
+ {"mvxworks-pic", no_argument, NULL, OPTION_MVXWORKS_PIC},
+ #endif /* OBJ_ELF */
++ {"ffix-bdsl", no_argument, NULL, OPTION_FIX_BDSL},
++ {"warn-possible-load-use", no_argument, NULL, OPTION_WARN_POSSIBLE_LOAD_USE},
++ {"warn-missing-delay-slot", no_argument, NULL, OPTION_WARN_MISSING_DELAY_SLOT},
+
+ {NULL, no_argument, NULL, 0}
+ };
+@@ -14431,6 +15193,18 @@ md_parse_option (int c, char *arg)
+ mips_disable_float_construction = 1;
+ break;
+
++ case OPTION_FIX_BDSL:
++ fix_bdsl = 1;
++ break;
++
++ case OPTION_WARN_POSSIBLE_LOAD_USE:
++ warn_possible_load_use = 1;
++ break;
++
++ case OPTION_WARN_MISSING_DELAY_SLOT:
++ warn_missing_delay_slot = 1;
++ break;
++
+ case OPTION_TRAP:
+ mips_trap = 1;
+ break;
+@@ -14509,6 +15283,9 @@ md_parse_option (int c, char *arg)
+ mips_set_option_string (&mips_arch_string, arg);
+ break;
+
++ case OPTION_MCE:
++ break;
++
+ case OPTION_M4650:
+ mips_set_option_string (&mips_arch_string, "4650");
+ mips_set_option_string (&mips_tune_string, "4650");
+@@ -15036,7 +15813,7 @@ mips_after_parse_args (void)
+ || mips_abi == O32_ABI))
+ mips_32bitmode = 1;
+
+- if (mips_opts.isa == ISA_MIPS1 && mips_trap)
++ if ((mips_opts.isa == ISA_MIPS1 || ISA_IS_RLX) && mips_trap)
+ as_bad (_("trap exception not supported at ISA 1"));
+
+ /* If the selected architecture includes support for ASEs, enable
+@@ -15113,6 +15890,9 @@ mips_after_parse_args (void)
+ }
+ }
+
++
++extern char *myname;
++
+ void
+ mips_init_after_args (void)
+ {
+@@ -15369,6 +16149,8 @@ md_apply_fix (fixS *fixP, valueT *valP,
+ case BFD_RELOC_MIPS_TLS_DTPREL_HI16:
+ case BFD_RELOC_MIPS_TLS_DTPREL_LO16:
+ case BFD_RELOC_MIPS_TLS_GOTTPREL:
++ case BFD_RELOC_MIPS_TLS_TPREL32:
++ case BFD_RELOC_MIPS_TLS_TPREL64:
+ case BFD_RELOC_MIPS_TLS_TPREL_HI16:
+ case BFD_RELOC_MIPS_TLS_TPREL_LO16:
+ case BFD_RELOC_MICROMIPS_TLS_GD:
+@@ -15378,6 +16160,13 @@ md_apply_fix (fixS *fixP, valueT *valP,
+ case BFD_RELOC_MICROMIPS_TLS_GOTTPREL:
+ case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16:
+ case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16:
++ case BFD_RELOC_MIPS16_TLS_GD:
++ case BFD_RELOC_MIPS16_TLS_LDM:
++ case BFD_RELOC_MIPS16_TLS_DTPREL_HI16:
++ case BFD_RELOC_MIPS16_TLS_DTPREL_LO16:
++ case BFD_RELOC_MIPS16_TLS_GOTTPREL:
++ case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
++ case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ /* fall through */
+
+@@ -15570,6 +16359,35 @@ md_apply_fix (fixS *fixP, valueT *valP,
+ fixP->fx_done = 0;
+ break;
+
++ case BFD_RELOC_RLX_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 ();
+ }
+@@ -16186,6 +17004,13 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
+ case 0:
+ break;
+ case ISA_MIPS1:
++ case ISA_RLX4081:
++ case ISA_RLX4180:
++ case ISA_RLX4181:
++ case ISA_RLX4281:
++ case ISA_RLX5181:
++ case ISA_RLX5280:
++ case ISA_RLX5281:
+ case ISA_MIPS2:
+ case ISA_MIPS32:
+ case ISA_MIPS32R2:
+@@ -16552,7 +17377,8 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED)
+ use in DWARF debug information. */
+
+ static void
+-s_dtprel_internal (size_t bytes)
++s_tls_rel_directive (const size_t bytes, const char *dirstr,
++ bfd_reloc_code_real_type rtype)
+ {
+ expressionS ex;
+ char *p;
+@@ -16561,19 +17387,13 @@ s_dtprel_internal (size_t bytes)
+
+ if (ex.X_op != O_symbol)
+ {
+- as_bad (_("Unsupported use of %s"), (bytes == 8
+- ? ".dtpreldword"
+- : ".dtprelword"));
++ as_bad (_("Unsupported use of %s"), dirstr);
+ ignore_rest_of_line ();
+ }
+
+ p = frag_more (bytes);
+ md_number_to_chars (p, 0, bytes);
+- fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+- (bytes == 8
+- ? BFD_RELOC_MIPS_TLS_DTPREL64
+- : BFD_RELOC_MIPS_TLS_DTPREL32));
+-
++ fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype);
+ demand_empty_rest_of_line ();
+ }
+
+@@ -16582,7 +17402,7 @@ s_dtprel_internal (size_t bytes)
+ static void
+ s_dtprelword (int ignore ATTRIBUTE_UNUSED)
+ {
+- s_dtprel_internal (4);
++ s_tls_rel_directive (4, ".dtprelword", BFD_RELOC_MIPS_TLS_DTPREL32);
+ }
+
+ /* Handle .dtpreldword. */
+@@ -16590,9 +17410,26 @@ s_dtprelword (int ignore ATTRIBUTE_UNUSE
+ static void
+ s_dtpreldword (int ignore ATTRIBUTE_UNUSED)
+ {
+- s_dtprel_internal (8);
++ s_tls_rel_directive (8, ".dtpreldword", BFD_RELOC_MIPS_TLS_DTPREL64);
++}
++
++/* Handle .tprelword. */
++
++static void
++s_tprelword (int ignore ATTRIBUTE_UNUSED)
++{
++ s_tls_rel_directive (4, ".tprelword", BFD_RELOC_MIPS_TLS_TPREL32);
+ }
+
++/* Handle .tpreldword. */
++
++static void
++s_tpreldword (int ignore ATTRIBUTE_UNUSED)
++{
++ s_tls_rel_directive (8, ".tpreldword", BFD_RELOC_MIPS_TLS_TPREL64);
++}
++
++
+ /* Handle the .gpvalue pseudo-op. This is used when generating NewABI PIC
+ code. It sets the offset to use in gp_rel relocations. */
+
+@@ -16996,6 +17833,9 @@ mips16_extended_frag (fragS *fragp, asec
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
++ /* force extend `b 0x3ff' */
++ if (fix_bdsl && type == 'q')
++ --maxtiny;
+ }
+
+ sym_frag = symbol_get_frag (fragp->fr_symbol);
+@@ -17203,7 +18043,7 @@ relaxed_branch_length (fragS *fragp, ase
+ {
+ /* Additional space for PIC loading of target address. */
+ length += 8;
+- if (mips_opts.isa == ISA_MIPS1)
++ if (mips_opts.isa == ISA_MIPS1 || ISA_IS_RLX)
+ /* Additional space for $at-stabilizing nop. */
+ length += 4;
+ }
+@@ -17809,7 +18649,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
+ md_number_to_chars ((char *) buf, insn, 4);
+ buf += 4;
+
+- if (mips_opts.isa == ISA_MIPS1)
++ if (mips_opts.isa == ISA_MIPS1 || ISA_IS_RLX)
+ {
+ /* nop */
+ md_number_to_chars ((char *) buf, 0, 4);
+@@ -18906,6 +19746,16 @@ static const struct mips_cpu_info mips_c
+ { "mips64", MIPS_CPU_IS_ISA, ISA_MIPS64, CPU_MIPS64 },
+ { "mips64r2", MIPS_CPU_IS_ISA, ISA_MIPS64R2, CPU_MIPS64R2 },
+
++ /* RLX */
++ { "rlx4081", MIPS_CPU_IS_ISA, ISA_RLX4081, CPU_RLX4081 },
++ { "rlx4180", MIPS_CPU_IS_ISA, ISA_RLX4180, CPU_RLX4180 },
++ { "rlx4181", MIPS_CPU_IS_ISA, ISA_RLX4181, CPU_RLX4181 },
++ { "rlx4281", MIPS_CPU_IS_ISA, ISA_RLX4281, CPU_RLX4281 },
++ { "rlx5181", MIPS_CPU_IS_ISA, ISA_RLX5181, CPU_RLX5181 },
++ { "rlx5280", MIPS_CPU_IS_ISA, ISA_RLX5280, CPU_RLX5280 },
++ { "rlx5281", MIPS_CPU_IS_ISA, ISA_RLX5281, CPU_RLX5281 },
++
++
+ /* MIPS I */
+ { "r3000", 0, ISA_MIPS1, CPU_R3000 },
+ { "r2000", 0, ISA_MIPS1, CPU_R3000 },
+@@ -19078,7 +19928,13 @@ 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')
+- given++;
++ {
++ /* 2006-01-19 tonywu: add to parse LX/RX CPUs */
++ if (TOLOWER (given[1]) == 'l' && TOLOWER (given[2]) == 'x')
++ given += 3;
++ else
++ given++;
++ }
+ if (!ISDIGIT (*given))
+ return FALSE;
+
+@@ -19086,10 +19942,15 @@ mips_matching_cpu_name_p (const char *ca
+ hoping to find a number there too. */
+ if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
+ canonical += 2;
+- else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
+- canonical += 2;
+ else if (TOLOWER (canonical[0]) == 'r')
+- canonical += 1;
++ {
++ if (TOLOWER (canonical[1]) == 'l' && TOLOWER (canonical[2]) == 'x')
++ canonical += 3;
++ else if (TOLOWER (canonical[1]) == 'm')
++ canonical += 2;
++ else
++ canonical += 1;
++ }
+
+ return mips_strict_matching_cpu_name_p (canonical, given);
+ }
+@@ -19353,3 +20214,69 @@ tc_mips_regname_to_dw2regnum (char *regn
+
+ return regnum;
+ }
++
++
++/* 2006-01-05 tonywu: merged from 2.14 */
++static inline int
++rlx_is_tword_use(const struct mips_cl_insn *insn1, const struct mips_cl_insn *insn2)
++{
++ int regno1;
++ int regno2;
++
++ if (insn1 == NULL || insn2 == NULL)
++ return 0;
++
++ if (strncmp(insn1->insn_mo->name, "lt", 2) != 0
++ && strncmp(insn1->insn_mo->name, "ltw", 3) != 0)
++ return 0;
++
++ regno1 = EXTRACT_OPERAND(mips_opts.micromips, RT, *insn1);
++ regno2 = regno1 + 1;
++
++#warning "Fix this"
++/*ololo
++ 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_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(mips_opts.micromips, RD, *pre) == EXTRACT_OPERAND(mips_opts.micromips, RT, *now))
++ return 2;
++
++ return 0;
++}
++
++static void
++rlx_warn_bdsl (const struct mips_cl_insn *insn2)
++{
++ struct mips_cl_insn *insn1 = history;
++
++ if ((insn1->insn_mo->pinfo
++ & (INSN_UNCOND_BRANCH_DELAY
++ | INSN_COND_BRANCH_DELAY)) != 0
++ && ((insn2->insn_mo->pinfo & INSN_LOAD_MEMORY_DELAY) != 0
++ || (mips_opts.mips16
++ && strcmp(insn2->insn_mo->name, "nop") != 0)))
++ {
++ as_warn (_("Branch-Deay-Slot-Load at noreorder section for `%s'"),
++ insn2->insn_mo->name);
++ }
++}
+diff -rupN ./bu.orig/include/elf/mips.h ./bu.new/include/elf/mips.h
+--- a/include/elf/mips.h 2011-07-24 17:20:12.000000000 +0300
++++ b/include/elf/mips.h 2013-09-26 20:56:56.787659157 +0300
+@@ -89,7 +89,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_RLX_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)
+@@ -98,7 +99,14 @@ START_RELOC_NUMBERS (elf_mips_reloc_type
+ RELOC_NUMBER (R_MIPS16_CALL16, 103)
+ RELOC_NUMBER (R_MIPS16_HI16, 104)
+ RELOC_NUMBER (R_MIPS16_LO16, 105)
+- FAKE_RELOC (R_MIPS16_max, 106)
++ RELOC_NUMBER (R_MIPS16_TLS_GD, 106)
++ RELOC_NUMBER (R_MIPS16_TLS_LDM, 107)
++ RELOC_NUMBER (R_MIPS16_TLS_DTPREL_HI16, 108)
++ RELOC_NUMBER (R_MIPS16_TLS_DTPREL_LO16, 109)
++ RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110)
++ RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111)
++ RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112)
++ FAKE_RELOC (R_MIPS16_max, 113)
+ /* These relocations are specific to VxWorks. */
+ RELOC_NUMBER (R_MIPS_COPY, 126)
+ RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127)
+diff -rupN ./bu.orig/include/opcode/mips.h ./bu.new/include/opcode/mips.h
+--- a/include/opcode/mips.h 2011-08-09 18:20:03.000000000 +0300
++++ b/include/opcode/mips.h 2013-09-26 21:45:55.694488685 +0300
+@@ -59,6 +59,42 @@
+
+ The general coprocessor instructions use COPZ. */
+
++/* dbb: modified for supporting radiax instructions */
++#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 */
++/* dbb: modified for supporting radiax instructions */
++
++/* DVR taro: modified for supporting audio engine instructions */
++#define OP_MASK_IMMIDATEa6 0x3f
++#define OP_SH_IMMIDATEa6 10
++/* DVR taro: modified for supporting audio engine instructions */
++
++/* DVR jacky: modified for supporting audio engine instructions */
++#define OP_MASK_IMMIDATE6A 0x3ff
++#define OP_SH_IMMIDATE6A 6
++/* DVR jacky: modified for supporting audio engine instructions */
++
++/* DVR yj: modified for supporting video engine2 instructions */
++#define OP_MASK_IMMIDATE8A 0xff
++#define OP_SH_IMMIDATE8A 8
++/* DVR yj: modified for supporting video engine2 instructions */
++
++/* 2009-03-19 tonywu: add for taroko */
++#define OP_MASK_RLX_SEL 0x3f
++#define OP_SH_RLX_SEL 0
++#define OP_MASK_RLX_STYPE 0x3f
++#define OP_SH_RLX_STYPE 6
++/* 2009-03-19 tonywu: add for taroko */
++
++
+ #define OP_MASK_OP 0x3f
+ #define OP_SH_OP 26
+ #define OP_MASK_RS 0x1f
+@@ -416,6 +452,33 @@ struct mips_opcode
+ Requires that "+A" or "+E" occur first to set position.
+ Enforces: 32 < (pos+size) <= 64.
+
++**** dbb modified for supporting radiax instructions **************************
++ "#`" even register,used in lt,st,ltp,stp (OP_*_EVENREG)
++ "#~" 8 bits immediate ,used in lbp,stp,etc(OP_*_IMMIDATE88)
++ "##" 4 bits immediate from 0 to 8,used in MFA,MFA2,RNDA2 (OP_*_IMMIDATE74)
++ "#@" 11 bits immediate used in lt,st (OP_*_IMMIDATE6b),in fact it is 14 bits,multiple of 8;
++ "#-" 10 bits offset,used in ltw(OP_*_OFFSET6A)
++ "#$"
++ "#&"
++ "#="
++ "#H"
++ "#I"
++ "#u"
++ "#k"
++ "#d1"
++ "#d2"
++ "#d3"
++ "#d4"
++ "#s1"
++ "#s2"
++ "#s3"
++ "#t1"
++ "#t2"
++ "#t3"
++**** dbb modified for supporting radiax instructions **************************
++
++
++
+ Floating point instructions:
+ "D" 5 bit destination register (OP_*_FD)
+ "M" 3 bit compare condition code (OP_*_CCC) (only used for mips4 and up)
+@@ -531,9 +594,9 @@ struct mips_opcode
+ instructions, if it is not equal to INSN_MACRO. */
+
+ /* Modifies the general purpose register in OP_*_RD. */
+-#define INSN_WRITE_GPR_D 0x00000001
++#define INSN_WRITE_RAD_D 0x00000001
+ /* Modifies the general purpose register in OP_*_RT. */
+-#define INSN_WRITE_GPR_T 0x00000002
++#define INSN_WRITE_RAD_T 0x00000002
+ /* Modifies general purpose register 31. */
+ #define INSN_WRITE_GPR_31 0x00000004
+ /* Modifies the floating point register in OP_*_FD. */
+@@ -543,9 +606,9 @@ struct mips_opcode
+ /* Modifies the floating point register in OP_*_FT. */
+ #define INSN_WRITE_FPR_T 0x00000020
+ /* Reads the general purpose register in OP_*_RS. */
+-#define INSN_READ_GPR_S 0x00000040
++#define INSN_READ_RAD_S 0x00000040
+ /* Reads the general purpose register in OP_*_RT. */
+-#define INSN_READ_GPR_T 0x00000080
++#define INSN_READ_RAD_T 0x00000080
+ /* Reads the floating point register in OP_*_FS. */
+ #define INSN_READ_FPR_S 0x00000100
+ /* Reads the floating point register in OP_*_FT. */
+@@ -617,6 +680,7 @@ struct mips_opcode
+ same information. */
+ #define INSN2_M_FP_D 0x00000010
+ /* Modifies the general purpose register in OP_*_RZ. */
++
+ #define INSN2_WRITE_GPR_Z 0x00000020
+ /* Modifies the floating point register in OP_*_FZ. */
+ #define INSN2_WRITE_FPR_Z 0x00000040
+@@ -673,13 +737,18 @@ struct mips_opcode
+ /* Reads the general purpose registers in MICROMIPSOP_*_MM/N. */
+ #define INSN2_READ_GPR_MMN 0x80000000
+
++/* DMP CEI
++ Identify an opcode is DMP CEI or not. */
++#define INSN2_TWORD_LOAD 0x00400000
++#define INSN2_TWORD_USE 0x00800000
++
+ /* Masks used to mark instructions to indicate which MIPS ISA level
+ they were introduced in. INSN_ISA_MASK masks an enumeration that
+ specifies the base ISA level(s). The remainder of a 32-bit
+ word constructed using these macros is a bitmask of the remaining
+ INSN_* values below. */
+
+-#define INSN_ISA_MASK 0x0000000ful
++#define INSN_ISA_MASK 0x0000001ful
+
+ /* We cannot start at zero due to ISA_UNKNOWN below. */
+ #define INSN_ISA1 1
+@@ -689,17 +758,39 @@ struct mips_opcode
+ #define INSN_ISA5 5
+ #define INSN_ISA32 6
+ #define INSN_ISA32R2 7
+-#define INSN_ISA64 8
+-#define INSN_ISA64R2 9
++
++/* RLX ASE */
++#define INSN_RLX_MASK 0x00000008ul
++
++#define INSN_RLX4081 9 /* Kinmen */
++#define INSN_RLX4180 10 /* Lexra */
++#define INSN_RLX4181 11 /* RLX */
++#define INSN_RLX4281 12 /* Taroko */
++#define INSN_RLX5181 13 /* RLX + Radiax-1 */
++#define INSN_RLX5280 14 /* Lexra + Radiax-1 */
++#define INSN_RLX5281 15 /* Taroko + Radiax-1 + Radiax-2 */
++
++#define INSN_ISA64 16
++#define INSN_ISA64R2 17
+ /* Below this point the INSN_* values correspond to combinations of ISAs.
+ They are only for use in the opcodes table to indicate membership of
+ a combination of ISAs that cannot be expressed using the usual inclusion
+ ordering on the above INSN_* values. */
+-#define INSN_ISA3_32 10
+-#define INSN_ISA3_32R2 11
+-#define INSN_ISA4_32 12
+-#define INSN_ISA4_32R2 13
+-#define INSN_ISA5_32R2 14
++#define INSN_ISA3_32 18
++#define INSN_ISA3_32R2 19
++#define INSN_ISA4_32 20
++#define INSN_ISA4_32R2 21
++#define INSN_ISA5_32R2 22
++
++/* RLX ASE group */
++#define INSN_RLX_ALL 24
++#define INSN_RLX_UDI 25
++#define INSN_RLX_TAROKO 26
++#define INSN_RLX_RAD1 27
++#define INSN_RLX_RAD2 28
++#define INSN_RLX_DMP 29
++#define INSN_ISA2_RLX 30
++#define INSN_ISA32_RALL 31
+
+ /* Given INSN_ISA* values X and Y, where X ranges over INSN_ISA1 through
+ INSN_ISA5_32R2 and Y ranges over INSN_ISA1 through INSN_ISA64R2,
+@@ -710,10 +801,13 @@ struct mips_opcode
+ (mips_isa_table[(Y & INSN_ISA_MASK) - 1] >> ((X & INSN_ISA_MASK) - 1)) & 1
+ is non-zero. */
+ static const unsigned int mips_isa_table[] =
+- { 0x0001, 0x0003, 0x0607, 0x1e0f, 0x3e1f, 0x0a23, 0x3e63, 0x3ebf, 0x3fff };
+-
++{
++ 0x00000001, 0x20000003, 0x20060007, 0x201e000f, 0x203e001f, 0x600a0023,
++ 0x603e0063, 0x40000081, 0x40800101, 0x40800201, 0x61800401, 0x63800801,
++ 0x75801001, 0x55802001, 0x6f804001, 0x603e803f, 0x603f807f,
++};
+ /* Masks used for Chip specific instructions. */
+-#define INSN_CHIP_MASK 0xc3ff0c20
++#define INSN_CHIP_MASK 0xc3ff1c00
+
+ /* Cavium Networks Octeon instructions. */
+ #define INSN_OCTEON 0x00000800
+@@ -766,7 +860,7 @@ static const unsigned int mips_isa_table
+ /* Loongson 3A. */
+ #define INSN_LOONGSON_3A 0x00000400
+ /* RMI Xlr instruction */
+-#define INSN_XLR 0x00000020
++#define INSN_XLR 0x00001000
+
+ /* MCU (MicroController) ASE */
+ #define INSN_MCU 0x00000010
+@@ -786,6 +880,14 @@ static const unsigned int mips_isa_table
+ #define ISA_MIPS32R2 INSN_ISA32R2
+ #define ISA_MIPS64R2 INSN_ISA64R2
+
++/* RLX ASE */
++#define ISA_RLX4081 INSN_RLX4081
++#define ISA_RLX4180 INSN_RLX4180
++#define ISA_RLX4181 INSN_RLX4181
++#define ISA_RLX4281 INSN_RLX4281
++#define ISA_RLX5181 INSN_RLX5181
++#define ISA_RLX5280 INSN_RLX5280
++#define ISA_RLX5281 INSN_RLX5281
+
+ /* CPU defines, use instead of hardcoding processor number. Keep this
+ in sync with bfd/archures.c in order for machine selection to work. */
+@@ -825,6 +927,14 @@ static const unsigned int mips_isa_table
+ #define CPU_OCTEON 6501
+ #define CPU_XLR 887682 /* decimal 'XLR' */
+
++#define CPU_RLX4081 4081 /* RLX4081 */
++#define CPU_RLX4180 4180 /* RLX4180 */
++#define CPU_RLX4181 4181 /* RLX4181 */
++#define CPU_RLX4281 4281 /* RLX4281 */
++#define CPU_RLX5181 5181 /* RLX5181 */
++#define CPU_RLX5280 5280 /* RLX5280 */
++#define CPU_RLX5281 5281 /* RLX5281 */
++
+ /* Test for membership in an ISA including chip specific ISAs. INSN
+ is pointer to an element of the opcode table; ISA is the specified
+ ISA/ASE bitmask to test against; and CPU is the CPU specific ISA to
+@@ -1285,6 +1395,16 @@ extern int bfd_mips_num_opcodes;
+ "E" 5 bit PC relative address * 4 (MIPS16OP_*_IMM5)
+ "m" 7 bit register list for save instruction (18 bit extended)
+ "M" 7 bit register list for restore instruction (18 bit extended)
++
++ Cache instruction:
++ "o" 0 bit offset (for compatible with mips1 mode)
++
++ Macro instructions:
++ "I" 32 bit immediate (value placed in imm_expr).
++
++ Coprocessor instructions:
++ "T" 5 bit target register (MIPS16OP_*_REGR32)
++ "G" 5 bit destination register (MIPS16OP_*_REG32R)
+ */
+
+ /* Save/restore encoding for the args field when all 4 registers are
+diff -rupN ./bu.orig/opcodes/micromips-opc.c ./bu.new/opcodes/micromips-opc.c
+--- a/opcodes/micromips-opc.c 2011-08-09 18:20:03.000000000 +0300
++++ b/opcodes/micromips-opc.c 2013-09-26 23:20:37.284803535 +0300
+@@ -58,17 +58,17 @@
+
+ /* For 32-bit microMIPS instructions. */
+ #define WR_s INSN_WRITE_GPR_S
+-#define WR_d INSN_WRITE_GPR_D
+-#define WR_t INSN_WRITE_GPR_T
++#define WR_d INSN_WRITE_RAD_D
++#define WR_t INSN_WRITE_RAD_T
+ #define WR_31 INSN_WRITE_GPR_31
+ #define WR_D INSN_WRITE_FPR_D
+ #define WR_T INSN_WRITE_FPR_T
+ #define WR_S INSN_WRITE_FPR_S
+ #define WR_CC INSN_WRITE_COND_CODE
+
+-#define RD_s INSN_READ_GPR_S
+-#define RD_b INSN_READ_GPR_S
+-#define RD_t INSN_READ_GPR_T
++#define RD_s INSN_READ_RAD_S
++#define RD_b INSN_READ_RAD_S
++#define RD_t INSN_READ_RAD_T
+ #define RD_T INSN_READ_FPR_T
+ #define RD_S INSN_READ_FPR_S
+ #define RD_R INSN_READ_FPR_R
+diff -rupN ./bu.orig/opcodes/mips16-opc.c ./bu.new/opcodes/mips16-opc.c
+--- a/opcodes/mips16-opc.c 2011-07-24 17:04:51.000000000 +0300
++++ b/opcodes/mips16-opc.c 2013-09-26 22:12:20.864576529 +0300
+@@ -67,6 +67,16 @@
+ #define I64 INSN_ISA64
+ #define T3 INSN_3900
+
++/* 2006-01-19 tonywu: define RLXn to simplify opcodes listing */
++#define RALL INSN_RLX_ALL
++#define I32_R INSN_ISA32_RALL
++
++#define COD INSN_COPROC_MOVE_DELAY
++#define CLD INSN_COPROC_MEMORY_DELAY
++#define RD_C0 INSN_COP
++#define WR_C0 INSN_COP
++
++
+ const struct mips_opcode mips16_opcodes[] =
+ {
+ /* name, args, match, mask, pinfo, pinfo2, membership */
+@@ -110,6 +120,9 @@ const struct mips_opcode mips16_opcodes[
+ {"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1 },
+ {"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 },
+ {"bnez", "x,p", 0x2800, 0xf800, CBR|RD_x, 0, I1 },
++/* 2006-01-19 tonywu: add blank break instructions */
++{"break", "", 0xe805, 0xffff, TRAP, 0, RALL },
++/* 2006-01-19 tonywu: add blank break instructions */
+ {"break", "6", 0xe805, 0xf81f, TRAP, 0, I1 },
+ {"bteqz", "p", 0x6000, 0xff00, CBR|RD_T, 0, I1 },
+ {"btnez", "p", 0x6100, 0xff00, CBR|RD_T, 0, I1 },
+@@ -244,6 +257,16 @@ const struct mips_opcode mips16_opcodes[
+ {"zeb", "x", 0xe811, 0xf8ff, WR_x|RD_x, 0, I32 },
+ {"zeh", "x", 0xe831, 0xf8ff, WR_x|RD_x, 0, I32 },
+ {"zew", "x", 0xe851, 0xf8ff, WR_x|RD_x, 0, I64 },
++ /* 2006-01-19 tonywu: add 16-bit mac instructions */
++{"madh", "x,y", 0xf800, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"madl", "x,y", 0xf802, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"mazh", "x,y", 0xf804, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"mazl", "x,y", 0xf806, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"msbh", "x,y", 0xf810, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"msbl", "x,y", 0xf812, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"mszh", "x,y", 0xf814, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++{"mszl", "x,y", 0xf816, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, RALL },
++ /* 2006-01-19 tonywu: add 16-bit mac instructions */
+ };
+
+ const int bfd_mips16_num_opcodes =
+diff -rupN ./bu.orig/opcodes/mips-dis.c ./bu.new/opcodes/mips-dis.c
+--- a/opcodes/mips-dis.c 2011-08-09 18:20:03.000000000 +0300
++++ b/opcodes/mips-dis.c 2013-09-26 23:00:05.814735292 +0300
+@@ -169,6 +169,52 @@ static const char * const mips_gpr_names
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+ };
+
++/* 2007-09-28 tonywu: extend to from 16 to 32 to prevent
++ * undefined pattern from crashing objdump
++ */
++static const char *const rlx_radacc_names_alias[32] = {
++ "reserved", "m0l", "m0h", "m0",
++ "reserved", "m1l", "m1h", "m1",
++ "reserved", "m2l", "m2h", "m2",
++ "reserved", "m3l", "m3h", "m3",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved"
++};
++/* 2007-09-28 tonywu: extend to from 16 to 32 to prevent
++ * undefined pattern from crashing objdump
++ */
++
++/* 2007-09-28 tonywu: extend to from 14 to 32 to prevent
++ * undefined pattern from crashing objdump
++ */
++static const char *const rlx_radreg_names_alias[32] = {
++ "cbs0", "cbs1", "cbs2", "reserved",
++ "cbe0", "cbe1", "cbe2", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "lps0", "lpe0", "lpc0", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "mmd", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved"
++};
++
++/* 2007-09-28 tonywu: extend to from 14 to 32 to prevent
++ * undefined pattern from crashing objdump
++ */
++/* tonywu 2006-01-04: merge from 2.14 */
++static const char *const rlx_cplxc0_names_alias[32] = {
++ "estatus", "ecause", "intvec", "cvstag",
++ "bpctl", "wmpctl", "wmpstatus", "wmpvaddr",
++ "tlptr", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "wmpextramask",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved",
++ "reserved", "reserved", "reserved", "reserved"
++};
++
+ static const char * const mips_fpr_names_numeric[32] =
+ {
+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+@@ -503,7 +549,20 @@ const struct mips_arch_choice mips_arch_
+ {
+ { "numeric", 0, 0, 0, 0,
+ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+-
++ { "rlx4081", 1, bfd_mach_mips_rlx4081, CPU_RLX4081, ISA_RLX4081,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx4180", 1, bfd_mach_mips_rlx4180, CPU_RLX4180, ISA_RLX4180,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx4181", 1, bfd_mach_mips_rlx4181, CPU_RLX4181, ISA_RLX4181,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx4281", 1, bfd_mach_mips_rlx4281, CPU_RLX4281, ISA_RLX4281,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx5181", 1, bfd_mach_mips_rlx5181, CPU_RLX5181, ISA_RLX5181,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx5280", 1, bfd_mach_mips_rlx5280, CPU_RLX5280, ISA_RLX5280,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
++ { "rlx5281", 1, bfd_mach_mips_rlx5281, CPU_RLX5281, ISA_RLX5281,
++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+ { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
+ mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
+ { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
+@@ -920,6 +979,7 @@ print_insn_args (const char *d,
+ const struct mips_opcode *opp)
+ {
+ int op, delta;
++ int mtype;
+ unsigned int lsb, msb, msbd;
+
+ lsb = 0;
+@@ -1479,6 +1539,134 @@ print_insn_args (const char *d,
+ (l >> OP_SH_FT) & OP_MASK_FT);
+ break;
+
++//----------------------------------------------------------------------
++ case '#':
++ d++;
++ switch (*d)
++ {
++ case '@':
++ delta = ((l >> OP_SH_IMMIDATE6b) & OP_MASK_IMMIDATE6b) * 8;
++ if (delta & 0x2000)
++ delta |= ~0x3fff;
++
++ (*info->fprintf_func) (info->stream, "%d", delta);
++ break;
++
++ /* 4 bits immediate from 0 to 8,used in MFA,MFA2,RNDA2 (OP_*_IMMIDATE74) */
++ case '#':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (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;
++ if ((strncmp (opp->name, "lbp", 3) == 0
++ || strncmp (opp->name, "sbp", 3) == 0))
++ mtype = 1;
++ else if ((strncmp (opp->name, "lhp", 3) == 0
++ || strncmp (opp->name, "shp", 3) == 0))
++ mtype = 2;
++ else if ((strncmp (opp->name, "lwp", 3) == 0
++ || strncmp (opp->name, "swp", 3) == 0))
++ mtype = 4;
++ else
++ mtype = 8;
++
++ (*info->fprintf_func) (info->stream, "%i", delta * mtype);
++ 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;
++
++ /* DVR taro: modified for supporting AE instructions */
++ case '$':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (l >> OP_SH_IMMIDATEa6) & OP_MASK_IMMIDATEa6);
++ break;
++ /* DVR taro: modified for supporting AE instructions */
++
++ /* DVR jacky: modified for supporting VE instructions */
++ case '&':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (l >> OP_SH_IMMIDATE6A) & OP_MASK_IMMIDATE6A);
++ break;
++
++ case '=':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (l >> OP_SH_IMMIDATE8A) & OP_MASK_IMMIDATE8A);
++ break;
++ /* DVR jacky: modified for supporting VE instructions */
++
++ /* 2008-07-08 tonywu: add for taroko processor */
++ case 'H':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (l >> OP_SH_RLX_SEL) & OP_MASK_RLX_SEL);
++ break;
++
++ case 'I':
++ (*info->fprintf_func) (info->stream, "%ld",
++ (l >> OP_SH_RLX_STYPE) & OP_MASK_RLX_STYPE);
++ break;
++ /* 2008-07-08 tonywu: add for taroko processor */
++
++ /* 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;
++
++ case 'k':
++ case 'u':
++ delta = (l >> OP_SH_RD) & OP_MASK_RD;
++ if (delta > 31 || delta < 0)
++ (*info->fprintf_func) (info->stream, "INVALID");
++ else
++ (*info->fprintf_func) (info->stream, "%s",
++ rlx_radreg_names_alias[delta]);
++ break;
++
++ case 'd': delta = (l >> OP_SH_RD) & OP_MASK_RD; goto GET_TYPE;
++ case 's': delta = (l >> OP_SH_RS) & OP_MASK_RS; goto GET_TYPE;
++ case 't': delta = (l >> OP_SH_RT) & OP_MASK_RT; goto GET_TYPE;
++GET_TYPE:
++ switch (*++d)
++ {
++ case '1': /* ACC */
++ case '2': /* ACC */
++ case '3': /* ACC */
++ if (delta > 15 || delta < 0)
++ (*info->fprintf_func) (info->stream, "INVALID");
++ else
++ (*info->fprintf_func) (info->stream, "%s",
++ rlx_radacc_names_alias[delta]);
++ break;
++ case '4':
++ if (delta > 31 || delta < 0)
++ (*info->fprintf_func) (info->stream, "INVALID");
++ else
++ (*info->fprintf_func) (info->stream, "%s",
++ rlx_cplxc0_names_alias[delta]);
++ break;
++ }
++ break;
++ }
++ break;
++ /* dbb: modified for supporting radiax instructions */
++
++
+ default:
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream,
+@@ -1555,7 +1743,7 @@ print_insn_mips (bfd_vma memaddr,
+ if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ {
+ if ((op->pinfo & (INSN_WRITE_GPR_31
+- | INSN_WRITE_GPR_D)) != 0)
++ | INSN_WRITE_RAD_D)) != 0)
+ info->insn_type = dis_jsr;
+ else
+ info->insn_type = dis_branch;
+@@ -1643,6 +1831,10 @@ print_mips16_insn_arg (char type,
+ (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
+ break;
+
++ case 'o':
++ (*info->fprintf_func) (info->stream, "0");
++ break;
++
+ case 'S':
+ (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
+ break;
+@@ -2170,7 +2362,8 @@ print_insn_mips16 (bfd_vma memaddr, stru
+ {
+ if (op->pinfo != INSN_MACRO
+ && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
+- && (insn & op->mask) == op->match)
++ && (insn & op->mask) == op->match
++ && OPCODE_IS_MEMBER (op, mips_isa, mips_processor))
+ {
+ const char *s;
+
+@@ -2915,7 +3108,7 @@ print_insn_micromips (bfd_vma memaddr, s
+ if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
+ | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
+ {
+- if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
++ if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_RAD_T)) != 0)
+ info->insn_type = dis_jsr;
+ else
+ info->insn_type = dis_branch;
+diff -rupN ./bu.orig/opcodes/mips-opc.c ./bu.new/opcodes/mips-opc.c
+--- a/opcodes/mips-opc.c 2011-08-09 18:20:03.000000000 +0300
++++ b/opcodes/mips-opc.c 2013-09-26 23:06:37.104756976 +0300
+@@ -41,15 +41,15 @@
+ #define TRAP INSN_NO_DELAY_SLOT
+ #define SM INSN_STORE_MEMORY
+
+-#define WR_d INSN_WRITE_GPR_D
+-#define WR_t INSN_WRITE_GPR_T
++#define WR_d INSN_WRITE_RAD_D
++#define WR_t INSN_WRITE_RAD_T
+ #define WR_31 INSN_WRITE_GPR_31
+ #define WR_D INSN_WRITE_FPR_D
+ #define WR_T INSN_WRITE_FPR_T
+ #define WR_S INSN_WRITE_FPR_S
+-#define RD_s INSN_READ_GPR_S
+-#define RD_b INSN_READ_GPR_S
+-#define RD_t INSN_READ_GPR_T
++#define RD_s INSN_READ_RAD_S
++#define RD_b INSN_READ_RAD_S
++#define RD_t INSN_READ_RAD_T
+ #define RD_S INSN_READ_FPR_S
+ #define RD_T INSN_READ_FPR_T
+ #define RD_R INSN_READ_FPR_R