diff options
author | xantares | 2015-06-08 23:10:16 +0200 |
---|---|---|
committer | xantares | 2015-06-08 23:10:16 +0200 |
commit | 5d909694dac917b4ec400645c1cd27977d3e526d (patch) | |
tree | 736573d31b7e07f7ca6e50f08f426bb44c3e0247 | |
download | aur-5d909694dac917b4ec400645c1cd27977d3e526d.tar.gz |
Initial import
-rw-r--r-- | .SRCINFO | 24 | ||||
-rw-r--r-- | PKGBUILD | 48 | ||||
-rw-r--r-- | binutils-2.22-PSP.patch | 4473 | ||||
-rw-r--r-- | binutils-2.22-texinfofix.patch | 24 |
4 files changed, 4569 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..5fd76d17d645 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,24 @@ +pkgbase = psp-binutils + pkgdesc = A set of programs to assemble and manipulate binary and object files (psp) + pkgver = 2.22 + pkgrel = 1 + url = http://www.gnu.org/software/binutils/ + arch = i686 + arch = x86_64 + groups = psp + license = GPL + makedepends = gcc + depends = zlib + depends = flex + options = !buildflags + options = !strip + options = staticlibs + source = http://ftp.gnu.org/pub/gnu/binutils/binutils-2.22.tar.bz2 + source = binutils-2.22-PSP.patch + source = binutils-2.22-texinfofix.patch + md5sums = ee0f10756c84979622b992a4a61ea3f5 + md5sums = a30ab9c15c985c771a42b19f3356d42b + md5sums = 771f36e63bc53732990f02ef42a475c9 + +pkgname = psp-binutils + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..a5996d63328a --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,48 @@ +# Maintainer: xantares <xantares09 at hotmail dot com> + +pkgname=psp-binutils +pkgver=2.22 +pkgrel=1 +pkgdesc="A set of programs to assemble and manipulate binary and object files (psp)" +arch=(i686 x86_64) +url="http://www.gnu.org/software/binutils/" +license=('GPL') +groups=('psp') +depends=('zlib' 'flex') +makedepends=('gcc') +options=('!buildflags' '!strip' 'staticlibs') +source=("http://ftp.gnu.org/pub/gnu/binutils/binutils-$pkgver.tar.bz2" + 'binutils-2.22-PSP.patch' + 'binutils-2.22-texinfofix.patch') +md5sums=('ee0f10756c84979622b992a4a61ea3f5' + 'a30ab9c15c985c771a42b19f3356d42b' + '771f36e63bc53732990f02ef42a475c9') + +prepare () +{ + cd "$srcdir/binutils-$pkgver" + rm -f include/opcode/vfpu.h ld/emulparams/elf_mipsallegrexel_psp.sh ld/scripttempl/elf_psp.sc + patch -p1 -i "$srcdir"/binutils-2.22-PSP.patch + patch -p1 -i "$srcdir"/binutils-2.22-texinfofix.patch +} + +build() +{ + cd "$srcdir/binutils-$pkgver" + mkdir -p build-psp && pushd build-psp + ../configure --prefix=/usr --target=psp \ + --enable-install-libbfd \ + --disable-werror + make +} + +package() +{ + cd "$srcdir/binutils-$pkgver/build-psp" + make install DESTDIR="$pkgdir" + rm -r "$pkgdir"/usr/share + cp -r "$pkgdir"/usr/`gcc -dumpmachine`/psp "$pkgdir"/usr + rm -r "$pkgdir"/usr/`gcc -dumpmachine` + rm -r "$pkgdir"/usr/lib +} + diff --git a/binutils-2.22-PSP.patch b/binutils-2.22-PSP.patch new file mode 100644 index 000000000000..c82c2458568d --- /dev/null +++ b/binutils-2.22-PSP.patch @@ -0,0 +1,4473 @@ +diff -burN orig.binutils-2.22/bfd/archures.c binutils-2.22/bfd/archures.c +--- orig.binutils-2.22/bfd/archures.c 2011-08-02 01:04:19.000000000 +0200 ++++ binutils-2.22/bfd/archures.c 2012-01-04 16:18:30.404282447 +0100 +@@ -175,6 +175,7 @@ + .#define bfd_mach_mips_loongson_2f 3002 + .#define bfd_mach_mips_loongson_3a 3003 + .#define bfd_mach_mips_sb1 12310201 {* octal 'SB', 01 *} ++.#define bfd_mach_mips_allegrex 10111431 {* octal 'AL', 31 *} + .#define bfd_mach_mips_octeon 6501 + .#define bfd_mach_mips_xlr 887682 {* decimal 'XLR' *} + .#define bfd_mach_mipsisa32 32 +diff -burN orig.binutils-2.22/bfd/bfd-in2.h binutils-2.22/bfd/bfd-in2.h +--- orig.binutils-2.22/bfd/bfd-in2.h 2011-09-16 03:15:18.000000000 +0200 ++++ binutils-2.22/bfd/bfd-in2.h 2012-01-04 16:18:30.406282423 +0100 +@@ -1882,6 +1882,7 @@ + #define bfd_mach_mips_loongson_2f 3002 + #define bfd_mach_mips_loongson_3a 3003 + #define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ ++#define bfd_mach_mips_allegrex 10111431 /* octal 'AL', 31 */ + #define bfd_mach_mips_octeon 6501 + #define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */ + #define bfd_mach_mipsisa32 32 +diff -burN orig.binutils-2.22/bfd/cpu-mips.c binutils-2.22/bfd/cpu-mips.c +--- orig.binutils-2.22/bfd/cpu-mips.c 2011-07-24 16:20:05.000000000 +0200 ++++ binutils-2.22/bfd/cpu-mips.c 2012-01-04 16:18:30.415282321 +0100 +@@ -89,6 +89,7 @@ + I_mipsisa64, + I_mipsisa64r2, + I_sb1, ++ I_allegrex, + I_loongson_2e, + I_loongson_2f, + I_loongson_3a, +@@ -130,6 +131,7 @@ + N (64, 64, bfd_mach_mipsisa64, "mips:isa64", FALSE, NN(I_mipsisa64)), + N (64, 64, bfd_mach_mipsisa64r2,"mips:isa64r2", FALSE, NN(I_mipsisa64r2)), + N (64, 64, bfd_mach_mips_sb1, "mips:sb1", FALSE, NN(I_sb1)), ++ N (32, 32, bfd_mach_mips_allegrex, "mips:allegrex", FALSE, NN(I_allegrex)), + N (64, 64, bfd_mach_mips_loongson_2e, "mips:loongson_2e", FALSE, NN(I_loongson_2e)), + N (64, 64, bfd_mach_mips_loongson_2f, "mips:loongson_2f", FALSE, NN(I_loongson_2f)), + N (64, 64, bfd_mach_mips_loongson_3a, "mips:loongson_3a", FALSE, NN(I_loongson_3a)), +diff -burN orig.binutils-2.22/bfd/elfxx-mips.c binutils-2.22/bfd/elfxx-mips.c +--- orig.binutils-2.22/bfd/elfxx-mips.c 2011-11-21 10:29:27.000000000 +0100 ++++ binutils-2.22/bfd/elfxx-mips.c 2012-01-04 16:34:40.245420280 +0100 +@@ -6173,14 +6173,19 @@ + case E_MIPS_MACH_SB1: + return bfd_mach_mips_sb1; + ++ case E_MIPS_MACH_ALLEGREX: ++ return bfd_mach_mips_allegrex; ++ + case E_MIPS_MACH_LS2E: + return bfd_mach_mips_loongson_2e; + + case E_MIPS_MACH_LS2F: + return bfd_mach_mips_loongson_2f; + ++ /* + case E_MIPS_MACH_LS3A: + return bfd_mach_mips_loongson_3a; ++ */ + + case E_MIPS_MACH_OCTEON: + return bfd_mach_mips_octeon; +@@ -10882,6 +10887,10 @@ + val = E_MIPS_ARCH_64 | E_MIPS_MACH_SB1; + break; + ++ case bfd_mach_mips_allegrex: ++ val = E_MIPS_ARCH_2 | E_MIPS_MACH_ALLEGREX; ++ break; ++ + case bfd_mach_mips_loongson_3a: + val = E_MIPS_ARCH_64 | E_MIPS_MACH_LS3A; + break; +@@ -13544,6 +13553,7 @@ + /* MIPS II extensions. */ + { bfd_mach_mips4000, bfd_mach_mips6000 }, + { bfd_mach_mipsisa32, bfd_mach_mips6000 }, ++ { bfd_mach_mips_allegrex, bfd_mach_mips6000 }, + + /* MIPS I extensions. */ + { bfd_mach_mips6000, bfd_mach_mips3000 }, +diff -burN orig.binutils-2.22/bfd/version.h binutils-2.22/bfd/version.h +--- orig.binutils-2.22/bfd/version.h 2011-11-21 10:29:28.000000000 +0100 ++++ binutils-2.22/bfd/version.h 2012-01-04 16:18:30.454281876 +0100 +@@ -1,4 +1,4 @@ +-#define BFD_VERSION_DATE 20111121 ++#define BFD_VERSION_DATE (PSNPT 20120103) + #define BFD_VERSION @bfd_version@ + #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ + #define REPORT_BUGS_TO @report_bugs_to@ +diff -burN orig.binutils-2.22/binutils/readelf.c binutils-2.22/binutils/readelf.c +--- orig.binutils-2.22/binutils/readelf.c 2011-09-21 22:49:13.000000000 +0200 ++++ binutils-2.22/binutils/readelf.c 2012-01-04 22:48:15.610613183 +0100 +@@ -2395,10 +2395,11 @@ + case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break; + case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break; + case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break; +- case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; ++ /* case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; */ + case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break; + case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break; + case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break; ++ case E_MIPS_MACH_ALLEGREX: strcat(buf, ", allegrex"); break; + case 0: + /* We simply ignore the field in this case to avoid confusion: + MIPS ELF does not specify EF_MIPS_MACH, it is a GNU +diff -burN orig.binutils-2.22/config.sub binutils-2.22/config.sub +--- orig.binutils-2.22/config.sub 2011-06-06 12:36:06.000000000 +0200 ++++ binutils-2.22/config.sub 2012-01-04 22:48:59.316081182 +0100 +@@ -279,6 +279,7 @@ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ ++ | mipsallegrex | mipsallegrexel \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ +@@ -389,6 +390,7 @@ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ ++ | mipsallegrex-* | mipsallegrexel-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ +@@ -788,6 +790,10 @@ + basic_machine=m68k-atari + os=-mint + ;; ++ psp) ++ basic_machine=mipsallegrexel-psp ++ os=-elf ++ ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; +diff -burN orig.binutils-2.22/configure binutils-2.22/configure +--- orig.binutils-2.22/configure 2011-08-14 14:28:15.000000000 +0200 ++++ binutils-2.22/configure 2012-01-04 16:18:36.756209883 +0100 +@@ -2667,7 +2667,7 @@ + # binutils, gas and ld appear in that order because it makes sense to run + # "make check" in that particular order. + # If --enable-gold is used, "gold" may replace "ld". +-host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools" ++host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb etc expect dejagnu m4 utils guile fastjar gnattools" + + # libgcj represents the runtime libraries only used by gcj. + libgcj="target-libffi \ +@@ -3568,7 +3568,6 @@ + mips*-*-linux*) + ;; + mips*-*-*) +- noconfigdirs="$noconfigdirs gprof" + ;; + sh-*-* | sh64-*-*) + case "${target}" in +diff -burN orig.binutils-2.22/gas/config/tc-mips.c binutils-2.22/gas/config/tc-mips.c +--- orig.binutils-2.22/gas/config/tc-mips.c 2011-11-21 10:29:32.000000000 +0100 ++++ binutils-2.22/gas/config/tc-mips.c 2012-01-14 23:46:05.823744072 +0100 +@@ -91,8 +91,32 @@ + + #define ZERO 0 + #define ATREG 1 ++#define V0 2 ++#define V1 3 ++#define A0 4 ++#define A1 5 ++#define A2 6 ++#define A3 7 ++#define T0 8 ++#define T1 9 ++#define T2 10 ++#define T3 11 ++#define T4 12 ++#define T5 13 ++#define T6 14 ++#define T7 15 + #define S0 16 ++#define S1 17 ++#define S2 18 ++#define S3 19 ++#define S4 20 ++#define S5 21 ++#define S6 22 + #define S7 23 ++#define T8 24 ++#define T9 25 ++#define K0 26 ++#define K1 27 + #define TREG 24 + #define PIC_CALL_REG 25 + #define KT0 26 +@@ -490,11 +514,14 @@ + /* Return true if the given CPU supports the microMIPS ASE. */ + #define CPU_HAS_MICROMIPS(cpu) 0 + ++/* True if the given CPU belongs to the Allegrex family. */ ++#define CPU_IS_ALLEGREX(CPU) ((CPU) == CPU_ALLEGREX) ++ + /* True if CPU has a dror instruction. */ + #define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500) + + /* True if CPU has a ror instruction. */ +-#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU) ++#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU) || CPU_IS_ALLEGREX (CPU) + + /* True if CPU has seq/sne and seqi/snei instructions. */ + #define CPU_HAS_SEQ(CPU) ((CPU) == CPU_OCTEON) +@@ -528,6 +555,7 @@ + || mips_opts.arch == CPU_R16000 \ + || mips_opts.arch == CPU_RM7000 \ + || mips_opts.arch == CPU_VR5500 \ ++ || mips_opts.arch == CPU_ALLEGREX \ + || mips_opts.micromips \ + ) + +@@ -1563,6 +1591,8 @@ + static expressionS imm_expr; + static expressionS imm2_expr; + static expressionS offset_expr; ++static expressionS vimm_expr[4]; ++static expressionS voffset_expr[4]; + + /* Relocs associated with imm_expr and offset_expr. */ + +@@ -1571,6 +1601,15 @@ + static bfd_reloc_code_real_type offset_reloc[3] + = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED}; + ++/* set by vfpu code for prefix instructions */ ++ ++static bfd_boolean vfpu_dprefix; ++static char vfpu_dprefix_str[64]; ++static bfd_boolean vfpu_sprefix; ++static char vfpu_sprefix_str[64]; ++static bfd_boolean vfpu_tprefix; ++static char vfpu_tprefix_str[64]; ++ + /* This is set to the resulting size of the instruction to be produced + by mips16_ip if an explicit extension is used or by mips_ip if an + explicit size is supplied. */ +@@ -2580,6 +2619,56 @@ + return; + } + ++ /* If we've generated operands for a VFPU prefix instruction then we need ++ to assemble and append the prefix instruction before emitting the ++ instruction it prefixes. Note that in mips_ip prefix operands do not ++ cause any side effects with imm_expr or offset_expr. If they did ++ we'd have to save and restore them here. */ ++ if (CPU_IS_ALLEGREX (mips_opts.arch) && ((vfpu_dprefix || vfpu_sprefix || vfpu_tprefix))) ++ { ++ ++ if (mips_opts.noreorder ++ && ( history[0].insn_mo->pinfo & (INSN_UNCOND_BRANCH_DELAY ++ | INSN_COND_BRANCH_DELAY ++ | INSN_COND_BRANCH_LIKELY))) ++ { ++ as_bad (_("instruction with prefix cannot be used in branch delay slot")); ++ } ++ ++ if (vfpu_dprefix) ++ { ++ struct mips_cl_insn prefix; ++ char buf[256]; ++ ++ sprintf (buf, "vpfxd %s", vfpu_dprefix_str); ++ mips_ip (buf, &prefix); ++ append_insn (&prefix, NULL, unused_reloc, FALSE); ++ vfpu_dprefix = FALSE; ++ } ++ ++ if (vfpu_sprefix) ++ { ++ struct mips_cl_insn prefix; ++ char buf[256]; ++ ++ sprintf (buf, "vpfxs %s", vfpu_sprefix_str); ++ mips_ip (buf, &prefix); ++ append_insn ( &prefix, NULL, unused_reloc, FALSE); ++ vfpu_sprefix = FALSE; ++ } ++ ++ if (vfpu_tprefix) ++ { ++ struct mips_cl_insn prefix; ++ char buf[256]; ++ ++ sprintf (buf, "vpfxt %s", vfpu_tprefix_str); ++ mips_ip (buf, &prefix); ++ append_insn (&prefix, NULL, unused_reloc, FALSE); ++ vfpu_tprefix = FALSE; ++ } ++ } ++ + if (insn.insn_mo->pinfo == INSN_MACRO) + { + macro_start (); +@@ -5085,6 +5174,55 @@ + } + continue; + ++ /* VFPU fields */ ++ case '?': ++ switch (*fmt++) ++ { ++ case 'o': ++ *r = (bfd_reloc_code_real_type) va_arg (args, int); ++ gas_assert (*r == BFD_RELOC_GPREL16 ++ || *r == BFD_RELOC_MIPS_LITERAL ++ || *r == BFD_RELOC_MIPS_HIGHER ++ || *r == BFD_RELOC_HI16_S ++ || *r == BFD_RELOC_LO16 ++ || *r == BFD_RELOC_MIPS_GOT16 ++ || *r == BFD_RELOC_MIPS_CALL16 ++ || *r == BFD_RELOC_MIPS_GOT_DISP ++ || *r == BFD_RELOC_MIPS_GOT_PAGE ++ || *r == BFD_RELOC_MIPS_GOT_OFST ++ || *r == BFD_RELOC_MIPS_GOT_LO16 ++ || *r == BFD_RELOC_MIPS_CALL_LO16); ++ break; ++ case 'd': ++ insn.insn_opcode |= va_arg (args, int) << VF_SH_VD; ++ fmt += 2; ++ break; ++ case 's': ++ insn.insn_opcode |= va_arg (args, int) << VF_SH_VS; ++ fmt += 2; ++ break; ++ case 'm': ++ { ++ int vtreg = va_arg (args, int); ++ insn.insn_opcode |= (vtreg & VF_MASK_VML) << VF_SH_VML; ++ insn.insn_opcode |= ((vtreg >> 5) & VF_MASK_VMH) << VF_SH_VMH; ++ fmt += 2; ++ } ++ break; ++ case 'n': ++ { ++ int vtreg = va_arg (args, int); ++ insn.insn_opcode |= (vtreg & VF_MASK_VNL) << VF_SH_VNL; ++ insn.insn_opcode |= ((vtreg >> 5) & VF_MASK_VNH) << VF_SH_VNH; ++ fmt += 2; ++ } ++ break; ++ case 'e': ++ insn.insn_opcode |= va_arg (args, int) << VF_SH_MCOND; ++ break; ++ } ++ continue; ++ + default: + internalError (); + } +@@ -6241,6 +6379,7 @@ + macro (struct mips_cl_insn *ip) + { + unsigned int treg, sreg, dreg, breg; ++ int vsreg, vtreg, vdreg, vmreg, vwb; + unsigned int tempreg; + int mask; + int used_at = 0; +@@ -6272,6 +6411,13 @@ + sreg = breg = EXTRACT_OPERAND (mips_opts.micromips, RS, *ip); + mask = ip->insn_mo->mask; + ++ vmreg = ((ip->insn_opcode >> 16) & 0x1f) ++ | ((ip->insn_opcode << 5) & 0x60); ++ vtreg = (ip->insn_opcode >> 16) & 0x7f; ++ vsreg = (ip->insn_opcode >> 8) & 0x7f; ++ vdreg = (ip->insn_opcode >> 0) & 0x7f; ++ vwb = (ip->insn_opcode >> 1) & 0x1; ++ + label_expr.X_op = O_constant; + label_expr.X_op_symbol = NULL; + label_expr.X_add_symbol = NULL; +@@ -7964,6 +8110,34 @@ + /* Itbl support may require additional care here. */ + coproc = 1; + goto ld_st; ++ case M_LV_S_AB: ++ s = "lv.s"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?m0x,?o(b)"; ++ treg = vmreg; ++ goto ld; ++ case M_LV_Q_AB: ++ s = "lv.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld; ++ case M_LVL_Q_AB: ++ s = "lvl.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld; ++ case M_LVR_Q_AB: ++ s = "lvr.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld; + case M_LWL_AB: + ab = 1; + case M_LWL_OB: +@@ -8125,6 +8299,37 @@ + /* Itbl support may require additional care here. */ + coproc = 1; + goto ld_st; ++ case M_SV_S_AB: ++ s = "sv.s"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?m0x,?o(b)"; ++ treg = vmreg; ++ goto ld_st; ++ case M_SV_Q_AB: ++ if (vwb) ++ s = "vwb.q"; ++ else ++ s = "sv.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld_st; ++ case M_SVL_Q_AB: ++ s = "svl.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld_st; ++ case M_SVR_Q_AB: ++ s = "svr.q"; ++ /* Itbl support may require additional care here. */ ++ coproc = 1; ++ fmt = "?n3x,?o(b)"; ++ treg = vmreg; ++ goto ld_st; + case M_SWL_AB: + ab = 1; + case M_SWL_OB: +@@ -8654,6 +8859,138 @@ + break; + } + ++ case M_LVI_S_SS: ++ case M_LVI_P_SS: ++ case M_LVI_T_SS: ++ case M_LVI_Q_SS: ++ { ++ int mtx = (vtreg >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; ++ int idx = (vtreg >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; ++ int fsl = 0; ++ int rxc = 0; ++ int vtreg_s = 0; ++ int vnum = 0; ++ int vat = 0; ++ int i; ++ ++ switch (mask) ++ { ++ case M_LVI_S_SS: ++ vnum = 1; ++ fsl = (vtreg >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; ++ rxc = 0; ++ break; ++ case M_LVI_P_SS: ++ vnum = 2; ++ fsl = ((vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL) << 1; ++ rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ break; ++ case M_LVI_T_SS: ++ vnum = 3; ++ fsl = (vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; ++ rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ break; ++ case M_LVI_Q_SS: ++ vnum = 4; ++ fsl = 0; ++ rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ break; ++ } ++ if (rxc) ++ vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_FSL) ++ | (fsl << VF_SH_MR_IDX); ++ else ++ vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_IDX) ++ | (fsl << VF_SH_MR_FSL); ++ ++ for (i = 0; i < vnum; i++) { ++ imm_expr = vimm_expr[i]; ++ offset_expr = voffset_expr[i]; ++ ++ if (imm_expr.X_op == O_constant) ++ { ++ load_register (AT, &imm_expr, 0); ++ macro_build ((expressionS *) NULL, ++ "mtv", "t,?d0z", AT, vtreg_s); ++ vat = 1; ++ } ++ else ++ { ++ gas_assert (offset_expr.X_op == O_symbol ++ && strcmp (segment_name (S_GET_SEGMENT ++ (offset_expr.X_add_symbol)), ++ ".lit4") == 0 ++ && offset_expr.X_add_number == 0); ++ macro_build (&offset_expr, ++ "lv.s", "?m0x,?o(b)", vtreg_s, ++ (int) BFD_RELOC_MIPS_LITERAL, mips_gp_register); ++ } ++ ++ if (rxc) ++ vtreg_s += (1 << VF_SH_MR_IDX); ++ else ++ vtreg_s += (1 << VF_SH_MR_FSL); ++ } ++ ++ if (vat) ++ break; ++ else ++ return; ++ } ++ ++ case M_LVHI_S_SS: ++ case M_LVHI_P_SS: ++ { ++ int mtx = (vtreg >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; ++ int idx = (vtreg >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; ++ int fsl = 0; ++ int rxc = 0; ++ int vtreg_s = 0; ++ int vnum = 0; ++ int i; ++ unsigned int f16v; ++ char f16v_str[16]; ++ ++ switch (mask) ++ { ++ case M_LVHI_S_SS: ++ vnum = 2; ++ fsl = (vtreg >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; ++ rxc = 0; ++ break; ++ case M_LVHI_P_SS: ++ vnum = 4; ++ fsl = ((vtreg >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL) << 1; ++ rxc = (vtreg >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ break; ++ } ++ if (rxc) ++ vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_FSL) ++ | (fsl << VF_SH_MR_IDX); ++ else ++ vtreg_s = (mtx << VF_SH_MR_MTX) | (idx << VF_SH_MR_IDX) ++ | (fsl << VF_SH_MR_FSL); ++ ++ ++ for (i = 0; i < vnum; i += 2) { ++ f16v = ((vimm_expr[i + 1].X_add_number & 0xffff) << 16) ++ | (vimm_expr[i].X_add_number & 0xffff); ++ sprintf(f16v_str, "0x%08x", f16v); ++ my_getExpression (&imm_expr, f16v_str); ++ ++ load_register (AT, &imm_expr, 0); ++ macro_build ((expressionS *) NULL, ++ "mtv", "t,?d0z", AT, vtreg_s); ++ ++ if (rxc) ++ vtreg_s += (1 << VF_SH_MR_IDX); ++ else ++ vtreg_s += (1 << VF_SH_MR_FSL); ++ } ++ ++ break; ++ } ++ + case M_LI_D: + /* Check if we have a constant in IMM_EXPR. If the GPRs are 64 bits + wide, IMM_EXPR is the entire value. Otherwise IMM_EXPR is the high +@@ -9164,6 +9501,27 @@ + move_register (dreg, sreg); + break; + ++ case M_VCMOV_S: ++ s = "vcmovt.s"; ++ fmt = "?d0d,?s0s,?e"; ++ goto vcmov; ++ case M_VCMOV_P: ++ s = "vcmovt.p"; ++ fmt = "?d1d,?s1s,?e"; ++ goto vcmov; ++ case M_VCMOV_T: ++ s = "vcmovt.t"; ++ fmt = "?d2d,?s2s,?e"; ++ goto vcmov; ++ case M_VCMOV_Q: ++ s = "vcmovt.q"; ++ fmt = "?d3d,?s3s,?e"; ++ vcmov: ++ macro_build ((expressionS *) NULL, s, fmt, ++ vdreg, vsreg, ++ (ip->insn_opcode >> VF_SH_MCOND) & VF_MASK_MCOND); ++ return; ++ + case M_DMUL: + dbl = 1; + case M_MUL: +@@ -9779,6 +10137,40 @@ + off12 = mips_opts.micromips; + off = 3; + goto uld_st; ++ ++ case M_ULV_S: ++ if (mips_opts.arch == CPU_ALLEGREX) ++ as_bad (_("opcode not supported on this processor")); ++ off = 3; ++ if (offset_expr.X_add_number >= 0x8000 - off) ++ as_bad (_("operand overflow")); ++ if (! target_big_endian) ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "lwl", "t,o(b)", ++ AT, (int) BFD_RELOC_LO16, breg); ++ if (! target_big_endian) ++ offset_expr.X_add_number -= off; ++ else ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "lwr", "t,o(b)", ++ AT, (int) BFD_RELOC_LO16, breg); ++ ++ macro_build ((expressionS *) NULL, "mtv", "t,?d0z", ++ AT, vmreg); ++ break; ++ ++ case M_ULV_Q: ++ off = 12; ++ if (offset_expr.X_add_number >= 0x8000 - off) ++ as_bad (_("operand overflow")); ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "lvl.q", "?n3x,?o(b)", ++ vmreg, (int) BFD_RELOC_LO16, breg); ++ offset_expr.X_add_number -= off; ++ macro_build (&offset_expr, "lvr.q", "?n3x,?o(b)", ++ vmreg, (int) BFD_RELOC_LO16, breg); ++ return; ++ + case M_ULD_A: + ab = 1; + case M_ULD: +@@ -9804,6 +10196,56 @@ + off = 3; + ust = 1; + goto uld_st; ++ ++ case M_USV_S: ++ off = 3; ++ if (offset_expr.X_add_number >= 0x8000 - off) ++ as_bad (_("operand overflow")); ++ macro_build ((expressionS *) NULL, "mfv", "t,?d0z", ++ AT, vmreg); ++ if (mips_opts.arch != CPU_ALLEGREX) ++ { ++ if (! target_big_endian) ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "swl", "t,o(b)", ++ AT, (int) BFD_RELOC_LO16, breg); ++ if (! target_big_endian) ++ offset_expr.X_add_number -= off; ++ else ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "swr", "t,o(b)", ++ AT, (int) BFD_RELOC_LO16, breg); ++ } ++ else ++ { ++ if (target_big_endian) ++ offset_expr.X_add_number += off; ++ while (off-- >= 0) ++ { ++ macro_build (&offset_expr, "sb", "t,o(b)", ++ AT, (int) BFD_RELOC_LO16, breg); ++ macro_build ((expressionS *) NULL, "ror", ++ "d,w,<", AT, AT, 8); ++ if (target_big_endian) ++ --offset_expr.X_add_number; ++ else ++ ++offset_expr.X_add_number; ++ } ++ } ++ break; ++ ++ case M_USV_Q: ++ off = 12; ++ if (offset_expr.X_add_number >= 0x8000 - off) ++ as_bad (_("operand overflow")); ++ offset_expr.X_add_number += off; ++ macro_build (&offset_expr, "svl.q", "?n3x,?o(b)", ++ vmreg, (int) BFD_RELOC_LO16, breg); ++ offset_expr.X_add_number -= off; ++ macro_build (&offset_expr, "svr.q", "?n3x,?o(b)", ++ vmreg, (int) BFD_RELOC_LO16, breg); ++ return; ++ + case M_USD_A: + ab = 1; + case M_USD: +@@ -10279,6 +10721,103 @@ + case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break; + case '[': break; + case ']': break; ++ ++ /* VFPU fields */ ++ case '?': ++ switch (c = *p++) ++ { ++ case '[': break; ++ case ']': break; ++ case 'y': ++ { ++ if ((*p != '0') && (*p != '1') && (*p != '2') && (*p != '3')) ++ { ++ as_bad (_("internal: bad mips opcode : %s %s"), ++ opc->name, opc->args); ++ return 0; ++ } ++ p++; ++ } ++ break; ++ ++ case 'o': USE_BITS (VF_MASK_OFFSET, VF_SH_OFFSET); break; ++ ++ case 's': ++ case 't': ++ case 'd': ++ case 'v': ++ case 'x': ++ case 'm': ++ case 'n': ++ { ++ if ((*p != '0') && (*p != '1') && (*p != '2') && (*p != '3') ++ && (*p != '5') && (*p != '6') && (*p != '7')) ++ { ++ as_bad (_("internal: bad mips opcode (vreg type `?%c'): %s %s"), ++ *p, opc->name, opc->args); ++ return 0; ++ } ++ p++; ++ ++ if ((*p != 's') && (*p != 't') && (*p != 'd') ++ && (*p != 'y') && (*p != 'x') && (*p != 'z') ++ && (*p != 'w') && (*p != 'm')) ++ { ++ as_bad (_("internal: bad mips opcode (vreg type `?%c'): %s %s"), ++ *(p - 1), opc->name, opc->args); ++ } ++ p++; ++ ++ switch (c) ++ { ++ case 's': USE_BITS (VF_MASK_VS, VF_SH_VS); break; ++ case 't': USE_BITS (VF_MASK_VT, VF_SH_VT); break; ++ case 'd': ++ case 'v': ++ case 'x': USE_BITS (VF_MASK_VD, VF_SH_VD); break; ++ case 'm': USE_BITS (VF_MASK_VML, VF_SH_VML); ++ USE_BITS (VF_MASK_VMH, VF_SH_VMH); break; ++ case 'n': USE_BITS (VF_MASK_VNL, VF_SH_VNL); ++ USE_BITS (VF_MASK_VNH, VF_SH_VNH); break; ++ } ++ } ++ break; ++ ++ case 'f': USE_BITS (VF_MASK_CC, VF_SH_CC); ++ p++; break; ++ ++ case 'a': USE_BITS (VF_MASK_CONST, VF_SH_CONST); break; ++ case 'b': USE_BITS (VF_MASK_SCALE, VF_SH_SCALE); break; ++ case 'c': USE_BITS (VF_MASK_BCOND, VF_SH_BCOND); break; ++ case 'e': USE_BITS (VF_MASK_MCOND, VF_SH_MCOND); break; ++ ++ case 'i': USE_BITS (VF_MASK_WRAP, VF_SH_WRAP); break; ++ ++ case 'q': USE_BITS (VF_MASK_VCD, VF_SH_VCD); break; ++ case 'r': USE_BITS (VF_MASK_VCS, VF_SH_VCS); break; ++ ++ case 'u': USE_BITS (VF_MASK_HFLOAT, VF_SH_HFLOAT); break; ++ ++ case 'w': USE_BITS (VF_MASK_ROT, VF_SH_ROT); break; ++ case 'z': USE_BITS (VF_MASK_RWB, VF_SH_RWB); break; ++ ++ case '0': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '1': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '2': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '3': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '4': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '5': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '6': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ case '7': USE_BITS (VF_MASK_PFX, VF_SH_PFX); break; ++ ++ default: ++ as_bad (_("internal: bad mips opcode (unknown extension operand type `?%c'): %s %s"), ++ c, opc->name, opc->args); ++ return 0; ++ ++ } ++ break; ++ + 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; +@@ -10585,7 +11124,7 @@ + char c = 0; + struct mips_opcode *insn; + char *argsStart; +- unsigned int regno; ++ unsigned int regno = 0; + unsigned int lastregno; + unsigned int destregno = 0; + unsigned int lastpos = 0; +@@ -10598,6 +11137,9 @@ + unsigned int rtype; + char *dot; + long end; ++ unsigned int vdregno = 0xffff; ++ char vdregt = 0; ++ char vdregl = 0; + + insn_error = NULL; + +@@ -11683,6 +12225,1151 @@ + case 'y': /* ALNV.PS source register. */ + gas_assert (mips_opts.micromips); + goto do_reg; ++ ++ /* VFPU fields */ ++ case '?': ++ switch (*++args) ++ { ++ case '[': ++ case ']': ++ if (*s++ == *args) ++ continue; ++ break; ++ ++ case 'y': /* immediate separator */ ++ ++args; ++ vimm_expr[*args - '0'] = imm_expr; ++ voffset_expr[*args - '0'] = offset_expr; ++ ++ imm_expr.X_op = O_absent; ++ offset_expr.X_op = O_absent; ++ imm_reloc[0] = BFD_RELOC_UNUSED; ++ imm_reloc[1] = BFD_RELOC_UNUSED; ++ imm_reloc[2] = BFD_RELOC_UNUSED; ++ offset_reloc[0] = BFD_RELOC_UNUSED; ++ offset_reloc[1] = BFD_RELOC_UNUSED; ++ offset_reloc[2] = BFD_RELOC_UNUSED; ++ ++ continue; ++ ++ case 'o': /* 16 bit offset */ ++ /* Check whether there is only a single bracketed expression ++ left. If so, it must be the base register and the ++ constant must be zero. */ ++ if (*s == '(' && strchr (s + 1, '(') == 0) ++ { ++ offset_expr.X_op = O_constant; ++ offset_expr.X_add_number = 0; ++ continue; ++ } ++ ++ /* If this value won't fit into a 16 bit offset, then go ++ find a macro that will generate the 32 bit offset ++ code pattern. */ ++ if (my_getSmallExpression (&offset_expr, offset_reloc, s) == 0 ++ && (offset_expr.X_op != O_constant ++ || offset_expr.X_add_number >= 0x8000 ++ || offset_expr.X_add_number < -0x8000)) ++ break; ++ ++ s = expr_end; ++ continue; ++ ++ case 's': /* VFPU source register */ ++ case 't': /* VFPU target register */ ++ case 'd': /* VFPU destination register */ ++ case 'v': /* VFPU destination register */ ++ case 'x': /* VFPU destination register */ ++ case 'm': /* VFPU target regsiter (load/store) */ ++ case 'n': /* VFPU target regsiter (load/store) */ ++ { ++ int dtype_err = 0; ++ int dnum_err = 0; ++ int dlen = 0; ++ char dtype = s[0]; ++ char regtype = *(args + 1); ++ ++ int mtx = 0; ++ int idx = 0; ++ int rxc = 0; ++ int fsl = 0; ++ int vidx = 0; ++ int vfsl = 0; ++ ++ if (ISDIGIT (s[1])) ++ { ++ int num = 0; ++ s++; ++ do ++ { ++ num *= 10; ++ num += *s - '0'; ++ dlen++; ++ s++; ++ } ++ while (ISDIGIT (*s)); ++ ++ if ((s[0] == '.') ++ && (s[1] == 's' || s[1] == 'p' ++ || s[1] == 't' || s[1] == 'q')) ++ s += 2; ++ ++ if (ISUPPER(dtype)) ++ dtype -= 'A' - 'a'; ++ ++ if (dtype == '$') ++ { ++ regno = num; ++ if (regno > VF_MAX_MR) ++ as_bad (_("Invalid VFPU register number (%d)"), ++ regno); ++ ++ idx = (num >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; ++ vfsl = (num >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; ++ switch (regtype) ++ { ++ case '0': /* single word */ ++ break; ++ case '1': /* pare word */ ++ dnum_err = (vfsl & 0x1); ++ break; ++ case '2': /* triple word */ ++ dnum_err = (vfsl > 1); ++ break; ++ case '3': /* quad word */ ++ dnum_err = (vfsl > 0); ++ break; ++ case '5': /* 2x2 word */ ++ dnum_err = (vfsl & 0x1) || (idx & 0x1); ++ break; ++ case '6': /* 3x3 word */ ++ dnum_err = (vfsl > 1) || (idx > 1); ++ break; ++ case '7': /* 4x4 word */ ++ dnum_err = (vfsl > 0) || (idx > 0); ++ break; ++ } ++ ++ if (dnum_err) ++ as_bad (_("Improper VFPU register number (%d)"), ++ regno); ++ ++ } ++ else if ((dlen == 3) ++ && ((dtype == 's') ++ || (dtype == 'c') || (dtype == 'r') ++ || (dtype == 'm') || (dtype == 'e'))) ++ { ++ mtx = num / 100; ++ if ((dtype == 'r') || (dtype == 'e')) ++ { ++ vfsl = (num / 10) % 10; ++ vidx = num % 10; ++ rxc = 1; ++ } ++ else ++ { ++ vidx = (num / 10) % 10; ++ vfsl = num % 10; ++ rxc = 0; ++ } ++ ++ switch (regtype) ++ { ++ case '0': /* single word */ ++ idx = vidx; ++ fsl = vfsl; ++ dtype_err = (dtype != 's'); ++ break; ++ case '1': /* pare word */ ++ idx = vidx; ++ fsl = (vfsl & 0x2) | rxc; ++ dnum_err = (vfsl & 0x1); ++ dtype_err = (dtype != 'c') && (dtype != 'r'); ++ break; ++ case '2': /* triple word */ ++ idx = vidx; ++ fsl = ((vfsl & 0x1) << 1) | rxc; ++ dnum_err = (vfsl > 1); ++ dtype_err = (dtype != 'c') && (dtype != 'r'); ++ break; ++ case '3': /* quad word */ ++ idx = vidx; ++ fsl = rxc; ++ dnum_err = (vfsl > 0); ++ dtype_err = (dtype != 'c') && (dtype != 'r'); ++ break; ++ case '5': /* 2x2 word */ ++ idx = vidx & 0x2; ++ fsl = (vfsl & 0x2) | rxc; ++ dnum_err = (vfsl & 0x1) || (vidx & 0x1); ++ dtype_err = (dtype != 'm') && (dtype != 'e'); ++ break; ++ case '6': /* 3x3 word */ ++ idx = vidx & 0x1; ++ fsl = ((vfsl & 0x1) << 1) | rxc; ++ dnum_err = (vfsl > 1) || (vidx > 1); ++ dtype_err = (dtype != 'm') && (dtype != 'e'); ++ break; ++ case '7': /* 4x4 word */ ++ idx = 0; ++ fsl = rxc; ++ dnum_err = (vfsl > 0) || (vidx > 0); ++ dtype_err = (dtype != 'm') && (dtype != 'e'); ++ break; ++ } ++ ++ if (dtype_err) ++ as_bad (_("Improper VFPU register prefix '%c'"), ++ dtype); ++ if (dnum_err) ++ as_bad (_("Improper VFPU register number (%03d)"), ++ num); ++ ++ if (mtx > VF_MAX_MR_MTX) ++ as_bad (_("VFPU matrix range over %d"), mtx); ++ if (vidx > VF_MAX_MR_IDX) ++ as_bad (_("VFPU index range over %d"), idx); ++ if (vfsl > VF_MAX_MR_FSL) ++ as_bad (_("VFPU field select range over %d"), fsl); ++ ++ regno = ((fsl & VF_MASK_MR_FSL) << VF_SH_MR_FSL) ++ | ((mtx & VF_MASK_MR_MTX) << VF_SH_MR_MTX) ++ | ((idx & VF_MASK_MR_IDX) << VF_SH_MR_IDX); ++ } ++ else ++ { ++ as_bad (_("Improper VFPU register prefix '%c'"), ++ dtype); ++ } ++ } ++ else ++ { ++ as_bad (_("bad operand %s"), s); ++ } ++ ++ if ((*args == 'v') || (*args == 'x')) ++ { ++ vdregno = regno; ++ vdregt = regtype; ++ vdregl = (*args == 'v'); ++ } ++ else if (vdregno <= VF_MAX_MR) ++ { ++ static unsigned short used_vreg[8][16] = { ++ { 0x0001, 0x0010, 0x0100, 0x1000, ++ 0x0002, 0x0020, 0x0200, 0x2000, ++ 0x0004, 0x0040, 0x0400, 0x4000, ++ 0x0008, 0x0080, 0x0800, 0x8000 }, ++ { 0x0003, 0x0030, 0x0300, 0x3000, ++ 0x0011, 0x0022, 0x0044, 0x0088, ++ 0x000c, 0x00c0, 0x0c00, 0xc000, ++ 0x1100, 0x2200, 0x4400, 0x8800 }, ++ { 0x0007, 0x0070, 0x0700, 0x7000, ++ 0x0111, 0x0222, 0x0444, 0x0888, ++ 0x000e, 0x00e0, 0x0e00, 0xe000, ++ 0x1110, 0x2220, 0x4440, 0x8880 }, ++ { 0x000f, 0x00f0, 0x0f00, 0xf000, ++ 0x1111, 0x2222, 0x4444, 0x8888, ++ 0x000f, 0x00f0, 0x0f00, 0xf000, ++ 0x1111, 0x2222, 0x4444, 0x8888 }, ++ { 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000, ++ 0x0000, 0x0000, 0x0000, 0x0000 }, ++ { 0x0033, 0x0033, 0x3300, 0x3300, ++ 0x0033, 0x0033, 0x00cc, 0x00cc, ++ 0x00cc, 0x00cc, 0xcc00, 0xcc00, ++ 0x3300, 0x3300, 0xcc00, 0xcc00 }, ++ { 0x0777, 0x7770, 0x0777, 0x7770, ++ 0x0777, 0x0eee, 0x0777, 0x0eee, ++ 0x0eee, 0xeee0, 0x0eee, 0xeee0, ++ 0x7770, 0xeee0, 0x7770, 0xeee0 }, ++ { 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff, ++ 0xffff, 0xffff, 0xffff, 0xffff }, ++ }; ++ int dmtx, smtx; ++ int dfsl, sfsl; ++ int didx, sidx; ++ int drxc, srxc; ++ ++ dmtx = (vdregno >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; ++ smtx = (regno >> VF_SH_MR_MTX) & VF_MASK_MR_MTX; ++ ++ if (dmtx == smtx) ++ { ++ unsigned short dused, sused; ++ int dtype2, stype; ++ ++ dfsl = (vdregno >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; ++ didx = (vdregno >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; ++ drxc = (vdregno >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ sfsl = (regno >> VF_SH_MR_FSL) & VF_MASK_MR_FSL; ++ sidx = (regno >> VF_SH_MR_IDX) & VF_MASK_MR_IDX; ++ srxc = (regno >> VF_SH_MR_RXC) & VF_MASK_MR_RXC; ++ ++ dtype2 = vdregt - '0'; ++ stype = regtype - '0'; ++ dused = used_vreg[dtype2][(dfsl << 2) + didx]; ++ sused = used_vreg[stype][(sfsl << 2) + sidx]; ++ ++ if ((dused & sused) ++ && (vdregl || (dused ^ sused) || (drxc != srxc))) ++ { ++ int dvfsl; ++ dvfsl = (vdregno >> VF_SH_MR_VFSL) & VF_MASK_MR_VFSL; ++ switch (vdregt) ++ { ++ case '1': ++ dvfsl <<= 1; ++ case '2': ++ case '3': ++ if (drxc) ++ as_bad (_("VFPU register conflict(R%d%d%d)"), ++ dmtx, dvfsl, didx); ++ else ++ as_bad (_("VFPU register conflict(C%d%d%d)"), ++ dmtx, didx, dvfsl); ++ break; ++ case '5': ++ dvfsl <<= 1; ++ case '6': ++ case '7': ++ if (drxc) ++ as_bad (_("VFPU register conflict(E%d%d%d)"), ++ dmtx, dvfsl, didx); ++ else ++ as_bad (_("VFPU register conflict(M%d%d%d)"), ++ dmtx, didx, dvfsl); ++ break; ++ } ++ } ++ } ++ } ++ ++ switch (*args++) ++ { ++ case 's': ++ if ( ++ (ip->insn_opcode ++ & VFPU_MASK_RPT_MMUL) == VFPU_INST_RPT_MMUL) ++ { ++ if (regno & (VF_MASK_MR_RXC << VF_SH_MR_RXC)) ++ regno &= ~(VF_MASK_MR_RXC << VF_SH_MR_RXC); ++ else ++ regno |= (VF_MASK_MR_RXC << VF_SH_MR_RXC); ++ } ++ ip->insn_opcode |= (regno & VF_MASK_VS) << VF_SH_VS; ++ break; ++ case 't': ++ ip->insn_opcode |= (regno & VF_MASK_VT) << VF_SH_VT; ++ break; ++ case 'd': ++ case 'v': ++ case 'x': ++ ip->insn_opcode |= (regno & VF_MASK_VD) << VF_SH_VD; ++ break; ++ case 'm': ++ { ++ int vmregL = (regno >> 0) & VF_MASK_VML; ++ int vmregH = (regno >> 5) & VF_MASK_VMH; ++ ip->insn_opcode |= (vmregL << VF_SH_VML) ++ | (vmregH << VF_SH_VMH); ++ } ++ break; ++ case 'n': ++ { ++ int vmregL = (regno >> 0) & VF_MASK_VNL; ++ int vmregH = (regno >> 5) & VF_MASK_VNH; ++ ip->insn_opcode |= (vmregL << VF_SH_VNL) ++ | (vmregH << VF_SH_VNH); ++ } ++ break; ++ } ++ args++; ++ ++ /* now check for vfpu prefixes if necessary */ ++ if (*s == '[') ++ { ++ char *prefix_out = NULL; ++ bfd_boolean *prefix_bool = NULL; ++ char *prefix_type = NULL; ++ int num_args = 0; ++ char *ob = ++s; ++ bfd_boolean has_w = FALSE; ++ bfd_boolean has_z = FALSE; ++ bfd_boolean has_y = FALSE; ++ bfd_boolean has_operator = FALSE; ++ bfd_boolean has_saturater = FALSE; ++ ++ switch (*args) ++ { ++ case 'w': /* only swizzle */ ++ case 's': /* source prefix */ ++ prefix_bool = &vfpu_sprefix; ++ prefix_out = vfpu_sprefix_str; ++ prefix_type = "source"; ++ break; ++ case 't': /* target prefix */ ++ prefix_bool = &vfpu_tprefix; ++ prefix_out = vfpu_tprefix_str; ++ prefix_type = "target"; ++ break; ++ case 'm': /* only write mask */ ++ case 'd': /* destination prefix */ ++ prefix_bool = &vfpu_dprefix; ++ prefix_out = vfpu_dprefix_str; ++ prefix_type = "destination"; ++ break; ++ case 'y': /* inhibit */ ++ prefix_bool = NULL; ++ prefix_type = "source"; ++ break; ++ case 'x': /* inhibit */ ++ prefix_bool = NULL; ++ prefix_type = "target"; ++ break; ++ case 'z': /* inhibit */ ++ prefix_bool = NULL; ++ prefix_type = "destination"; ++ break; ++ } ++ ++ for ( ; *s != '\0' && *s != ']'; s++) ++ { ++ switch (*s) ++ { ++ case ',': ++ /* count no. of params for syntax check */ ++ num_args++; ++ break; ++ case ' ': ++ case '\t': ++ break; ++ case 'm': ++ case 'M': ++ case 'x': ++ case 'X': ++ break; ++ case 'y': ++ case 'Y': ++ has_y = TRUE; ++ break; ++ case 'z': ++ case 'Z': ++ has_z = TRUE; ++ break; ++ case 'w': ++ case 'W': ++ has_w = TRUE; ++ break; ++ default: ++ if (*args == 'w') ++ has_operator = TRUE; ++ if (*args == 'm') ++ has_saturater = TRUE; ++ } ++ } ++ ++ if (*s == ']') ++ { ++ if (prefix_bool) ++ { ++ *prefix_bool = TRUE; ++ strncpy (prefix_out, ob, s - ob); ++ prefix_out[s - ob] = '\0'; ++ s++; ++ } ++ else ++ { ++ as_bad (_("%s cannot use %s prefix"), ++ insn->name, prefix_type); ++ s++; ++ continue; ++ } ++ } ++ else ++ { ++ as_bad (_("parse error (%s)"), ob - 1); ++ return; ++ } ++ ++ if (num_args != regtype - '0') ++ { ++ as_bad (_("%s prefix specification requires %d parameters - [%s]"), ++ prefix_type, regtype - '0' + 1, ++ prefix_out); ++ } ++ else ++ { ++ int i = 8 - ((3 - num_args) * 2); ++ char dummy_d[] = " m,m,m,m"; ++ char dummy_st[] = " x,y,z,w"; ++ ++ if (*args == 'd' || *args == 'm') ++ { ++ strcat (prefix_out, dummy_d + i); ++ if (has_saturater) ++ { ++ as_bad (_("%s is restricted to mask destination prefixes only"), ++ insn->name); ++ } ++ } ++ else ++ { ++ strcat (prefix_out, dummy_st + i); ++ if (has_operator) ++ { ++ as_bad (_("%s is restricted to swizzle %s prefixes only"), ++ insn->name, prefix_type); ++ } ++ /* semantic check, w can't be specified for ++ s, p, or t instructions same goes for ++ z for p and s, and y for scalars */ ++ if ((has_y && num_args == 0) ++ || (has_z && num_args < 2) ++ || (has_w && num_args < 3)) ++ { ++ as_bad (_("%s swizzle operand is out of range in [%s]"), ++ prefix_type, prefix_out); ++ } ++ } ++ } ++ } ++ ++ continue; ++ } ++ break; ++ ++ case 'q': /* VFPU destination control register */ ++ case 'r': /* VFPU source control register */ ++ { ++ if ((s[0] == '$') && ISDIGIT (s[1])) ++ { ++ s++; ++ regno = 0; ++ do ++ { ++ regno *= 10; ++ regno += *s - '0'; ++ ++s; ++ } ++ while (ISDIGIT (*s)); ++ ++ if ((regno < VF_MIN_CR) || (regno > VF_MAX_CR)) ++ as_bad (_("Invalid VFPU control register number (%d)"), ++ regno); ++ ++ else if (!((regno >= VF_MIN_VCR) && (regno <= VF_MAX_VCR))) ++ as_bad (_("Improper VFPU control register number (%d)"), ++ regno); ++ ++ switch (*args) ++ { ++ case 'q': ++ ip->insn_opcode |= (regno & VF_MASK_VCD) << VF_SH_VCD; ++ break; ++ case 'r': ++ ip->insn_opcode |= (regno & VF_MASK_VCS) << VF_SH_VCS; ++ break; ++ } ++ } ++ else ++ { ++ as_bad (_("Invalid VFPU control register name (%s)"), s); ++ } ++ ++ continue; ++ } ++ break; ++ ++ case 'f': /* condition code */ ++ { ++ int cond = 0; ++ if (ISDIGIT (s[0])) ++ { ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ cond = imm_expr.X_add_number; ++ if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC)) ++ as_bad (_("Invalid VFPU condition code (%d)"), cond); ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ } ++ else ++ { ++ static const char * const vfpu_cond_names[] = { ++ "FL", "EQ", "LT", "LE", ++ "TR", "NE", "GE", "GT", ++ "EZ", "EN", "EI", "ES", ++ "NZ", "NN", "NI", "NS" }; ++ for (cond = VF_MIN_CC; cond <= VF_MAX_CC; cond++) ++ { ++ if (strncasecmp(vfpu_cond_names[cond], s, 2) == 0) ++ break; ++ } ++ if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC)) ++ as_bad (_("Invalid VFPU condition code (%s)"), s); ++ ++ s += 2; ++ } ++ ++ args++; ++ if ((cond == 0) || (cond == 4)) ++ { ++ } ++ else if (cond & 0x8) ++ { ++ if (*args - '0' < 1) ++ as_bad (_("Invalid VFPU condition oparetion")); ++ } ++ else ++ { ++ if (*args - '0' < 2) ++ as_bad (_("Invalid VFPU condition oparetion")); ++ } ++ ++ ip->insn_opcode |= (cond & VF_MASK_CC) << VF_SH_CC; ++ continue; ++ } ++ break; ++ ++ case 'a': /* constant code */ ++ { ++ int cst = 0; ++ if (ISDIGIT (s[0])) ++ { ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ cst = imm_expr.X_add_number; ++ if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST)) ++ { ++ as_bad (_("Improper constant code (%d)"), cst); ++ cst &= VF_MASK_CONST; ++ } ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ } ++ else ++ { ++ static const char * const vfpu_const_names[] = { ++ "", "VFPU_HUGE", "VFPU_SQRT2", "VFPU_SQRT1_2", ++ "VFPU_2_SQRTPI", "VFPU_2_PI", "VFPU_1_PI", "VFPU_PI_4", ++ "VFPU_PI_2", "VFPU_PI", "VFPU_E", "VFPU_LOG2E", ++ "VFPU_LOG10E", "VFPU_LN2", "VFPU_LN10", "VFPU_2PI", ++ "VFPU_PI_6", "VFPU_LOG10TWO", "VFPU_LOG2TEN", ++ "VFPU_SQRT3_2"}; ++ for (cst = VF_MIN_CONST; cst <= VF_MAX_CONST; cst++) ++ { ++ if (strcasecmp(vfpu_const_names[cst], s) == 0) ++ break; ++ } ++ if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST)) ++ as_bad (_("Invalid constant code (%s)"), s); ++ else ++ s += strlen(vfpu_const_names[cst]); ++ } ++ ++ ip->insn_opcode |= cst << VF_SH_CONST; ++ } ++ continue; ++ ++ case 'b': /* scale exponent */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_SCALE) ++ { ++ as_bad (_("Improper scale (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_SCALE; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_SCALE; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'c': /* branch condition code bit */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_BCOND) ++ { ++ as_bad (_("Improper condition bit (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_BCOND; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_BCOND; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'e': /* move condition code bit */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_MCOND) ++ { ++ as_bad (_("Improper condition bit (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_MCOND; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_MCOND; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'i': /* wrap exponent */ ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_WRAP) ++ { ++ as_bad (_("Improper wrap (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_WRAP; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_WRAP; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ ++ case 'w': /* rotation code */ ++ if (s[0] == '[') ++ { ++ char *rot_str = s; ++ int rot_idx = 0; ++ int rot_neg = 0; ++ int rot_sin = 3; ++ int rot_cos = 3; ++ int rot_err = 0; ++ int rot_n; ++ int rot_neg_n = 0; ++ int rot_sin_n = 0; ++ int rot_cos_n = 0; ++ int rot_code; ++ ++ if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_PAIR) ++ rot_n = 2; ++ else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_TRIPLE) ++ rot_n = 3; ++ else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_QUAD) ++ rot_n = 4; ++ else ++ rot_n = 0; ++ ++ s++; ++ while ((s[0] != ']') && (s[0] != '\0')) ++ { ++ if (s[0] == '-') ++ { ++ if ((s[1] != 's') && (s[1] != 'S')) ++ { ++ rot_err = 1; ++ break; ++ } ++ rot_neg = 1; ++ rot_neg_n++; ++ s++; ++ } ++ ++ if (s[0] == ',') ++ rot_idx++; ++ else if ((s[0] == 'c') || (s[0] == 'C')) ++ { ++ rot_cos = rot_idx; ++ rot_cos_n++; ++ } ++ else if ((s[0] == 's') || (s[0] == 'S')) ++ { ++ rot_sin = rot_idx; ++ rot_sin_n++; ++ } ++ else if (ISSPACE(s[0]) || (s[0] == '0')) ++ ; ++ else ++ { ++ rot_err = 1; ++ break; ++ } ++ ++ s++; ++ } ++ ++ if (s[0] == ']') ++ rot_idx++; ++ else ++ rot_err = 1; ++ s++; ++ ++ if ((rot_sin_n == 0) && (rot_cos_n == 0)) ++ { ++ if (rot_n == 2) ++ rot_sin = 2; ++ else if ((rot_n == 4) || (rot_n == 3)) ++ rot_err = 1; ++ } ++ ++ if (rot_cos_n > 1) ++ rot_err = 1; ++ ++ if (rot_sin_n > 1) ++ { ++ if (((rot_sin_n + rot_cos_n) != rot_n) ++ || ((rot_n == 4) && (rot_cos_n == 0))) ++ rot_err = 1; ++ } ++ ++ if (rot_neg && (rot_neg_n != rot_sin_n)) ++ rot_err = 1; ++ ++ if (rot_sin_n > 1) ++ rot_sin = rot_cos; ++ ++ if (rot_err || (rot_n != rot_idx)) ++ as_bad (_("Invalid rotation code (%s)"), rot_str); ++ ++ rot_code = ((rot_neg & VF_MASK_ROT_NEG) << VF_SH_ROT_NEG) ++ | ((rot_cos & VF_MASK_ROT_COS) << VF_SH_ROT_COS) ++ | ((rot_sin & VF_MASK_ROT_SIN) << VF_SH_ROT_SIN); ++ ip->insn_opcode |= rot_code << VF_SH_ROT; ++ } ++ else ++ { ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_ROT) ++ { ++ as_bad (_("Improper rotation code (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_ROT; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_ROT; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ } ++ continue; ++ ++ case 'u': /* half float */ ++ if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) ++ { ++ my_getExpression (&imm_expr, s); ++ check_absolute_expr (ip, &imm_expr); ++ if ((unsigned long) imm_expr.X_add_number > VF_MAX_HFLOAT) ++ { ++ as_bad (_("Improper half floating point constant: (%lu)"), ++ (unsigned long) imm_expr.X_add_number); ++ imm_expr.X_add_number &= VF_MASK_HFLOAT; ++ } ++ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_HFLOAT; ++ imm_expr.X_op = O_absent; ++ s = expr_end; ++ continue; ++ } ++ else ++ { ++ char *save_in; ++ char *err; ++ int len; ++ unsigned char temp[8]; ++ unsigned int f32, f16; ++ int exponent32, exponent16; ++ int fraction32, fraction16; ++ int sign; ++ char f16_str[8]; ++ ++ save_in = input_line_pointer; ++ input_line_pointer = s; ++ err = md_atof ('f', (char *) temp, &len); ++ s = input_line_pointer; ++ input_line_pointer = save_in; ++ if (err != NULL && *err != '\0') ++ { ++ as_bad (_("Bad half floating point constant: %s"), err); ++ memset (temp, '\0', sizeof temp); ++ } ++ ++ if (! target_big_endian) ++ f32 = bfd_getl32 (temp); ++ else ++ f32 = bfd_getb32 (temp); ++ ++ sign = (f32 >> VF_SH_F32_SIGN) & VF_MASK_F32_SIGN; ++ exponent32 = (f32 >> VF_SH_F32_EXP) & VF_MASK_F32_EXP; ++ fraction32 = (f32 >> VF_SH_F32_FRA) & VF_MASK_F32_FRA; ++ exponent16 = exponent32 ++ - VF_BIAS_F32_EXP + VF_BIAS_F16_EXP; ++ ++ if (exponent16 < VF_MIN_F16_EXP) ++ { ++ if ((exponent32 == VF_MIN_F32_EXP) ++ && (fraction32 == 0)) ++ { // zero ++ exponent16 = VF_MIN_F16_EXP; ++ fraction16 = 0; ++ } ++ else ++ { // underflow ++ float* p; ++ p = (float*) &f32; ++ as_warn (_("Half floating point underflow: %g"), ++ *p); ++ exponent16 = VF_MIN_F16_EXP; ++ fraction16 = 0; ++ } ++ } ++ else if (exponent16 > VF_MAX_F16_EXP) ++ { ++ if (exponent32 != VF_MAX_F32_EXP) ++ { // overflow ++ float* p; ++ p = (float*) &f32; ++ as_warn (_("Half floating point overflow: %g"), ++ *p); ++ exponent16 = VF_MAX_F16_EXP; ++ fraction16 = 0; ++ } ++ else ++ { ++ if (fraction32 == 0) ++ { // infinity ++ exponent16 = VF_MAX_F16_EXP; ++ fraction16 = 0; ++ } ++ else ++ { // NaN ++ exponent16 = VF_MAX_F16_EXP; ++ fraction16 = 1; ++ } ++ } ++ } ++ else ++ { ++ fraction16 = (f32 >> (VF_SH_F32_EXP - VF_SH_F16_EXP)) ++ & VF_MASK_F16_FRA; ++ } ++ ++ f16 = (sign << VF_SH_F16_SIGN) ++ | (exponent16 << VF_SH_F16_EXP) ++ | (fraction16 << VF_SH_F16_FRA); ++ ip->insn_opcode |= (f16 & VF_MASK_HFLOAT) << VF_SH_HFLOAT; ++ ++ sprintf(f16_str, "0x%04x", f16); ++ my_getExpression (&imm_expr, f16_str); ++ ++ continue; ++ } ++ break; ++ ++ case 'z': /* read/write access code */ ++ { ++ int rwb = 0; ++ ++ if (strncasecmp (s, "WT", 2) == 0) ++ rwb = 0x0; ++ else if (strncasecmp (s, "WB", 2) == 0) ++ rwb = 0x1; ++ else ++ as_bad (_("Invalid memory access type (%s)"), s); ++ ++ s += 2; ++ ip->insn_opcode |= (rwb & VF_MASK_RWB) << VF_SH_RWB; ++ ++ continue; ++ } ++ ++ case '0': /* source or target prefix code (X) */ ++ case '1': /* source or target prefix code (Y) */ ++ case '2': /* source or target prefix code (Z) */ ++ case '3': /* source or target prefix code (W) */ ++ { ++ int operand; ++ int shift; ++ ++ int pfx_neg = 0; ++ int pfx_cst = 0; ++ int pfx_abs = 0; ++ int pfx_swz = 0; ++ int pfx_err = 0; ++ int cst = 0; ++ char *pfx_str = s; ++ ++ if (s[0] == '-') ++ { // sign code ++ pfx_neg = 1; ++ s++; ++ } ++ ++ if (ISDIGIT (s[0])) ++ { // constant ++ pfx_cst = 1; ++ ++ if (s[0] == '0') ++ cst = 0; ++ else if (s[0] == '1') ++ { ++ if (s[1] == '/') ++ { ++ s += 2; ++ if (s[0] == '2') ++ cst = 3; ++ else if (s[0] == '3') ++ cst = 5; ++ else if (s[0] == '4') ++ cst = 6; ++ else if (s[0] == '6') ++ cst = 7; ++ else ++ pfx_err = 1; ++ } ++ else ++ { ++ cst = 1; ++ } ++ } ++ else if (s[0] == '2') ++ cst = 2; ++ else if (s[0] == '3') ++ cst = 4; ++ else ++ pfx_err = 1; ++ ++ pfx_abs = (cst >> 2) & 0x1; ++ pfx_swz = (cst >> 0) & 0x3; ++ s++; ++ } ++ else ++ { // variable ++ ++ if (s[0] == '|') ++ { // abs ++ pfx_abs = 1; ++ s++; ++ } ++ ++ if ((s[0] == 'X') || (s[0] == 'x')) ++ { ++ pfx_swz = 0; ++ s++; ++ } ++ else if ((s[0] == 'Y') || (s[0] == 'y')) ++ { ++ pfx_swz = 1; ++ s++; ++ } ++ else if ((s[0] == 'Z') || (s[0] == 'z')) ++ { ++ pfx_swz = 2; ++ s++; ++ } ++ else if ((s[0] == 'W') || (s[0] == 'w')) ++ { ++ pfx_swz = 3; ++ s++; ++ } ++ else if ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]) ++ || (s[0] == '|')) ++ { ++ pfx_swz = *args - '0'; ++ } ++ else ++ pfx_err = 1; ++ ++ if (pfx_err == 0) ++ { ++ if (s[0] == '|') ++ { ++ s++; ++ if (pfx_abs == 0) ++ pfx_err = 1; ++ } ++ else ++ { ++ if (pfx_abs == 1) ++ pfx_err = 1; ++ } ++ } ++ } ++ ++ if (! ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]))) ++ pfx_err = 1; ++ ++ if (pfx_err) ++ as_bad (_("Invalid prefix format (%s)"), pfx_str); ++ ++ shift = *args - '0'; ++ ++ operand = (pfx_neg << (VF_SH_PFX_NEG + shift)) ++ | (pfx_cst << (VF_SH_PFX_CST + shift)) ++ | (pfx_abs << (VF_SH_PFX_ABS + shift)) ++ | (pfx_swz << (VF_SH_PFX_SWZ + shift * 2)); ++ ++ ip->insn_opcode |= operand; ++ continue; ++ } ++ ++ case '4': /* destination prefix code (X) */ ++ case '5': /* destination prefix code (Y) */ ++ case '6': /* destination prefix code (Z) */ ++ case '7': /* destination prefix code (W) */ ++ { ++ int operand; ++ int shift; ++ static const char order[] = "xyzwXYZW"; ++ ++ int pfx_msk = 0; ++ int pfx_sat = 0; ++ char *pfx_str = s; ++ ++ if (s[0] == '[') ++ s++; ++ if (s[0] == '-') /* -1:1, skip the minus symbol */ ++ s++; ++ ++ if ((s[0] == 'm') || (s[0] == 'M')) ++ { ++ pfx_msk = 1; ++ s++; ++ } ++ else if (s[0] == '0') /* 0:1 */ ++ { ++ pfx_sat = 1; ++ s++; ++ } ++ else if (s[0] == '1') /* -1:1 or -1:+1 */ ++ { ++ pfx_sat = 3; ++ s++; ++ } ++ else if ((s[0] == order[(*args) - '4']) ++ || (s[0] == order[(*args) - '4' + 4])) ++ { ++ pfx_sat = 0; ++ s++; ++ } ++ ++ if (s[0] == ':') /* skip the :1 or :+1 part of the expression */ ++ { ++ s++; ++ if (s[0] == '+') ++ s++; ++ if (s[0] == '1') ++ s++; ++ } ++ if (s[0] == ']') ++ s++; ++ ++ if (! ((s[0] == ',') || IS_SPACE_OR_NUL (s[0]))) ++ as_bad (_("Invalid prefix format (%s)"), pfx_str); ++ ++ shift = *args - '4'; ++ operand = (pfx_msk << (VF_SH_PFX_MSK + shift)) ++ | (pfx_sat << (VF_SH_PFX_SAT + shift * 2)); ++ ++ ip->insn_opcode |= operand; ++ continue; ++ } ++ } ++ break; ++ + case 'x': /* Ignore register name. */ + case 'U': /* Destination register (CLO/CLZ). */ + case 'g': /* Coprocessor destination register. */ +@@ -11877,6 +13564,7 @@ + { + if ((regno & 1) != 0 + && HAVE_32BIT_FPRS ++ && ! CPU_IS_ALLEGREX (mips_opts.arch) + && !mips_oddfpreg_ok (ip->insn_mo, argnum)) + as_warn (_("Float register should be even, was %d"), + regno); +@@ -18227,7 +19915,7 @@ + | RELAX_DELAY_SLOT_SIZE_SECOND); + msg = macro_warning (s); + if (msg != NULL) +- as_warn_where (fragp->fr_file, fragp->fr_line, msg); ++ as_warn_where (fragp->fr_file, fragp->fr_line, "%s", msg); + subtype &= ~s; + } + +@@ -18241,7 +19929,7 @@ + & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT)); + msg = macro_warning (s); + if (msg != NULL) +- as_warn_where (fragp->fr_file, fragp->fr_line, msg); ++ as_warn_where (fragp->fr_file, fragp->fr_line, "%s", msg); + subtype &= ~s; + } + +@@ -18913,6 +20601,8 @@ + + /* MIPS II */ + { "r6000", 0, ISA_MIPS2, CPU_R6000 }, ++ /* Sony PSP "Allegrex" CPU core */ ++ { "allegrex", 0, ISA_MIPS2, CPU_ALLEGREX }, + + /* MIPS III */ + { "r4000", 0, ISA_MIPS3, CPU_R4000 }, +diff -burN orig.binutils-2.22/gas/configure binutils-2.22/gas/configure +--- orig.binutils-2.22/gas/configure 2011-05-18 11:41:14.000000000 +0200 ++++ binutils-2.22/gas/configure 2012-01-04 16:18:36.289215219 +0100 +@@ -12043,6 +12043,9 @@ + mips64vr | mips64vrel) + mips_cpu=vr4100 + ;; ++ mipsallegrex | mipsallegrexel) ++ mips_cpu=allegrex ++ ;; + mipsisa32r2* | mipsisa64r2*) + mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'` + ;; +diff -burN orig.binutils-2.22/gas/configure.in binutils-2.22/gas/configure.in +--- orig.binutils-2.22/gas/configure.in 2011-05-18 11:41:14.000000000 +0200 ++++ binutils-2.22/gas/configure.in 2012-01-04 16:18:36.289215219 +0100 +@@ -213,6 +213,9 @@ + mips64vr | mips64vrel) + mips_cpu=vr4100 + ;; ++ mipsallegrex | mipsallegrexel) ++ mips_cpu=allegrex ++ ;; + mipsisa32r2* | mipsisa64r2*) + changequote(,)dnl + mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..r2//' -e 's/el$//'` +diff -burN orig.binutils-2.22/gas/testsuite/gas/mips/mips.exp binutils-2.22/gas/testsuite/gas/mips/mips.exp +--- orig.binutils-2.22/gas/testsuite/gas/mips/mips.exp 2011-11-21 10:29:32.000000000 +0100 ++++ binutils-2.22/gas/testsuite/gas/mips/mips.exp 2012-01-04 16:18:34.940230631 +0100 +@@ -409,6 +409,9 @@ + mips_arch_create sb1 64 mips64 { mips3d } \ + { -march=sb1 -mtune=sb1 } { -mmips:sb1 } \ + { mipsisa64sb1-*-* mipsisa64sb1el-*-* } ++mips_arch_create allegrex 32 mips2 { ror } \ ++ { -march=allegrex -mtune=allegrex } { -mmips:allegrex } \ ++ { mipsallegrex-*-* mipsallegrexel-*-* } + mips_arch_create octeon 64 mips64r2 {} \ + { -march=octeon -mtune=octeon } { -mmips:octeon } \ + { mips64octeon*-*-* } +diff -burN orig.binutils-2.22/include/elf/common.h binutils-2.22/include/elf/common.h +--- orig.binutils-2.22/include/elf/common.h 2011-07-22 22:22:36.000000000 +0200 ++++ binutils-2.22/include/elf/common.h 2012-01-04 16:18:36.333214716 +0100 +@@ -96,6 +96,7 @@ + #define ET_HIOS 0xFEFF /* Operating system-specific */ + #define ET_LOPROC 0xFF00 /* Processor-specific */ + #define ET_HIPROC 0xFFFF /* Processor-specific */ ++#define ET_PSPEXEC 0xFFA0 /* Sony PSP executable file */ + + /* Values for e_machine, which identifies the architecture. These numbers + are officially assigned by registry@sco.com. See below for a list of +diff -burN orig.binutils-2.22/include/elf/mips.h binutils-2.22/include/elf/mips.h +--- orig.binutils-2.22/include/elf/mips.h 2011-07-24 16:20:12.000000000 +0200 ++++ binutils-2.22/include/elf/mips.h 2012-01-04 16:32:22.726926151 +0100 +@@ -265,6 +265,7 @@ + #define E_MIPS_MACH_5400 0x00910000 + #define E_MIPS_MACH_5500 0x00980000 + #define E_MIPS_MACH_9000 0x00990000 ++#define E_MIPS_MACH_ALLEGREX 0x00A20000 + #define E_MIPS_MACH_LS2E 0x00A00000 + #define E_MIPS_MACH_LS2F 0x00A10000 + #define E_MIPS_MACH_LS3A 0x00A20000 +diff -burN orig.binutils-2.22/include/opcode/mips.h binutils-2.22/include/opcode/mips.h +--- orig.binutils-2.22/include/opcode/mips.h 2011-08-09 17:20:03.000000000 +0200 ++++ binutils-2.22/include/opcode/mips.h 2012-01-04 16:18:36.338214659 +0100 +@@ -216,6 +216,228 @@ + #define MDMX_FMTSEL_VEC_QH 0x15 + #define MDMX_FMTSEL_VEC_OB 0x16 + ++#include "vfpu.h" ++ ++#define VF_MASK_VT 0x7f ++#define VF_SH_VT 16 ++#define VF_MASK_VS 0x7f ++#define VF_SH_VS 8 ++#define VF_MASK_VD 0x7f ++#define VF_SH_VD 0 ++#define VF_MASK_VML 0x1f ++#define VF_SH_VML 16 ++#define VF_MASK_VMH 0x3 ++#define VF_SH_VMH 0 ++#define VF_MASK_VNL 0x1f ++#define VF_SH_VNL 16 ++#define VF_MASK_VNH 0x1 ++#define VF_SH_VNH 0 ++#define VF_MASK_OFFSET 0x3fff ++#define VF_SH_OFFSET 2 ++#define VF_MASK_CC 0xf ++#define VF_SH_CC 0 ++#define VF_MASK_CONST 0x1f ++#define VF_SH_CONST 16 ++#define VF_MASK_SCALE 0x1f ++#define VF_SH_SCALE 16 ++#define VF_MASK_BCOND 0x7 ++#define VF_SH_BCOND 18 ++#define VF_MASK_MCOND 0x7 ++#define VF_SH_MCOND 16 ++#define VF_MASK_VCD 0xff ++#define VF_SH_VCD 0 ++#define VF_MASK_VCS 0xff ++#define VF_SH_VCS 8 ++#define VF_MASK_ROT 0x1f ++#define VF_SH_ROT 16 ++#define VF_MASK_WRAP 0xff ++#define VF_SH_WRAP 16 ++#define VF_MASK_TSIGN 0x1 ++#define VF_SH_TSIGN 5 ++#define VF_MASK_BMCOND 0x1f ++#define VF_SH_BMCOND 0 ++#define VF_MASK_HFLOAT 0xffff ++#define VF_SH_HFLOAT 0 ++#define VF_MASK_PFX 0xffffff ++#define VF_SH_PFX 0 ++#define VF_MASK_RWB 0x1 ++#define VF_SH_RWB 1 ++ ++#define VF_MASK_PFX_SWZ 0x3 ++#define VF_SH_PFX_SWZ 0 ++#define VF_MASK_PFX_ABS 0x1 ++#define VF_SH_PFX_ABS 8 ++#define VF_MASK_PFX_CST 0x1 ++#define VF_SH_PFX_CST 12 ++#define VF_MASK_PFX_NEG 0x1 ++#define VF_SH_PFX_NEG 16 ++#define VF_MASK_PFX_SAT 0x3 ++#define VF_SH_PFX_SAT 0 ++#define VF_MASK_PFX_MSK 0x1 ++#define VF_SH_PFX_MSK 8 ++ ++#define VF_MASK_ROT_COS 0x3 ++#define VF_SH_ROT_COS 0 ++#define VF_MASK_ROT_SIN 0x3 ++#define VF_SH_ROT_SIN 2 ++#define VF_MASK_ROT_NEG 0x1 ++#define VF_SH_ROT_NEG 4 ++ ++#define VF_MASK_MR_MTX 0x7 ++#define VF_SH_MR_MTX 2 ++#define VF_MASK_MR_IDX 0x3 ++#define VF_SH_MR_IDX 0 ++#define VF_MASK_MR_FSL 0x3 ++#define VF_SH_MR_FSL 5 ++#define VF_MASK_MR_RXC 0x1 ++#define VF_SH_MR_RXC 5 ++#define VF_MASK_MR_VFSL 0x1 ++#define VF_SH_MR_VFSL 6 ++ ++#define VF_MAX_MR_MTX 7 ++#define VF_MAX_MR_IDX 3 ++#define VF_MAX_MR_FSL 3 ++#define VF_MAX_MR_VIDX 1 ++#define VF_MAX_MR_VFSL 1 ++ ++#define VF_MIN_MR 0 ++#define VF_MAX_MR 127 ++#define VF_MIN_CR 128 ++#define VF_MAX_CR 255 ++#define VF_MIN_VCR 128 ++#define VF_MAX_VCR 143 ++#define VF_MIN_CC 0 ++#define VF_MAX_CC 15 ++#define VF_MIN_CONST 1 ++#define VF_MAX_CONST 19 ++#define VF_MIN_SCALE 0 ++#define VF_MAX_SCALE 31 ++#define VF_MIN_BCOND 0 ++#define VF_MAX_BCOND 5 ++#define VF_MIN_MCOND 0 ++#define VF_MAX_MCOND 6 ++#define VF_MIN_WRAP 0 ++#define VF_MAX_WRAP 255 ++#define VF_MIN_ROT 0 ++#define VF_MAX_ROT 31 ++#define VF_MIN_TSIGN 0 ++#define VF_MAX_TSIGN 1 ++#define VF_MIN_BMCOND 0 ++#define VF_MAX_BMCOND 31 ++#define VF_MIN_HFLOAT 0 ++#define VF_MAX_HFLOAT 0xffff ++ ++#define VF_MASK_F32_SIGN 0x1 ++#define VF_SH_F32_SIGN 31 ++#define VF_MASK_F32_EXP 0xff ++#define VF_SH_F32_EXP 23 ++#define VF_MASK_F32_FRA 0x7fffff ++#define VF_SH_F32_FRA 0 ++#define VF_MASK_F16_SIGN 0x1 ++#define VF_SH_F16_SIGN 15 ++#define VF_MASK_F16_EXP 0x1f ++#define VF_SH_F16_EXP 10 ++#define VF_MASK_F16_FRA 0x3ff ++#define VF_SH_F16_FRA 0 ++ ++#define VF_MIN_F32_EXP 0 ++#define VF_MAX_F32_EXP 255 ++#define VF_BIAS_F32_EXP 127 ++#define VF_MIN_F16_EXP 0 ++#define VF_MAX_F16_EXP 31 ++#define VF_BIAS_F16_EXP 15 ++ ++#define OP_SH_VFPU_DELTA 0 ++#define OP_MASK_VFPU_DELTA 0xfffc ++#define OP_SH_VFPU_IMM3 16 ++#define OP_MASK_VFPU_IMM3 0x7 ++#define OP_SH_VFPU_IMM5 16 ++#define OP_MASK_VFPU_IMM5 0x1f ++#define OP_SH_VFPU_IMM8 16 ++#define OP_MASK_VFPU_IMM8 0xff ++#define OP_SH_VFPU_CC 18 /* Condition code. */ ++#define OP_MASK_VFPU_CC 0x7 ++#define OP_SH_VFPU_CONST 16 ++#define OP_MASK_VFPU_CONST 0x1f ++#define OP_SH_VFPU_COND 0 /* Conditional compare. */ ++#define OP_MASK_VFPU_COND 0xf ++#define OP_SH_VFPU_VMTVC 0 ++#define OP_MASK_VFPU_VMTVC 0xff ++#define OP_SH_VFPU_VMFVC 8 ++#define OP_MASK_VFPU_VMFVC 0xff ++#define OP_SH_VFPU_RWB 1 ++#define OP_MASK_VFPU_RWB 0x1 ++#define OP_SH_VFPU_ROT 16 /* Rotators used in vrot. */ ++#define OP_MASK_VFPU_ROT 0x1f ++#define OP_SH_VFPU_FLOAT16 0 ++#define OP_MASK_VFPU_FLOAT16 0xffff ++ ++/* VFPU registers. */ ++#define OP_SH_VFPU_VD 0 ++#define OP_MASK_VFPU_VD 0x7f ++#define OP_SH_VFPU_VS 8 ++#define OP_MASK_VFPU_VS 0x7f ++#define OP_SH_VFPU_VT 16 ++#define OP_MASK_VFPU_VT 0x7f ++#define OP_SH_VFPU_VT_LO 16 /* Bits 0-4 of vt. */ ++#define OP_MASK_VFPU_VT_LO 0x1f ++#define OP_SH_VFPU_VT_HI 5 /* Right-shifted. */ ++#define OP_MASK_VFPU_VT_HI1 0x1 /* Bit 5 of vt. */ ++#define OP_MASK_VFPU_VT_HI2 0x3 /* Bits 5-6 of vt. */ ++/* Special handling of vs in vmmul instructions. */ ++#define VFPU_OP_VT_VS_VD 0xff800000 ++#define VFPU_OPCODE_VMMUL 0xf0000000 ++ ++/* VFPU condition codes. FL and TR accept no arguments, while any conditions ++ above and including EZ only accept one argument. The rest require two ++ arguments. */ ++enum ++{ ++ VFPU_COND_FL, VFPU_COND_EQ, VFPU_COND_LT, VFPU_COND_LE, ++ VFPU_COND_TR, VFPU_COND_NE, VFPU_COND_GE, VFPU_COND_GT, ++ VFPU_COND_EZ, VFPU_COND_EN, VFPU_COND_EI, VFPU_COND_ES, ++ VFPU_COND_NZ, VFPU_COND_NN, VFPU_COND_NI, VFPU_COND_NS, ++ VFPU_NUM_CONDS ++}; ++ ++/* VFPU prefix instruction operands. The *_SH_* values really specify where ++ the bitfield begins, as VFPU prefix instructions have four operands ++ encoded within the immediate field. */ ++#define VFPU_SH_PFX_NEG 16 ++#define VFPU_MASK_PFX_NEG 0x1 /* Negation. */ ++#define VFPU_SH_PFX_CST 12 ++#define VFPU_MASK_PFX_CST 0x1 /* Constant. */ ++#define VFPU_SH_PFX_ABS_CSTHI 8 ++#define VFPU_MASK_PFX_ABS_CSTHI 0x1 /* Abs/Constant (bit 2). */ ++#define VFPU_SH_PFX_SWZ_CSTLO 0 ++#define VFPU_MASK_PFX_SWZ_CSTLO 0x3 /* Swizzle/Constant (bits 0-1). */ ++#define VFPU_SH_PFX_MASK 8 ++#define VFPU_MASK_PFX_MASK 0x1 /* Mask. */ ++#define VFPU_SH_PFX_SAT 0 ++#define VFPU_MASK_PFX_SAT 0x3 /* Saturation. */ ++ ++/* Special handling of the vrot instructions. */ ++#define VFPU_MASK_OP_SIZE 0x8080 /* Masks the operand size (pair, triple, quad). */ ++#define VFPU_OP_SIZE_PAIR 0x80 ++#define VFPU_OP_SIZE_TRIPLE 0x8000 ++#define VFPU_OP_SIZE_QUAD 0x8080 ++/* Note that these are within the rotators field, and not the full opcode. */ ++#define VFPU_SH_ROT_HI 2 ++#define VFPU_MASK_ROT_HI 0x3 ++#define VFPU_SH_ROT_LO 0 ++#define VFPU_MASK_ROT_LO 0x3 ++#define VFPU_SH_ROT_NEG 4 /* Negation. */ ++#define VFPU_MASK_ROT_NEG 0x1 ++ ++/* VFPU 16-bit floating-point format. */ ++#define VFPU_FLOAT16_EXP_MAX 0x1f ++#define VFPU_SH_FLOAT16_SIGN 15 ++#define VFPU_MASK_FLOAT16_SIGN 0x1 ++#define VFPU_SH_FLOAT16_EXP 10 ++#define VFPU_MASK_FLOAT16_EXP 0x1f ++#define VFPU_SH_FLOAT16_FRAC 0 ++#define VFPU_MASK_FLOAT16_FRAC 0x3ff ++ + /* UDI */ + #define OP_SH_UDI1 6 + #define OP_MASK_UDI1 0x1f +@@ -416,6 +638,29 @@ + Requires that "+A" or "+E" occur first to set position. + Enforces: 32 < (pos+size) <= 64. + ++ Sony Allegrex VFPU instructions: ++ "?o" ++ "?0" - "?3" ++ "?4" - "?7" ++ "?a" ++ "?b" ++ "?c" ++ "?e" ++ "?f" ++ "?i" ++ "?q" ++ "?r" ++ "?u" ++ "?w" ++ "?d" ++ "?m" ++ "?n" ++ "?s" ++ "?t" ++ "?v" ++ "?x" ++ "?z" ++ + Floating point instructions: + "D" 5 bit destination register (OP_*_FD) + "M" 3 bit compare condition code (OP_*_CCC) (only used for mips4 and up) +@@ -750,6 +995,8 @@ + #define INSN_5400 0x01000000 + /* NEC VR5500 instruction. */ + #define INSN_5500 0x02000000 ++/* Sony Allegrex instruction. */ ++#define INSN_ALLEGREX 0x10000000 + + /* MDMX ASE */ + #define INSN_MDMX 0x04000000 +@@ -819,6 +1066,7 @@ + #define CPU_MIPS64 64 + #define CPU_MIPS64R2 65 + #define CPU_SB1 12310201 /* octal 'SB', 01. */ ++#define CPU_ALLEGREX 10111431 /* octal 'AL', 31. */ + #define CPU_LOONGSON_2E 3001 + #define CPU_LOONGSON_2F 3002 + #define CPU_LOONGSON_3A 3003 +@@ -851,6 +1099,7 @@ + || (cpu == CPU_VR4120 && ((insn)->membership & INSN_4120) != 0) \ + || (cpu == CPU_VR5400 && ((insn)->membership & INSN_5400) != 0) \ + || (cpu == CPU_VR5500 && ((insn)->membership & INSN_5500) != 0) \ ++ || (cpu == CPU_ALLEGREX && ((insn)->membership & INSN_ALLEGREX) != 0) \ + || (cpu == CPU_LOONGSON_2E \ + && ((insn)->membership & INSN_LOONGSON_2E) != 0) \ + || (cpu == CPU_LOONGSON_2F \ +@@ -1005,11 +1254,27 @@ + M_LI_DD, + M_LI_S, + M_LI_SS, ++ M_LVHI_S_SS, ++ M_LVHI_P_SS, ++ M_LVI_S_SS, ++ M_LVI_P_SS, ++ M_LVI_T_SS, ++ M_LVI_Q_SS, + M_LL_AB, + M_LL_OB, + M_LLD_AB, + M_LLD_OB, + M_LS_A, ++ M_LVHI_P, ++ M_LVHI_S, ++ M_LVI_P, ++ M_LVI_Q, ++ M_LVI_S, ++ M_LVI_T, ++ M_LVL_Q_AB, ++ M_LVR_Q_AB, ++ M_LV_Q_AB, ++ M_LV_Q_AB_2, + M_LW_A, + M_LW_AB, + M_LWC0_A, +@@ -1021,6 +1286,7 @@ + M_LWC2_OB, + M_LWC3_A, + M_LWC3_AB, ++ M_LV_S_AB, + M_LWL_A, + M_LWL_AB, + M_LWL_OB, +@@ -1130,6 +1396,10 @@ + M_SUB_I, + M_SUBU_I, + M_SUBU_I_2, ++ M_SVL_Q_AB, ++ M_SV_Q_AB, ++ M_SVR_Q_AB, ++ M_SV_S_AB, + M_TEQ_I, + M_TGE_I, + M_TGEU_I, +@@ -1144,14 +1414,24 @@ + M_ULH_A, + M_ULHU, + M_ULHU_A, ++ M_ULV_Q, ++ M_ULV_Q_AB, ++ M_ULV_S, + M_ULW, + M_ULW_A, + M_USH, + M_USH_A, ++ M_USV_Q, ++ M_USV_Q_AB, ++ M_USV_S, + M_USW, + M_USW_A, + M_USD, + M_USD_A, ++ M_VCMOV_P, ++ M_VCMOV_Q, ++ M_VCMOV_S, ++ M_VCMOV_T, + M_XOR_I, + M_COP0, + M_COP1, +diff -burN orig.binutils-2.22/include/opcode/vfpu.h binutils-2.22/include/opcode/vfpu.h +--- orig.binutils-2.22/include/opcode/vfpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.22/include/opcode/vfpu.h 2012-01-04 16:18:36.338214659 +0100 +@@ -0,0 +1,261 @@ ++#ifndef _VFPU_H_ ++#define _VFPU_H_ ++ ++//////////////////////////////////// ++// data type ++#define VFPU_MASK_DTYPE 0x8080 ++#define VFPU_QUAD 0x8080 ++#define VFPU_TRIPLE 0x8000 ++#define VFPU_PAIR 0x0080 ++#define VFPU_SINGLE 0x0000 ++ ++//////////////////////////////////// ++// register index ++#define VFPU_MASK_VT 0x7f0000 ++#define VFPU_MASK_VS 0x007f00 ++#define VFPU_MASK_VD 0x00007f ++ ++//////////////////////////////////// ++// condition and comapre inst ++#define VFPU_PADD_BIN_CMP 0x70 ++ ++//////////////////////////////////// ++// load/store left/right ++#define VFPU_MASK_LDST_LR 0x2 ++#define VFPU_LDST_L 0x0 ++#define VFPU_LDST_R 0x2 ++ ++//////////////////////////////////// ++// load/store memory/buffer ++#define VFPU_MASK_LDST_MB 0x2 ++#define VFPU_LDST_M 0x0 ++#define VFPU_LDST_B 0x2 ++ ++//////////////////////////////////// ++// coprocessor move ++#define VFPU_MASK_COP_MV 0xff80 ++#define VFPU_MASK_COP_MVC 0xff00 ++ ++//////////////////////////////////// ++// sync code ++#define VFPU_MASK_SYNC_CODE 0xffff ++#define VFPU_SYNC_CODE_DEFAULT 0x0320 ++#define VFPU_SYNC_CODE_NOP 0x0000 ++#define VFPU_SYNC_CODE_FLUSH 0x040d ++ ++//////////////////////////////////// ++#define VFPU_INST_BR_F 0x49000000 ++#define VFPU_MASK_BR_F 0xffe30000 ++#define VFPU_INST_BR_FL 0x49020000 ++#define VFPU_MASK_BR_FL 0xffe30000 ++#define VFPU_INST_BR_T 0x49010000 ++#define VFPU_MASK_BR_T 0xffe30000 ++#define VFPU_INST_BR_TL 0x49030000 ++#define VFPU_MASK_BR_TL 0xffe30000 ++ ++#define VFPU_INST_COP_LD_S 0xc8000000 ++#define VFPU_MASK_COP_LD_S 0xfc000000 ++#define VFPU_INST_COP_ST_S 0xe8000000 ++#define VFPU_MASK_COP_ST_S 0xfc000000 ++#define VFPU_INST_COP_LD_Q 0xd8000000 ++#define VFPU_MASK_COP_LD_Q 0xfc000000 ++#define VFPU_INST_COP_ST_Q 0xf8000000 ++#define VFPU_MASK_COP_ST_Q 0xfc000000 ++#define VFPU_INST_COP_LD_U 0xd4000000 ++#define VFPU_MASK_COP_LD_U 0xfc000000 ++#define VFPU_INST_COP_ST_U 0xf4000000 ++#define VFPU_MASK_COP_ST_U 0xfc000000 ++#define VFPU_INST_COP_MF 0x48600000 ++#define VFPU_MASK_COP_MF 0xffe00000 ++#define VFPU_INST_COP_MT 0x48e00000 ++#define VFPU_MASK_COP_MT 0xffe00000 ++ ++#define VFPU_INST_BIN_ADD 0x60000000 ++#define VFPU_MASK_BIN_ADD 0xff800000 ++#define VFPU_INST_BIN_SUB 0x60800000 ++#define VFPU_MASK_BIN_SUB 0xff800000 ++#define VFPU_INST_BIN_SBN 0x61000000 ++#define VFPU_MASK_BIN_SBN 0xff800000 ++#define VFPU_INST_BIN_DIV 0x63800000 ++#define VFPU_MASK_BIN_DIV 0xff800000 ++#define VFPU_INST_BIN_MUL 0x64000000 ++#define VFPU_MASK_BIN_MUL 0xff800000 ++#define VFPU_INST_BIN_DOT 0x64800000 ++#define VFPU_MASK_BIN_DOT 0xff800000 ++#define VFPU_INST_BIN_SCL 0x65000000 ++#define VFPU_MASK_BIN_SCL 0xff800000 ++#define VFPU_INST_BIN_HDP 0x66000000 ++#define VFPU_MASK_BIN_HDP 0xff800000 ++#define VFPU_INST_BIN_CRS 0x66800000 ++#define VFPU_MASK_BIN_CRS 0xff800000 ++#define VFPU_INST_BIN_DET 0x67000000 ++#define VFPU_MASK_BIN_DET 0xff800000 ++#define VFPU_INST_BIN_CMP 0x6c000000 ++#define VFPU_MASK_BIN_CMP 0xff800000 ++#define VFPU_INST_BIN_MIN 0x6d000000 ++#define VFPU_MASK_BIN_MIN 0xff800000 ++#define VFPU_INST_BIN_MAX 0x6d800000 ++#define VFPU_MASK_BIN_MAX 0xff800000 ++#define VFPU_INST_BIN_SCMP 0x6e800000 ++#define VFPU_MASK_BIN_SCMP 0xff800000 ++#define VFPU_INST_BIN_SGE 0x6f000000 ++#define VFPU_MASK_BIN_SGE 0xff800000 ++#define VFPU_INST_BIN_SLT 0x6f800000 ++#define VFPU_MASK_BIN_SLT 0xff800000 ++ ++#define VFPU_INST_UNR_MOV 0xd0000000 ++#define VFPU_MASK_UNR_MOV 0xffff0000 ++#define VFPU_INST_UNR_ABS 0xd0010000 ++#define VFPU_MASK_UNR_ABS 0xffff0000 ++#define VFPU_INST_UNR_NEG 0xd0020000 ++#define VFPU_MASK_UNR_NEG 0xffff0000 ++#define VFPU_INST_UNR_IDT 0xd0030000 ++#define VFPU_MASK_UNR_IDT 0xffff0000 ++#define VFPU_INST_UNR_SAT0 0xd0040000 ++#define VFPU_MASK_UNR_SAT0 0xffff0000 ++#define VFPU_INST_UNR_SAT1 0xd0050000 ++#define VFPU_MASK_UNR_SAT1 0xffff0000 ++#define VFPU_INST_UNR_ZERO 0xd0060000 ++#define VFPU_MASK_UNR_ZERO 0xffff0000 ++#define VFPU_INST_UNR_ONE 0xd0070000 ++#define VFPU_MASK_UNR_ONE 0xffff0000 ++#define VFPU_INST_UNR_RCP 0xd0100000 ++#define VFPU_MASK_UNR_RCP 0xffff0000 ++#define VFPU_INST_UNR_RSQ 0xd0110000 ++#define VFPU_MASK_UNR_RSQ 0xffff0000 ++#define VFPU_INST_UNR_SIN 0xd0120000 ++#define VFPU_MASK_UNR_SIN 0xffff0000 ++#define VFPU_INST_UNR_COS 0xd0130000 ++#define VFPU_MASK_UNR_COS 0xffff0000 ++#define VFPU_INST_UNR_EXP2 0xd0140000 ++#define VFPU_MASK_UNR_EXP2 0xffff0000 ++#define VFPU_INST_UNR_LOG2 0xd0150000 ++#define VFPU_MASK_UNR_LOG2 0xffff0000 ++#define VFPU_INST_UNR_SQR 0xd0160000 ++#define VFPU_MASK_UNR_SQR 0xffff0000 ++#define VFPU_INST_UNR_ASIN 0xd0170000 ++#define VFPU_MASK_UNR_ASIN 0xffff0000 ++#define VFPU_INST_UNR_NRCP 0xd0180000 ++#define VFPU_MASK_UNR_NRCP 0xffff0000 ++#define VFPU_INST_UNR_NSIN 0xd01a0000 ++#define VFPU_MASK_UNR_NSIN 0xffff0000 ++#define VFPU_INST_UNR_REXP2 0xd01c0000 ++#define VFPU_MASK_UNR_REXP2 0xffff0000 ++#define VFPU_INST_UNR_RNDS 0xd0200000 ++#define VFPU_MASK_UNR_RNDS 0xffff0000 ++#define VFPU_INST_UNR_RNDI 0xd0210000 ++#define VFPU_MASK_UNR_RNDI 0xffff0000 ++#define VFPU_INST_UNR_RNDF1 0xd0220000 ++#define VFPU_MASK_UNR_RNDF1 0xffff0000 ++#define VFPU_INST_UNR_RNDF2 0xd0230000 ++#define VFPU_MASK_UNR_RNDF2 0xffff0000 ++#define VFPU_INST_UNR_F2H 0xd0320000 ++#define VFPU_MASK_UNR_F2H 0xffff0000 ++#define VFPU_INST_UNR_H2F 0xd0330000 ++#define VFPU_MASK_UNR_H2F 0xffff0000 ++#define VFPU_INST_UNR_SBZ 0xd0360000 ++#define VFPU_MASK_UNR_SBZ 0xffff0000 ++#define VFPU_INST_UNR_LGB 0xd0370000 ++#define VFPU_MASK_UNR_LGB 0xffff0000 ++#define VFPU_INST_UNR_US2I 0xd03a0000 ++#define VFPU_MASK_UNR_US2I 0xffff0000 ++#define VFPU_INST_UNR_S2I 0xd03b0000 ++#define VFPU_MASK_UNR_S2I 0xffff0000 ++#define VFPU_INST_UNR_I2UC 0xd03c0000 ++#define VFPU_MASK_UNR_I2UC 0xffff0000 ++#define VFPU_INST_UNR_I2C 0xd03d0000 ++#define VFPU_MASK_UNR_I2C 0xffff0000 ++#define VFPU_INST_UNR_I2US 0xd03e0000 ++#define VFPU_MASK_UNR_I2US 0xffff0000 ++#define VFPU_INST_UNR_I2S 0xd03f0000 ++#define VFPU_MASK_UNR_I2S 0xffff0000 ++#define VFPU_INST_UNR_SRT1 0xd0400000 ++#define VFPU_MASK_UNR_SRT1 0xffff0000 ++#define VFPU_INST_UNR_SRT2 0xd0410000 ++#define VFPU_MASK_UNR_SRT2 0xffff0000 ++#define VFPU_INST_UNR_BFY1 0xd0420000 ++#define VFPU_MASK_UNR_BFY1 0xffff0000 ++#define VFPU_INST_UNR_BFY2 0xd0430000 ++#define VFPU_MASK_UNR_BFY2 0xffff0000 ++#define VFPU_INST_UNR_OCP 0xd0440000 ++#define VFPU_MASK_UNR_OCP 0xffff0000 ++#define VFPU_INST_UNR_SOCP 0xd0450000 ++#define VFPU_MASK_UNR_SOCP 0xffff0000 ++#define VFPU_INST_UNR_FAD 0xd0460000 ++#define VFPU_MASK_UNR_FAD 0xffff0000 ++#define VFPU_INST_UNR_AVG 0xd0470000 ++#define VFPU_MASK_UNR_AVG 0xffff0000 ++#define VFPU_INST_UNR_SRT3 0xd0480000 ++#define VFPU_MASK_UNR_SRT3 0xffff0000 ++#define VFPU_INST_UNR_SRT4 0xd0490000 ++#define VFPU_MASK_UNR_SRT4 0xffff0000 ++#define VFPU_INST_UNR_SGN 0xd04a0000 ++#define VFPU_MASK_UNR_SGN 0xffff0000 ++#define VFPU_INST_UNR_CF 0xd0500000 ++#define VFPU_MASK_UNR_CF 0xffff0080 ++#define VFPU_INST_UNR_CT 0xd0510000 ++#define VFPU_MASK_UNR_CT 0xffff8000 ++#define VFPU_INST_UNR_T4444 0xd0590000 ++#define VFPU_MASK_UNR_T4444 0xffff0000 ++#define VFPU_INST_UNR_T5551 0xd05a0000 ++#define VFPU_MASK_UNR_T5551 0xffff0000 ++#define VFPU_INST_UNR_T5650 0xd05b0000 ++#define VFPU_MASK_UNR_T5650 0xffff0000 ++#define VFPU_INST_UNR_CST 0xd0600000 ++#define VFPU_MASK_UNR_CST 0xffe00000 ++ ++#define VFPU_INST_UNRI_F2I_N 0xd2000000 ++#define VFPU_MASK_UNRI_F2I_N 0xffe00000 ++#define VFPU_INST_UNRI_F2I_Z 0xd2200000 ++#define VFPU_MASK_UNRI_F2I_Z 0xffe00000 ++#define VFPU_INST_UNRI_F2I_U 0xd2400000 ++#define VFPU_MASK_UNRI_F2I_U 0xffe00000 ++#define VFPU_INST_UNRI_F2I_D 0xd2600000 ++#define VFPU_MASK_UNRI_F2I_D 0xffe00000 ++#define VFPU_INST_UNRI_I2F 0xd2800000 ++#define VFPU_MASK_UNRI_I2F 0xffe00000 ++#define VFPU_INST_UNRI_CMOV_T 0xd2a00000 ++#define VFPU_MASK_UNRI_CMOV_T 0xfff80000 ++#define VFPU_INST_UNRI_CMOV_F 0xd2a80000 ++#define VFPU_MASK_UNRI_CMOV_F 0xfff80000 ++#define VFPU_INST_UNRI_WBN 0xd3000000 ++#define VFPU_MASK_UNRI_WBN 0xff000000 ++ ++#define VFPU_INST_PFX_RA 0xdc000000 ++#define VFPU_MASK_PFX_RA 0xff000000 ++#define VFPU_INST_PFX_RB 0xdd000000 ++#define VFPU_MASK_PFX_RB 0xff000000 ++#define VFPU_INST_PFX_W 0xde000000 ++#define VFPU_MASK_PFX_W 0xff000000 ++#define VFPU_INST_IIM 0xdf000000 ++#define VFPU_MASK_IIM 0xff800000 ++#define VFPU_INST_FIM 0xdf800000 ++#define VFPU_MASK_FIM 0xff800000 ++ ++#define VFPU_INST_RPT_MMUL 0xf0000000 ++#define VFPU_MASK_RPT_MMUL 0xff800000 ++#define VFPU_INST_RPT_TFM2 0xf0800000 ++#define VFPU_MASK_RPT_TFM2 0xff800000 ++#define VFPU_INST_RPT_TFM3 0xf1000000 ++#define VFPU_MASK_RPT_TFM3 0xff800000 ++#define VFPU_INST_RPT_TFM4 0xf1800000 ++#define VFPU_MASK_RPT_TFM4 0xff800000 ++#define VFPU_INST_RPT_MSCL 0xf2000000 ++#define VFPU_MASK_RPT_MSCL 0xff800000 ++#define VFPU_INST_RPT_QMUL 0xf2800000 ++#define VFPU_MASK_RPT_QMUL 0xff800000 ++#define VFPU_INST_RPT_MMOV 0xf3800000 ++#define VFPU_MASK_RPT_MMOV 0xffff0000 ++#define VFPU_INST_RPT_MIDT 0xf3830000 ++#define VFPU_MASK_RPT_MIDT 0xffff0000 ++#define VFPU_INST_RPT_MZERO 0xf3860000 ++#define VFPU_MASK_RPT_MZERO 0xffff0000 ++#define VFPU_INST_RPT_MONE 0xf3870000 ++#define VFPU_MASK_RPT_MONE 0xffff0000 ++#define VFPU_INST_RPT_ROT 0xf3a00000 ++#define VFPU_MASK_RPT_ROT 0xffe00000 ++ ++#define VFPU_INST_SYNC 0xffff0000 ++#define VFPU_MASK_SYNC 0xffff0000 ++ ++#endif /* _VFPU_H_ */ +diff -burN orig.binutils-2.22/ld/configure.tgt binutils-2.22/ld/configure.tgt +--- orig.binutils-2.22/ld/configure.tgt 2011-11-21 10:29:37.000000000 +0100 ++++ binutils-2.22/ld/configure.tgt 2012-01-04 16:18:36.578211917 +0100 +@@ -383,6 +383,8 @@ + mips*vr4100-*-elf*) targ_emul=elf32b4300 ;; + mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;; + mips*vr5000-*-elf*) targ_emul=elf32b4300 ;; ++mips*allegrexel-psp-elf*) targ_emul=elf_mipsallegrexel_psp ++ targ_extra_emuls="elf32elmip" ;; + mips*el-sde-elf*) targ_emul=elf32ltsmip + targ_extra_emuls="elf32btsmip elf32ltsmipn32 elf64ltsmip elf32btsmipn32 elf64btsmip" ;; + mips*-sde-elf*) targ_emul=elf32btsmip +diff -burN orig.binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh +--- orig.binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh 2012-01-04 16:18:36.368214315 +0100 +@@ -0,0 +1,22 @@ ++# Based off of the default elf32 MIPS target. However, we use a seperate ++# script template because the PSP architecture defines sections that normally ++# cannot be overriden here and would normally get absorbed (i.e. ++# .rodata.sceModuleInfo would be absorbed into .rodata). ++ ++EMBEDDED=yes ++. ${srcdir}/emulparams/elf32lmip.sh ++unset NONPAGED_TEXT_START_ADDR ++unset SHLIB_TEXT_START_ADDR ++unset COMMONPAGESIZE ++ ++SCRIPT_NAME=elf_psp ++TEXT_START_ADDR=0x08900000 ++MAXPAGESIZE=256 ++ARCH="mips:allegrex" ++MACHINE= ++TEMPLATE_NAME=elf32 ++GENERATE_SHLIB_SCRIPT=yes ++DYNAMIC_LINK=FALSE ++ ++# Discard the .comment and .pdr sections. ++OTHER_SECTIONS="/DISCARD/ : { *(.comment) *(.pdr) }" +diff -burN orig.binutils-2.22/ld/Makefile.am binutils-2.22/ld/Makefile.am +--- orig.binutils-2.22/ld/Makefile.am 2011-07-22 22:22:37.000000000 +0200 ++++ binutils-2.22/ld/Makefile.am 2012-01-04 17:02:20.728460268 +0100 +@@ -262,6 +262,7 @@ + eelf_i386_ldso.c \ + eelf_i386_sol2.c \ + eelf_i386_vxworks.c \ ++ eelf_mipsallegrexel_psp.o \ + eelf_s390.c \ + egld960.c \ + egld960coff.c \ +@@ -1196,6 +1197,9 @@ + $(srcdir)/emulparams/vxworks.sh $(srcdir)/emultempl/vxworks.em \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386_vxworks "$(tdir_elf_i386_vxworks)" ++eelf_mipsallegrexel_psp.c: $(srcdir)/emulparams/elf_mipsallegrexel_psp.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf_psp.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf_mipsallegrexel_psp "$(tdir_elf_mipsallegrexel_psp)" + eelf_s390.c: $(srcdir)/emulparams/elf_s390.sh \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_s390 "$(tdir_elf_s390)" +diff -burN orig.binutils-2.22/ld/Makefile.in binutils-2.22/ld/Makefile.in +--- orig.binutils-2.22/ld/Makefile.in 2011-07-22 22:22:37.000000000 +0200 ++++ binutils-2.22/ld/Makefile.in 2012-01-04 17:02:25.531403806 +0100 +@@ -568,6 +568,7 @@ + eelf_i386_ldso.c \ + eelf_i386_sol2.c \ + eelf_i386_vxworks.c \ ++ eelf_mipsallegrexel_psp.o \ + eelf_s390.c \ + egld960.c \ + egld960coff.c \ +@@ -2649,6 +2650,9 @@ + $(srcdir)/emulparams/vxworks.sh $(srcdir)/emultempl/vxworks.em \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_i386_vxworks "$(tdir_elf_i386_vxworks)" ++eelf_mipsallegrexel_psp.c: $(srcdir)/emulparams/elf_mipsallegrexel_psp.sh \ ++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf_psp.sc ${GEN_DEPENDS} ++ ${GENSCRIPTS} elf_mipsallegrexel_psp "$(tdir_elf_mipsallegrexel_psp)" + eelf_s390.c: $(srcdir)/emulparams/elf_s390.sh \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + ${GENSCRIPTS} elf_s390 "$(tdir_elf_s390)" +diff -burN orig.binutils-2.22/ld/scripttempl/elf_psp.sc binutils-2.22/ld/scripttempl/elf_psp.sc +--- orig.binutils-2.22/ld/scripttempl/elf_psp.sc 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.22/ld/scripttempl/elf_psp.sc 2012-01-04 16:18:36.380214179 +0100 +@@ -0,0 +1,496 @@ ++# ++# Unusual variables checked by this code: ++# NOP - four byte opcode for no-op (defaults to 0) ++# NO_SMALL_DATA - no .sbss/.sbss2/.sdata/.sdata2 sections if not ++# empty. ++# SMALL_DATA_CTOR - .ctors contains small data. ++# SMALL_DATA_DTOR - .dtors contains small data. ++# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start ++# INITIAL_READONLY_SECTIONS - at start of text segment ++# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... ++# (e.g., .PARISC.milli) ++# OTHER_TEXT_SECTIONS - these get put in .text when relocating ++# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... ++# (e.g., .PARISC.global) ++# OTHER_RELRO_SECTIONS - other than .data.rel.ro ... ++# (e.g. PPC32 .fixup, .got[12]) ++# OTHER_BSS_SECTIONS - other than .bss .sbss ... ++# OTHER_SECTIONS - at the end ++# EXECUTABLE_SYMBOLS - symbols that must be defined for an ++# executable (e.g., _DYNAMIC_LINK) ++# TEXT_START_ADDR - the first byte of the text segment, after any ++# headers. ++# TEXT_BASE_ADDRESS - the first byte of the text segment. ++# TEXT_START_SYMBOLS - symbols that appear at the start of the ++# .text section. ++# DATA_START_SYMBOLS - symbols that appear at the start of the ++# .data section. ++# OTHER_GOT_SYMBOLS - symbols defined just before .got. ++# OTHER_GOT_SECTIONS - sections just after .got. ++# OTHER_SDATA_SECTIONS - sections just after .sdata. ++# OTHER_BSS_SYMBOLS - symbols that appear at the start of the ++# .bss section besides __bss_start. ++# DATA_PLT - .plt should be in data segment, not text segment. ++# PLT_BEFORE_GOT - .plt just before .got when .plt is in data segement. ++# BSS_PLT - .plt should be in bss segment ++# TEXT_DYNAMIC - .dynamic in text segment, not data segment. ++# EMBEDDED - whether this is for an embedded system. ++# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set ++# start address of shared library. ++# INPUT_FILES - INPUT command of files to always include ++# WRITABLE_RODATA - if set, the .rodata section should be writable ++# INIT_START, INIT_END - statements just before and just after ++# combination of .init sections. ++# FINI_START, FINI_END - statements just before and just after ++# combination of .fini sections. ++# STACK_ADDR - start of a .stack section. ++# OTHER_END_SYMBOLS - symbols to place right at the end of the script. ++# SEPARATE_GOTPLT - if set, .got.plt should be separate output section, ++# so that .got can be in the RELRO area. It should be set to ++# the number of bytes in the beginning of .got.plt which can be ++# in the RELRO area as well. ++# ++# When adding sections, do note that the names of some sections are used ++# when specifying the start address of the next. ++# ++ ++# Many sections come in three flavours. There is the 'real' section, ++# like ".data". Then there are the per-procedure or per-variable ++# sections, generated by -ffunction-sections and -fdata-sections in GCC, ++# and useful for --gc-sections, which for a variable "foo" might be ++# ".data.foo". Then there are the linkonce sections, for which the linker ++# eliminates duplicates, which are named like ".gnu.linkonce.d.foo". ++# The exact correspondences are: ++# ++# Section Linkonce section ++# .text .gnu.linkonce.t.foo ++# .rodata .gnu.linkonce.r.foo ++# .data .gnu.linkonce.d.foo ++# .bss .gnu.linkonce.b.foo ++# .sdata .gnu.linkonce.s.foo ++# .sbss .gnu.linkonce.sb.foo ++# .sdata2 .gnu.linkonce.s2.foo ++# .sbss2 .gnu.linkonce.sb2.foo ++# .debug_info .gnu.linkonce.wi.foo ++# .tdata .gnu.linkonce.td.foo ++# .tbss .gnu.linkonce.tb.foo ++# ++# Each of these can also have corresponding .rel.* and .rela.* sections. ++ ++test -z "$ENTRY" && ENTRY=_start ++test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} ++test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} ++if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi ++test -z "${ELFSIZE}" && ELFSIZE=32 ++test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8" ++test "$LD_FLAG" = "N" && DATA_ADDR=. ++test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE="" ++test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE="" ++test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT ++DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))" ++DATA_SEGMENT_RELRO_END="" ++DATA_SEGMENT_RELRO_GOTPLT_END="" ++DATA_SEGMENT_END="" ++if test -n "${COMMONPAGESIZE}"; then ++ DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})" ++ DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);" ++ if test -n "${SEPARATE_GOTPLT}"; then ++ DATA_SEGMENT_RELRO_GOTPLT_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT}, .);" ++ else ++ DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (0, .);" ++ fi ++fi ++INTERP=".interp ${RELOCATING-0} : { *(.interp) }" ++PLT=".plt ${RELOCATING-0} : { *(.plt) }" ++if test -z "$GOT"; then ++ if test -z "$SEPARATE_GOTPLT"; then ++ GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" ++ else ++ GOT=".got ${RELOCATING-0} : { *(.got) }" ++ GOTPLT="${RELOCATING+${DATA_SEGMENT_RELRO_GOTPLT_END}} ++ .got.plt ${RELOCATING-0} : { *(.got.plt) }" ++ fi ++fi ++DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" ++RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" ++DATARELRO=".data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }" ++STACKNOTE="/DISCARD/ : { *(.note.GNU-stack) }" ++if test -z "${NO_SMALL_DATA}"; then ++ SBSS=".sbss ${RELOCATING-0} : ++ { ++ ${RELOCATING+PROVIDE (__sbss_start = .);} ++ ${RELOCATING+PROVIDE (___sbss_start = .);} ++ ${CREATE_SHLIB+*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)} ++ *(.dynsbss) ++ *(.sbss${RELOCATING+ .sbss.* .gnu.linkonce.sb.*}) ++ *(.scommon) ++ ${RELOCATING+PROVIDE (__sbss_end = .);} ++ ${RELOCATING+PROVIDE (___sbss_end = .);} ++ }" ++ SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2${RELOCATING+ .sbss2.* .gnu.linkonce.sb2.*}) }" ++ SDATA="/* We want the small data sections together, so single-instruction offsets ++ can access them all, and initialized data all before uninitialized, so ++ we can shorten the on-disk segment size. */ ++ .sdata ${RELOCATING-0} : ++ { ++ ${RELOCATING+${SDATA_START_SYMBOLS}} ++ ${CREATE_SHLIB+*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)} ++ *(.sdata${RELOCATING+ .sdata.* .gnu.linkonce.s.*}) ++ }" ++ SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2${RELOCATING+ .sdata2.* .gnu.linkonce.s2.*}) }" ++ REL_SDATA=".rel.sdata ${RELOCATING-0} : { *(.rel.sdata${RELOCATING+ .rel.sdata.* .rel.gnu.linkonce.s.*}) } ++ .rela.sdata ${RELOCATING-0} : { *(.rela.sdata${RELOCATING+ .rela.sdata.* .rela.gnu.linkonce.s.*}) }" ++ REL_SBSS=".rel.sbss ${RELOCATING-0} : { *(.rel.sbss${RELOCATING+ .rel.sbss.* .rel.gnu.linkonce.sb.*}) } ++ .rela.sbss ${RELOCATING-0} : { *(.rela.sbss${RELOCATING+ .rela.sbss.* .rela.gnu.linkonce.sb.*}) }" ++ REL_SDATA2=".rel.sdata2 ${RELOCATING-0} : { *(.rel.sdata2${RELOCATING+ .rel.sdata2.* .rel.gnu.linkonce.s2.*}) } ++ .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2${RELOCATING+ .rela.sdata2.* .rela.gnu.linkonce.s2.*}) }" ++ REL_SBSS2=".rel.sbss2 ${RELOCATING-0} : { *(.rel.sbss2${RELOCATING+ .rel.sbss2.* .rel.gnu.linkonce.sb2.*}) } ++ .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2${RELOCATING+ .rela.sbss2.* .rela.gnu.linkonce.sb2.*}) }" ++else ++ NO_SMALL_DATA=" " ++fi ++test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" " ++CTOR=".ctors ${CONSTRUCTING-0} : ++ { ++ ${CONSTRUCTING+${CTOR_START}} ++ /* gcc uses crtbegin.o to find the start of ++ the constructors, so we make sure it is ++ first. Because this is a wildcard, it ++ doesn't matter if the user does not ++ actually link against crtbegin.o; the ++ linker won't look for a file to match a ++ wildcard. The wildcard also means that it ++ doesn't matter which directory crtbegin.o ++ is in. */ ++ ++ KEEP (*crtbegin*.o(.ctors)) ++ ++ /* We don't want to include the .ctor section from ++ from the crtend.o file until after the sorted ctors. ++ The .ctor section from the crtend file contains the ++ end of ctors marker and it must be last */ ++ ++ KEEP (*(EXCLUDE_FILE (*crtend*.o $OTHER_EXCLUDE_FILES) .ctors)) ++ KEEP (*(SORT(.ctors.*))) ++ KEEP (*(.ctors)) ++ ${CONSTRUCTING+${CTOR_END}} ++ }" ++DTOR=".dtors ${CONSTRUCTING-0} : ++ { ++ ${CONSTRUCTING+${DTOR_START}} ++ KEEP (*crtbegin*.o(.dtors)) ++ KEEP (*(EXCLUDE_FILE (*crtend*.o $OTHER_EXCLUDE_FILES) .dtors)) ++ KEEP (*(SORT(.dtors.*))) ++ KEEP (*(.dtors)) ++ ${CONSTRUCTING+${DTOR_END}} ++ }" ++STACK=" .stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} : ++ { ++ ${RELOCATING+_stack = .;} ++ *(.stack) ++ }" ++ ++# if this is for an embedded system, don't add SIZEOF_HEADERS. ++if [ -z "$EMBEDDED" ]; then ++ test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS" ++else ++ test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}" ++fi ++ ++cat <<EOF ++OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", ++ "${LITTLE_OUTPUT_FORMAT}") ++OUTPUT_ARCH(${OUTPUT_ARCH}) ++ENTRY(${ENTRY}) ++ ++${RELOCATING+${LIB_SEARCH_DIRS}} ++${RELOCATING+/* Do we need any of these for elf? ++ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} ++${RELOCATING+${EXECUTABLE_SYMBOLS}} ++${RELOCATING+${INPUT_FILES}} ++${RELOCATING- /* For some reason, the Solaris linker makes bad executables ++ if gld -r is used and the intermediate file has sections starting ++ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld ++ bug. But for now assigning the zero vmas works. */} ++ ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${TEXT_BASE_ADDRESS};}}} ++ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} ++ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} ++ ${CREATE_SHLIB-${INTERP}} ++ ${INITIAL_READONLY_SECTIONS} ++ ${TEXT_DYNAMIC+${DYNAMIC}} ++ .hash ${RELOCATING-0} : { *(.hash) } ++ .dynsym ${RELOCATING-0} : { *(.dynsym) } ++ .dynstr ${RELOCATING-0} : { *(.dynstr) } ++ .gnu.version ${RELOCATING-0} : { *(.gnu.version) } ++ .gnu.version_d ${RELOCATING-0}: { *(.gnu.version_d) } ++ .gnu.version_r ${RELOCATING-0}: { *(.gnu.version_r) } ++ ++EOF ++if [ "x$COMBRELOC" = x ]; then ++ COMBRELOCCAT=cat ++else ++ COMBRELOCCAT="cat > $COMBRELOC" ++fi ++eval $COMBRELOCCAT <<EOF ++ .rel.init ${RELOCATING-0} : { *(.rel.init) } ++ .rela.init ${RELOCATING-0} : { *(.rela.init) } ++ .rel.text ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) } ++ .rela.text ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) } ++ .rel.fini ${RELOCATING-0} : { *(.rel.fini) } ++ .rela.fini ${RELOCATING-0} : { *(.rela.fini) } ++ ++ /* PSP-specific relocations. */ ++ .rel.sceStub.text ${RELOCATING-0} : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } ++ .rel.lib.ent.top ${RELOCATING-0} : { *(.rel.lib.ent.top) } ++ .rel.lib.ent ${RELOCATING-0} : { *(.rel.lib.ent) } ++ .rel.lib.ent.btm ${RELOCATING-0} : { *(.rel.lib.ent.btm) } ++ .rel.lib.stub.top ${RELOCATING-0} : { *(.rel.lib.stub.top) } ++ .rel.lib.stub ${RELOCATING-0} : { *(.rel.lib.stub) } ++ .rel.lib.stub.btm ${RELOCATING-0} : { *(.rel.lib.stub.btm) } ++ .rel.rodata.sceModuleInfo ${RELOCATING-0} : { *(.rel.rodata.sceModuleInfo) } ++ .rel.rodata.sceResident ${RELOCATING-0} : { *(.rel.rodata.sceResident) } ++ .rel.rodata.sceNid ${RELOCATING-0} : { *(.rel.rodata.sceNid) } ++ .rel.rodata.sceVstub ${RELOCATING-0} : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } ++ ++ .rel.rodata ${RELOCATING-0} : { *(.rel.rodata${RELOCATING+ .rel.rodata.* .rel.gnu.linkonce.r.*}) } ++ .rela.rodata ${RELOCATING-0} : { *(.rela.rodata${RELOCATING+ .rela.rodata.* .rela.gnu.linkonce.r.*}) } ++ ${OTHER_READONLY_RELOC_SECTIONS} ++ .rel.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) } ++ .rela.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) } ++ .rel.data ${RELOCATING-0} : { *(.rel.data${RELOCATING+ .rel.data.* .rel.gnu.linkonce.d.*}) } ++ .rela.data ${RELOCATING-0} : { *(.rela.data${RELOCATING+ .rela.data.* .rela.gnu.linkonce.d.*}) } ++ .rel.tdata ${RELOCATING-0} : { *(.rel.tdata${RELOCATING+ .rel.tdata.* .rel.gnu.linkonce.td.*}) } ++ .rela.tdata ${RELOCATING-0} : { *(.rela.tdata${RELOCATING+ .rela.tdata.* .rela.gnu.linkonce.td.*}) } ++ .rel.tbss ${RELOCATING-0} : { *(.rel.tbss${RELOCATING+ .rel.tbss.* .rel.gnu.linkonce.tb.*}) } ++ .rela.tbss ${RELOCATING-0} : { *(.rela.tbss${RELOCATING+ .rela.tbss.* .rela.gnu.linkonce.tb.*}) } ++ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } ++ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } ++ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } ++ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } ++ .rel.got ${RELOCATING-0} : { *(.rel.got) } ++ .rela.got ${RELOCATING-0} : { *(.rela.got) } ++ ${OTHER_GOT_RELOC_SECTIONS} ++ ${REL_SDATA} ++ ${REL_SBSS} ++ ${REL_SDATA2} ++ ${REL_SBSS2} ++ .rel.bss ${RELOCATING-0} : { *(.rel.bss${RELOCATING+ .rel.bss.* .rel.gnu.linkonce.b.*}) } ++ .rela.bss ${RELOCATING-0} : { *(.rela.bss${RELOCATING+ .rela.bss.* .rela.gnu.linkonce.b.*}) } ++EOF ++if [ -n "$COMBRELOC" ]; then ++cat <<EOF ++ .rel.dyn ${RELOCATING-0} : ++ { ++EOF ++sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/ \1/' $COMBRELOC ++cat <<EOF ++ } ++ .rela.dyn ${RELOCATING-0} : ++ { ++EOF ++sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/ \1/' $COMBRELOC ++cat <<EOF ++ } ++EOF ++fi ++cat <<EOF ++ .rel.plt ${RELOCATING-0} : { *(.rel.plt) } ++ .rela.plt ${RELOCATING-0} : { *(.rela.plt) } ++ ${OTHER_PLT_RELOC_SECTIONS} ++ ++ .init ${RELOCATING-0} : ++ { ++ ${RELOCATING+${INIT_START}} ++ KEEP (*(.init)) ++ ${RELOCATING+${INIT_END}} ++ } =${NOP-0} ++ ++ ${DATA_PLT-${BSS_PLT-${PLT}}} ++ .text ${RELOCATING-0} : ++ { ++ ${RELOCATING+${TEXT_START_SYMBOLS}} ++ *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*}) ++ KEEP (*(.text.*personality*)) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ ${RELOCATING+${OTHER_TEXT_SECTIONS}} ++ } =${NOP-0} ++ .fini ${RELOCATING-0} : ++ { ++ ${RELOCATING+${FINI_START}} ++ KEEP (*(.fini)) ++ ${RELOCATING+${FINI_END}} ++ } =${NOP-0} ++ ++ /* PSP library stub functions. */ ++ .sceStub.text ${RELOCATING-0} : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } ++ ++ ${RELOCATING+PROVIDE (__etext = .);} ++ ${RELOCATING+PROVIDE (_etext = .);} ++ ${RELOCATING+PROVIDE (etext = .);} ++ ++ /* PSP library entry table and library stub table. */ ++ .lib.ent.top ${RELOCATING-0} : { *(.lib.ent.top) } ++ .lib.ent ${RELOCATING-0} : { *(.lib.ent) } ++ .lib.ent.btm ${RELOCATING-0} : { *(.lib.ent.btm) } ++ ++ .lib.stub.top ${RELOCATING-0} : { *(.lib.stub.top) } ++ .lib.stub ${RELOCATING-0} : { *(.lib.stub) } ++ .lib.stub.btm ${RELOCATING-0} : { *(.lib.stub.btm) } ++ ++ /* PSP read-only data for module info, NIDs, and Vstubs. The ++ .rodata.sceModuleInfo section must appear before the .rodata section ++ otherwise it would get absorbed into .rodata and the PSP bootloader ++ would be unable to locate the module info structure. */ ++ .rodata.sceModuleInfo ${RELOCATING-0} : { *(.rodata.sceModuleInfo) } ++ .rodata.sceResident ${RELOCATING-0} : { *(.rodata.sceResident) } ++ .rodata.sceNid ${RELOCATING-0} : { *(.rodata.sceNid) } ++ .rodata.sceVstub ${RELOCATING-0} : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } ++ ++ ${WRITABLE_RODATA-${RODATA}} ++ .rodata1 ${RELOCATING-0} : { *(.rodata1) } ++ ${CREATE_SHLIB-${SDATA2}} ++ ${CREATE_SHLIB-${SBSS2}} ++ ${OTHER_READONLY_SECTIONS} ++ .eh_frame_hdr : { *(.eh_frame_hdr) } ++ .eh_frame ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) } ++ .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } ++ ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. */ ++ ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}} ++ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}} ++ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}} ++ ++ /* Exception handling */ ++ .eh_frame ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) } ++ .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } ++ ++ /* Thread Local Storage sections */ ++ .tdata ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) } ++ .tbss ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} } ++ ++ /* Ensure the __preinit_array_start label is properly aligned. We ++ could instead move the label definition inside the section, but ++ the linker would then create the section even if it turns out to ++ be empty, which isn't pretty. */ ++ ${RELOCATING+. = ALIGN(${ALIGNMENT});} ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_start = .);}} ++ .preinit_array ${RELOCATING-0} : { KEEP (*(.preinit_array)) } ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_end = .);}} ++ ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_start = .);}} ++ .init_array ${RELOCATING-0} : { KEEP (*(.init_array)) } ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_end = .);}} ++ ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_start = .);}} ++ .fini_array ${RELOCATING-0} : { KEEP (*(.fini_array)) } ++ ${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_end = .);}} ++ ++ ${SMALL_DATA_CTOR-${RELOCATING+${CTOR}}} ++ ${SMALL_DATA_DTOR-${RELOCATING+${DTOR}}} ++ .jcr ${RELOCATING-0} : { KEEP (*(.jcr)) } ++ ++ ${RELOCATING+${DATARELRO}} ++ ${OTHER_RELRO_SECTIONS} ++ ${TEXT_DYNAMIC-${DYNAMIC}} ++ ${NO_SMALL_DATA+${RELRO_NOW+${GOT}}} ++ ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT}}}} ++ ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT+${GOTPLT}}}} ++ ${RELOCATING+${DATA_SEGMENT_RELRO_END}} ++ ${NO_SMALL_DATA+${RELRO_NOW-${SEPARATE_GOTPLT-${GOT}}}} ++ ++ ${DATA_PLT+${PLT_BEFORE_GOT-${PLT}}} ++ ++ .data ${RELOCATING-0} : ++ { ++ ${RELOCATING+${DATA_START_SYMBOLS}} ++ *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*}) ++ KEEP (*(.gnu.linkonce.d.*personality*)) ++ ${CONSTRUCTING+SORT(CONSTRUCTORS)} ++ } ++ .data1 ${RELOCATING-0} : { *(.data1) } ++ ${WRITABLE_RODATA+${RODATA}} ++ ${OTHER_READWRITE_SECTIONS} ++ ${SMALL_DATA_CTOR+${RELOCATING+${CTOR}}} ++ ${SMALL_DATA_DTOR+${RELOCATING+${DTOR}}} ++ ${DATA_PLT+${PLT_BEFORE_GOT+${PLT}}} ++ ${RELOCATING+${OTHER_GOT_SYMBOLS}} ++ ${NO_SMALL_DATA-${GOT}} ++ ${OTHER_GOT_SECTIONS} ++ ${SDATA} ++ ${OTHER_SDATA_SECTIONS} ++ ${RELOCATING+_edata = .;} ++ ${RELOCATING+PROVIDE (edata = .);} ++ ${RELOCATING+__bss_start = .;} ++ ${RELOCATING+${OTHER_BSS_SYMBOLS}} ++ ${SBSS} ++ ${BSS_PLT+${PLT}} ++ .bss ${RELOCATING-0} : ++ { ++ *(.dynbss) ++ *(.bss${RELOCATING+ .bss.* .gnu.linkonce.b.*}) ++ *(COMMON) ++ /* Align here to ensure that the .bss section occupies space up to ++ _end. Align after .bss to ensure correct alignment even if the ++ .bss section disappears because there are no input sections. */ ++ ${RELOCATING+. = ALIGN(${ALIGNMENT});} ++ } ++ ${OTHER_BSS_SECTIONS} ++ ${RELOCATING+. = ALIGN(${ALIGNMENT});} ++ ${RELOCATING+_end = .;} ++ ${RELOCATING+${OTHER_BSS_END_SYMBOLS}} ++ ${RELOCATING+PROVIDE (end = .);} ++ ${RELOCATING+${DATA_SEGMENT_END}} ++ ++ /* Stabs debugging sections. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ .stab.excl 0 : { *(.stab.excl) } ++ .stab.exclstr 0 : { *(.stab.exclstr) } ++ .stab.index 0 : { *(.stab.index) } ++ .stab.indexstr 0 : { *(.stab.indexstr) } ++ ++ .comment 0 : { *(.comment) } ++ ++ /* DWARF debug sections. ++ Symbols in the DWARF debugging sections are relative to the beginning ++ of the section so we begin them at 0. */ ++ ++ /* DWARF 1 */ ++ .debug 0 : { *(.debug) } ++ .line 0 : { *(.line) } ++ ++ /* GNU DWARF 1 extensions */ ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ ++ /* DWARF 1.1 and DWARF 2 */ ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ ++ /* DWARF 2 */ ++ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } ++ .debug_abbrev 0 : { *(.debug_abbrev) } ++ .debug_line 0 : { *(.debug_line) } ++ .debug_frame 0 : { *(.debug_frame) } ++ .debug_str 0 : { *(.debug_str) } ++ .debug_loc 0 : { *(.debug_loc) } ++ .debug_macinfo 0 : { *(.debug_macinfo) } ++ ++ /* SGI/MIPS DWARF 2 extensions */ ++ .debug_weaknames 0 : { *(.debug_weaknames) } ++ .debug_funcnames 0 : { *(.debug_funcnames) } ++ .debug_typenames 0 : { *(.debug_typenames) } ++ .debug_varnames 0 : { *(.debug_varnames) } ++ ++ ${STACK_ADDR+${STACK}} ++ ${OTHER_SECTIONS} ++ ${RELOCATING+${OTHER_END_SYMBOLS}} ++ ${RELOCATING+${STACKNOTE}} ++} ++EOF +diff -burN orig.binutils-2.22/opcodes/mips-dis.c binutils-2.22/opcodes/mips-dis.c +--- orig.binutils-2.22/opcodes/mips-dis.c 2011-08-09 17:20:03.000000000 +0200 ++++ binutils-2.22/opcodes/mips-dis.c 2012-01-04 16:18:36.745210009 +0100 +@@ -245,6 +245,139 @@ + "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", + }; + ++static const char * const vfpu_sreg_names[128] = { ++ "S000", "S010", "S020", "S030", "S100", "S110", "S120", "S130", ++ "S200", "S210", "S220", "S230", "S300", "S310", "S320", "S330", ++ "S400", "S410", "S420", "S430", "S500", "S510", "S520", "S530", ++ "S600", "S610", "S620", "S630", "S700", "S710", "S720", "S730", ++ "S001", "S011", "S021", "S031", "S101", "S111", "S121", "S131", ++ "S201", "S211", "S221", "S231", "S301", "S311", "S321", "S331", ++ "S401", "S411", "S421", "S431", "S501", "S511", "S521", "S531", ++ "S601", "S611", "S621", "S631", "S701", "S711", "S721", "S731", ++ "S002", "S012", "S022", "S032", "S102", "S112", "S122", "S132", ++ "S202", "S212", "S222", "S232", "S302", "S312", "S322", "S332", ++ "S402", "S412", "S422", "S432", "S502", "S512", "S522", "S532", ++ "S602", "S612", "S622", "S632", "S702", "S712", "S722", "S732", ++ "S003", "S013", "S023", "S033", "S103", "S113", "S123", "S133", ++ "S203", "S213", "S223", "S233", "S303", "S313", "S323", "S333", ++ "S403", "S413", "S423", "S433", "S503", "S513", "S523", "S533", ++ "S603", "S613", "S623", "S633", "S703", "S713", "S723", "S733" ++}; ++ ++static const char * const vfpu_vpreg_names[128] = { ++ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130", ++ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330", ++ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530", ++ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730", ++ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103", ++ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303", ++ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503", ++ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703", ++ "C002", "C012", "C022", "C032", "C102", "C112", "C122", "C132", ++ "C202", "C212", "C222", "C232", "C302", "C312", "C322", "C332", ++ "C402", "C412", "C422", "C432", "C502", "C512", "C522", "C532", ++ "C602", "C612", "C622", "C632", "C702", "C712", "C722", "C732", ++ "R020", "R021", "R022", "R023", "R120", "R121", "R122", "R123", ++ "R220", "R221", "R222", "R223", "R320", "R321", "R322", "R323", ++ "R420", "R421", "R422", "R423", "R520", "R521", "R522", "R523", ++ "R620", "R621", "R622", "R623", "R720", "R721", "R722", "R723" ++}; ++ ++static const char * const vfpu_vtreg_names[128] = { ++ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130", ++ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330", ++ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530", ++ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730", ++ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103", ++ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303", ++ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503", ++ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703", ++ "C001", "C011", "C021", "C031", "C101", "C111", "C121", "C131", ++ "C201", "C211", "C221", "C231", "C301", "C311", "C321", "C331", ++ "C401", "C411", "C421", "C431", "C501", "C511", "C521", "C531", ++ "C601", "C611", "C621", "C631", "C701", "C711", "C721", "C731", ++ "R010", "R011", "R012", "R013", "R110", "R111", "R112", "R113", ++ "R210", "R211", "R212", "R213", "R310", "R311", "R312", "R313", ++ "R410", "R411", "R412", "R413", "R510", "R511", "R512", "R513", ++ "R610", "R611", "R612", "R613", "R710", "R711", "R712", "R713" ++}; ++ ++static const char * const vfpu_vqreg_names[128] = { ++ "C000", "C010", "C020", "C030", "C100", "C110", "C120", "C130", ++ "C200", "C210", "C220", "C230", "C300", "C310", "C320", "C330", ++ "C400", "C410", "C420", "C430", "C500", "C510", "C520", "C530", ++ "C600", "C610", "C620", "C630", "C700", "C710", "C720", "C730", ++ "R000", "R001", "R002", "R003", "R100", "R101", "R102", "R103", ++ "R200", "R201", "R202", "R203", "R300", "R301", "R302", "R303", ++ "R400", "R401", "R402", "R403", "R500", "R501", "R502", "R503", ++ "R600", "R601", "R602", "R603", "R700", "R701", "R702", "R703", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "" ++}; ++ ++static const char * const vfpu_mpreg_names[128] = { ++ "M000", "", "M020", "", "M100", "", "M120", "", ++ "M200", "", "M220", "", "M300", "", "M320", "", ++ "M400", "", "M420", "", "M500", "", "M520", "", ++ "M600", "", "M620", "", "M700", "", "M720", "", ++ "E000", "", "E002", "", "E100", "", "E102", "", ++ "E200", "", "E202", "", "E300", "", "E302", "", ++ "E400", "", "E402", "", "E500", "", "E502", "", ++ "E600", "", "E602", "", "E700", "", "E702", "", ++ "M002", "", "M022", "", "M102", "", "M122", "", ++ "M202", "", "M222", "", "M302", "", "M322", "", ++ "M402", "", "M422", "", "M502", "", "M522", "", ++ "M602", "", "M622", "", "M702", "", "M722", "", ++ "E020", "", "E022", "", "E120", "", "E122", "", ++ "E220", "", "E222", "", "E320", "", "E322", "", ++ "E420", "", "E422", "", "E520", "", "E522", "", ++ "E620", "", "E622", "", "E720", "", "E722", "" ++}; ++ ++static const char * const vfpu_mtreg_names[128] = { ++ "M000", "M010", "", "", "M100", "M110", "", "", ++ "M200", "M210", "", "", "M300", "M310", "", "", ++ "M400", "M410", "", "", "M500", "M510", "", "", ++ "M600", "M610", "", "", "M700", "M710", "", "", ++ "E000", "E001", "", "", "E100", "E101", "", "", ++ "E200", "E201", "", "", "E300", "E301", "", "", ++ "E400", "E401", "", "", "E500", "E501", "", "", ++ "E600", "E601", "", "", "E700", "E701", "", "", ++ "M001", "M011", "", "", "M101", "M111", "", "", ++ "M201", "M211", "", "", "M301", "M311", "", "", ++ "M401", "M411", "", "", "M501", "M511", "", "", ++ "M601", "M611", "", "", "M701", "M711", "", "", ++ "E010", "E011", "", "", "E110", "E111", "", "", ++ "E210", "E211", "", "", "E310", "E311", "", "", ++ "E410", "E411", "", "", "E510", "E511", "", "", ++ "E610", "E611", "", "", "E710", "E711", "", "" ++}; ++ ++static const char * const vfpu_mqreg_names[128] = { ++ "M000", "", "", "", "M100", "", "", "", ++ "M200", "", "", "", "M300", "", "", "", ++ "M400", "", "", "", "M500", "", "", "", ++ "M600", "", "", "", "M700", "", "", "", ++ "E000", "", "", "", "E100", "", "", "", ++ "E200", "", "", "", "E300", "", "", "", ++ "E400", "", "", "", "E500", "", "", "", ++ "E600", "", "", "", "E700", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "" ++}; ++ + static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = + { + { 16, 1, "c0_config1" }, +@@ -471,6 +604,54 @@ + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" + }; + ++static const char * const vfpu_cond_names[16] = { ++ "FL", "EQ", "LT", "LE", "TR", "NE", "GE", "GT", ++ "EZ", "EN", "EI", "ES", "NZ", "NN", "NI", "NS" ++}; ++ ++static const char * const vfpu_const_names[20] = { ++ "", ++ "VFPU_HUGE", ++ "VFPU_SQRT2", ++ "VFPU_SQRT1_2", ++ "VFPU_2_SQRTPI", ++ "VFPU_2_PI", ++ "VFPU_1_PI", ++ "VFPU_PI_4", ++ "VFPU_PI_2", ++ "VFPU_PI", ++ "VFPU_E", ++ "VFPU_LOG2E", ++ "VFPU_LOG10E", ++ "VFPU_LN2", ++ "VFPU_LN10", ++ "VFPU_2PI", ++ "VFPU_PI_6", ++ "VFPU_LOG10TWO", ++ "VFPU_LOG2TEN", ++ "VFPU_SQRT3_2" ++}; ++ ++#define VFPU_NUM_CONSTANTS \ ++ ((sizeof vfpu_const_names) / (sizeof (vfpu_const_names[0]))) ++const unsigned int vfpu_num_constants = VFPU_NUM_CONSTANTS; ++ ++static const char * const vfpu_rwb_names[4] = { ++ "wt", "wb", "", "" ++}; ++ ++static const char * const pfx_cst_names[8] = { ++ "0", "1", "2", "1/2", "3", "1/3", "1/4", "1/6" ++}; ++ ++static const char * const pfx_swz_names[4] = { ++ "x", "y", "z", "w" ++}; ++ ++static const char * const pfx_sat_names[4] = { ++ "", "[0:1]", "", "[-1:1]" ++}; ++ + struct mips_abi_choice + { + const char * name; +@@ -550,6 +731,8 @@ + mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, + mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, ++ { "allegrex", 1, bfd_mach_mips_allegrex, CPU_ALLEGREX, ISA_MIPS2, ++ mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + + /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs. + Note that MIPS-3D and MDMX are not applicable to MIPS32. (See +@@ -1479,6 +1662,349 @@ + (l >> OP_SH_FT) & OP_MASK_FT); + break; + ++ case '?': ++ /* VFPU extensions. */ ++ d++; ++ switch (*d) ++ { ++ case '\0': ++ /* xgettext:c-format */ ++ (*info->fprintf_func) (info->stream, ++ _("# internal error, incomplete VFPU extension sequence (?)")); ++ return; ++ ++ case 'o': ++ delta = (l >> OP_SH_VFPU_DELTA) & OP_MASK_VFPU_DELTA; ++ if (delta & 0x8000) ++ delta |= ~0xffff; ++ (*info->fprintf_func) (info->stream, "%d", ++ delta); ++ break; ++ ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ { ++ unsigned int pos = *d, base = '0'; ++ unsigned int negation = (l >> (pos - (base - VFPU_SH_PFX_NEG))) & VFPU_MASK_PFX_NEG; ++ unsigned int constant = (l >> (pos - (base - VFPU_SH_PFX_CST))) & VFPU_MASK_PFX_CST; ++ unsigned int abs_consthi = ++ (l >> (pos - (base - VFPU_SH_PFX_ABS_CSTHI))) & VFPU_MASK_PFX_ABS_CSTHI; ++ unsigned int swz_constlo = (l >> ((pos - base) * 2)) & VFPU_MASK_PFX_SWZ_CSTLO; ++ ++ if (negation) ++ (*info->fprintf_func) (info->stream, "-"); ++ if (constant) ++ { ++ (*info->fprintf_func) (info->stream, "%s", ++ pfx_cst_names[(abs_consthi << 2) | swz_constlo]); ++ } ++ else ++ { ++ if (abs_consthi) ++ (*info->fprintf_func) (info->stream, "|%s|", ++ pfx_swz_names[swz_constlo]); ++ else ++ (*info->fprintf_func) (info->stream, "%s", ++ pfx_swz_names[swz_constlo]); ++ } ++ } ++ break; ++ ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ { ++ unsigned int pos = *d, base = '4'; ++ unsigned int mask = (l >> (pos - (base - VFPU_SH_PFX_MASK))) & VFPU_MASK_PFX_MASK; ++ unsigned int saturation = (l >> ((pos - base) * 2)) & VFPU_MASK_PFX_SAT; ++ ++ if (mask) ++ (*info->fprintf_func) (info->stream, "m"); ++ else ++ (*info->fprintf_func) (info->stream, "%s", ++ pfx_sat_names[saturation]); ++ } ++ break; ++ ++ case 'a': ++ { ++ unsigned int c = (l >> OP_SH_VFPU_CONST) & OP_MASK_VFPU_CONST; ++ if (c < vfpu_num_constants) ++ { ++ (*info->fprintf_func) (info->stream, "%s", ++ vfpu_const_names[c]); ++ } ++ break; ++ } ++ ++ case 'b': ++ /* 5-bit immediate value. */ ++ (*info->fprintf_func) (info->stream, "%d", ++ (l >> OP_SH_VFPU_IMM5) & OP_MASK_VFPU_IMM5); ++ break; ++ ++ case 'c': ++ /* VFPU condition code. */ ++ (*info->fprintf_func) (info->stream, "%d", ++ (l >> OP_SH_VFPU_CC) & OP_MASK_VFPU_CC); ++ break; ++ ++ case 'e': ++ /* 3-bit immediate value. */ ++ (*info->fprintf_func) (info->stream, "%d", ++ (l >> OP_SH_VFPU_IMM3) & OP_MASK_VFPU_IMM3); ++ break; ++ ++ case 'f': ++ /* Conditional compare. */ ++ (*info->fprintf_func) (info->stream, "%s", ++ vfpu_cond_names[(l >> OP_SH_VFPU_COND) & OP_MASK_VFPU_COND]); ++ /* Apparently this specifier is unused. */ ++ d++; ++ break; ++ ++ case 'i': ++ /* 8-bit immediate value. */ ++ (*info->fprintf_func) (info->stream, "0x%02x", ++ (l >> OP_SH_VFPU_IMM8) & OP_MASK_VFPU_IMM8); ++ break; ++ ++ case 'q': ++ /* VFPU control register (vmtvc). */ ++ (*info->fprintf_func) (info->stream, "$%d", ++ (l >> OP_SH_VFPU_VMTVC) & OP_MASK_VFPU_VMTVC); ++ break; ++ ++ case 'r': ++ /* VFPU control register (vmfvc). */ ++ (*info->fprintf_func) (info->stream, "$%d", ++ (l >> OP_SH_VFPU_VMFVC) & OP_MASK_VFPU_VMFVC); ++ break; ++ ++ case 'u': ++ /* Convert a VFPU 16-bit floating-point number to IEEE754. */ ++ { ++ union float2int { ++ unsigned int i; ++ float f; ++ } float2int; ++ unsigned short float16 = (l >> OP_SH_VFPU_FLOAT16) & OP_MASK_VFPU_FLOAT16; ++ unsigned int sign = (float16 >> VFPU_SH_FLOAT16_SIGN) & VFPU_MASK_FLOAT16_SIGN; ++ int exponent = (float16 >> VFPU_SH_FLOAT16_EXP) & VFPU_MASK_FLOAT16_EXP; ++ unsigned int fraction = float16 & VFPU_MASK_FLOAT16_FRAC; ++ char signchar = '+' + ((sign == 1) * 2); ++ ++ if (exponent == VFPU_FLOAT16_EXP_MAX) ++ { ++ if (fraction == 0) ++ (*info->fprintf_func) (info->stream, "%cInf", signchar); ++ else ++ (*info->fprintf_func) (info->stream, "%cNaN", signchar); ++ } ++ else if (exponent == 0 && fraction == 0) ++ { ++ (*info->fprintf_func) (info->stream, "%c0", signchar); ++ } ++ else ++ { ++ if (exponent == 0) ++ { ++ do ++ { ++ fraction <<= 1; ++ exponent--; ++ } ++ while (!(fraction & (VFPU_MASK_FLOAT16_FRAC + 1))); ++ ++ fraction &= VFPU_MASK_FLOAT16_FRAC; ++ } ++ ++ /* Convert to 32-bit single-precision IEEE754. */ ++ float2int.i = sign << 31; ++ float2int.i |= (exponent + 112) << 23; ++ float2int.i |= fraction << 13; ++ (*info->fprintf_func) (info->stream, "%g", float2int.f); ++ } ++ } ++ break; ++ ++ case 'w': ++ { ++ const char *elements[4]; ++ unsigned int opcode = l & VFPU_MASK_OP_SIZE; ++ unsigned int rotators = (l >> OP_SH_VFPU_ROT) & OP_MASK_VFPU_ROT; ++ unsigned int opsize, rothi, rotlo, negation, i; ++ ++ /* Determine the operand size so we'll know how many elements to output. */ ++ if (opcode == VFPU_OP_SIZE_PAIR) ++ opsize = 2; ++ else if (opcode == VFPU_OP_SIZE_TRIPLE) ++ opsize = 3; ++ else ++ opsize = (opcode == VFPU_OP_SIZE_QUAD) * 4; /* Sanity check. */ ++ ++ rothi = (rotators >> VFPU_SH_ROT_HI) & VFPU_MASK_ROT_HI; ++ rotlo = (rotators >> VFPU_SH_ROT_LO) & VFPU_MASK_ROT_LO; ++ negation = (rotators >> VFPU_SH_ROT_NEG) & VFPU_MASK_ROT_NEG; ++ ++ if (rothi == rotlo) ++ { ++ if (negation) ++ { ++ elements[0] = "-s"; ++ elements[1] = "-s"; ++ elements[2] = "-s"; ++ elements[3] = "-s"; ++ } ++ else ++ { ++ elements[0] = "s"; ++ elements[1] = "s"; ++ elements[2] = "s"; ++ elements[3] = "s"; ++ } ++ } ++ else ++ { ++ elements[0] = "0"; ++ elements[1] = "0"; ++ elements[2] = "0"; ++ elements[3] = "0"; ++ } ++ if (negation) ++ elements[rothi] = "-s"; ++ else ++ elements[rothi] = "s"; ++ elements[rotlo] = "c"; ++ ++ (*info->fprintf_func) (info->stream, "["); ++ i = 0; ++ for (;;) ++ { ++ (*info->fprintf_func) (info->stream, "%s", ++ elements[i++]); ++ if (i >= opsize) ++ break; ++ (*info->fprintf_func) (info->stream, ","); ++ } ++ (*info->fprintf_func) (info->stream, "]"); ++ } ++ break; ++ ++ case 'd': ++ case 'm': ++ case 'n': ++ case 's': ++ case 't': ++ case 'v': ++ case 'x': ++ { ++ unsigned int vreg = 0; ++ ++ /* The first char specifies the bitfield that contains the register number. */ ++ switch (*d) ++ { ++ case 'd': ++ case 'v': ++ case 'x': ++ vreg = (l >> OP_SH_VFPU_VD) & OP_MASK_VFPU_VD; ++ break; ++ ++ case 'm': ++ /* Combine bits 0-4 of vt with bits 5-6 of vt. */ ++ vreg = ((l >> OP_SH_VFPU_VT_LO) & OP_MASK_VFPU_VT_LO) ++ | ((l & OP_MASK_VFPU_VT_HI2) << OP_SH_VFPU_VT_HI); ++ break; ++ ++ case 'n': ++ /* Combine bits 0-4 of vt with bit 5 of vt. */ ++ vreg = ((l >> OP_SH_VFPU_VT_LO) & OP_MASK_VFPU_VT_LO) ++ | ((l & OP_MASK_VFPU_VT_HI1) << OP_SH_VFPU_VT_HI); ++ break; ++ ++ case 's': ++ { ++ unsigned int temp_vreg = l >> OP_SH_VFPU_VS; ++ ++ vreg = temp_vreg & OP_MASK_VFPU_VS; ++ if ((l & VFPU_OP_VT_VS_VD) == VFPU_OPCODE_VMMUL) ++ { ++ /* vmmul instructions have the RXC bit (bit 13) inverted. */ ++ if (temp_vreg & 0x20) ++ vreg = temp_vreg & 0x5f; ++ else ++ vreg |= 0x20; ++ } ++ } ++ break; ++ ++ case 't': ++ vreg = (l >> OP_SH_VFPU_VT) & OP_MASK_VFPU_VT; ++ break; ++ } ++ ++ /* The next char is the register set vreg comes from. */ ++ d++; ++ switch (*d) ++ { ++ case '0': ++ (*info->fprintf_func) (info->stream, "%s.s", ++ vfpu_sreg_names[vreg]); ++ break; ++ ++ case '1': ++ (*info->fprintf_func) (info->stream, "%s.p", ++ vfpu_vpreg_names[vreg]); ++ break; ++ ++ case '2': ++ (*info->fprintf_func) (info->stream, "%s.t", ++ vfpu_vtreg_names[vreg]); ++ break; ++ ++ case '3': ++ (*info->fprintf_func) (info->stream, "%s.q", ++ vfpu_vqreg_names[vreg]); ++ break; ++ ++ case '5': ++ (*info->fprintf_func) (info->stream, "%s.p", ++ vfpu_mpreg_names[vreg]); ++ break; ++ ++ case '6': ++ (*info->fprintf_func) (info->stream, "%s.t", ++ vfpu_mtreg_names[vreg]); ++ break; ++ ++ case '7': ++ (*info->fprintf_func) (info->stream, "%s.q", ++ vfpu_mqreg_names[vreg]); ++ break; ++ ++ default: ++ /* xgettext:c-format */ ++ (*info->fprintf_func) (info->stream, ++ _("# internal error, undefined vreg modifier(%c)"), ++ *d); ++ break; ++ } ++ ++ /* The last char is unused for disassembly. */ ++ d++; ++ } ++ break; ++ ++ case 'z': ++ (*info->fprintf_func) (info->stream, "%s", ++ vfpu_rwb_names[(l >> OP_SH_VFPU_RWB) & OP_MASK_VFPU_RWB]); ++ break; ++ } ++ break; ++ + default: + /* xgettext:c-format */ + (*info->fprintf_func) (info->stream, +diff -burN orig.binutils-2.22/opcodes/mips-opc.c binutils-2.22/opcodes/mips-opc.c +--- orig.binutils-2.22/opcodes/mips-opc.c 2011-08-09 17:20:03.000000000 +0200 ++++ binutils-2.22/opcodes/mips-opc.c 2012-01-12 22:06:52.133470527 +0100 +@@ -121,6 +121,7 @@ + #define N5 (INSN_5400 | INSN_5500) + #define N54 INSN_5400 + #define N55 INSN_5500 ++#define AL INSN_ALLEGREX + #define IOCT INSN_OCTEON + #define XLR INSN_XLR + +@@ -402,6 +403,7 @@ + {"bnel", "s,t,p", 0x54000000, 0xfc000000, CBL|RD_s|RD_t, 0, I2|T3 }, + {"bnel", "s,I,p", 0, (int) M_BNEL_I, INSN_MACRO, 0, I2|T3 }, + {"break", "", 0x0000000d, 0xffffffff, TRAP, 0, I1 }, ++{"break", "B", 0x0000000d, 0xfc00003f, TRAP, 0, AL }, + {"break", "c", 0x0000000d, 0xfc00ffff, TRAP, 0, I1 }, + {"break", "c,q", 0x0000000d, 0xfc00003f, TRAP, 0, I1 }, + {"c.f.d", "S,T", 0x46200030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, +@@ -584,7 +586,7 @@ + {"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|AL}, + {"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 }, +@@ -602,7 +604,9 @@ + {"cins", "t,r,+P,+S",0x70000033, 0xfc00003f, WR_t|RD_s, 0, IOCT }, /* cins32 */ + {"cins", "t,r,+p,+s",0x70000032, 0xfc00003f, WR_t|RD_s, 0, IOCT }, + {"clo", "U,s", 0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, ++{"clo", "d,s", 0x00000017, 0xfc1f07ff, WR_d|RD_s, 0, AL }, + {"clz", "U,s", 0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, ++{"clz", "d,s", 0x00000016, 0xfc1f07ff, WR_d|RD_s, 0, AL }, + {"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, + {"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, + {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, +@@ -627,16 +631,16 @@ + {"cvt.ps.s","D,V,T", 0x46000026, 0xffe0003f, WR_D|RD_S|RD_T|FP_S|FP_D, 0, I5_33 }, + {"cvt.pw.ps", "D,S", 0x46c00024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, + {"dabs", "d,v", 0, (int) M_DABS, INSN_MACRO, 0, I3 }, ++{"max", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, AL }, + {"dadd", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, + {"dadd", "t,r,I", 0, (int) M_DADD_I, INSN_MACRO, 0, I3 }, +-{"dadd", "D,S,T", 0x45e00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, +-{"dadd", "D,S,T", 0x4b60000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F|IL3A }, + {"daddi", "t,r,j", 0x60000000, 0xfc000000, WR_t|RD_s, 0, I3 }, + {"daddiu", "t,r,j", 0x64000000, 0xfc000000, WR_t|RD_s, 0, I3 }, ++{"min", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, AL }, + {"daddu", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, + {"daddu", "t,r,I", 0, (int) M_DADDU_I, INSN_MACRO, 0, I3 }, + {"daddwc", "d,s,t", 0x70000038, 0xfc0007ff, WR_d|RD_s|RD_t|WR_C0|RD_C0, 0, XLR }, +-{"dbreak", "", 0x7000003f, 0xffffffff, 0, 0, N5 }, ++{"dbreak", "", 0x7000003f, 0xffffffff, 0, 0, N5|AL }, + {"dclo", "U,s", 0x70000025, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, + {"dclz", "U,s", 0x70000024, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, + /* dctr and dctw are used on the r5000. */ +@@ -725,7 +729,7 @@ + {"dremu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, + {"dremu", "d,v,t", 0, (int) M_DREMU_3, INSN_MACRO, 0, I3 }, + {"dremu", "d,v,I", 0, (int) M_DREMU_3I, INSN_MACRO, 0, I3 }, +-{"dret", "", 0x7000003e, 0xffffffff, 0, 0, N5 }, ++{"dret", "", 0x7000003e, 0xffffffff, 0, 0, N5|AL }, + {"drol", "d,v,t", 0, (int) M_DROL, INSN_MACRO, 0, I3 }, + {"drol", "d,v,I", 0, (int) M_DROL_I, INSN_MACRO, 0, I3 }, + {"dror", "d,v,t", 0, (int) M_DROR, INSN_MACRO, 0, I3 }, +@@ -774,10 +778,10 @@ + {"ei", "t", 0x41606020, 0xffe0ffff, WR_t|WR_C0, 0, I33|IOCT}, + {"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, + {"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, +-{"eret", "", 0x42000018, 0xffffffff, NODS, 0, I3_32 }, ++{"eret", "", 0x42000018, 0xffffffff, NODS, 0, I3_32|AL }, + {"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, + {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, +-{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, ++{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33|AL }, + {"exts32", "t,r,+p,+S",0x7000003b, 0xfc00003f, WR_t|RD_s, 0, IOCT }, + {"exts", "t,r,+P,+S",0x7000003b, 0xfc00003f, WR_t|RD_s, 0, IOCT }, /* exts32 */ + {"exts", "t,r,+p,+s",0x7000003a, 0xfc00003f, WR_t|RD_s, 0, IOCT }, +@@ -786,7 +790,7 @@ + {"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, + {"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, + {"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, +-{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 }, ++{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33|AL }, + {"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC }, + {"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, + /* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with +@@ -829,18 +833,10 @@ + {"ldaddw", "t,b", 0x70000010, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, + {"ldaddwu", "t,b", 0x70000011, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, + {"ldaddd", "t,b", 0x70000012, 0xfc00ffff, SM|RD_t|WR_t|RD_b, 0, XLR }, +-{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, +-{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, +-{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, +-{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, +-{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, /* ldc1 */ +-{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, INSN2_M_FP_D, I1 }, +-{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, INSN2_M_FP_D, I1 }, +-{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, +-{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, 0, I2 }, +-{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, +-{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, 0, I2 }, +-{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, ++/* ldc1 is at the bottom of the table. */ ++/* ldc2 is at the bottom of the table. */ ++/* ldc3 is at the bottom of the table. */ ++{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3|AL }, + {"ldl", "t,A(b)", 0, (int) M_LDL_AB, INSN_MACRO, 0, I3 }, + {"ldr", "t,o(b)", 0x6c000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, + {"ldr", "t,A(b)", 0, (int) M_LDR_AB, INSN_MACRO, 0, I3 }, +@@ -870,8 +866,7 @@ + {"lwc1", "E,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, + {"l.s", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, 0, I1 }, /* lwc1 */ + {"l.s", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, +-{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, +-{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, 0, I1 }, ++/* lwc2 is at the bottom of the table. */ + {"lwc3", "E,o(b)", 0xcc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, + {"lwc3", "E,A(b)", 0, (int) M_LWC3_AB, INSN_MACRO, 0, I1 }, + {"lwl", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, +@@ -911,12 +906,14 @@ + {"madd.ps", "D,S,T", 0x45600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, + {"madd.ps", "D,S,T", 0x71600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, + {"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, ++{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, + {"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, + {"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, + {"madd", "7,s,t", 0x70000000, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, + {"maddp", "s,t", 0x70000441, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, + {"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, ++{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, + {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, + {"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, + {"maddu", "7,s,t", 0x70000001, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, +@@ -957,7 +954,7 @@ + /* mfc2 is at the bottom of the table. */ + /* mfhc2 is at the bottom of the table. */ + /* mfc3 is at the bottom of the table. */ +-{"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, ++{"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5|AL }, + {"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, 0, I1 }, + {"mfhi", "d,9", 0x00000010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, + {"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, 0, I1 }, +@@ -979,7 +976,7 @@ + {"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|AL }, + {"movnz", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IL2E|IL2F|IL3A }, + {"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 }, +@@ -993,7 +990,7 @@ + {"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|AL }, + {"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 }, +@@ -1021,9 +1018,11 @@ + {"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", 0x0000002e, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, + {"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, + {"msub", "7,s,t", 0x70000004, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, ++{"msubu", "s,t", 0x0000002f, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, AL }, + {"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, + {"msubu", "7,s,t", 0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"mtpc", "t,P", 0x4080c801, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 }, +@@ -1038,7 +1037,7 @@ + /* mtc2 is at the bottom of the table. */ + /* mthc2 is at the bottom of the table. */ + /* mtc3 is at the bottom of the table. */ +-{"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, ++{"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5|AL }, + {"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, 0, I1 }, + {"mthi", "s,7", 0x00000011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, + {"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, 0, I1 }, +@@ -1223,13 +1222,13 @@ + {"rol", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I1 }, + {"ror", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I1 }, + {"ror", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I1 }, +-{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT }, +-{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT }, +-{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT }, +-{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT }, +-{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT }, +-{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT }, +-{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT }, ++{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT|AL }, ++{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT|AL }, ++{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT|AL }, ++{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT|AL }, ++{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT|AL }, ++{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT|AL }, ++{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT|AL }, + {"round.l.d", "D,S", 0x46200008, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, + {"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, + {"round.w.d", "D,S", 0x4620000c, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, +@@ -1262,24 +1261,17 @@ + {"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, 0, G2 }, + {"sdbbp", "", 0x7000003f, 0xffffffff, TRAP, 0, I32 }, + {"sdbbp", "B", 0x7000003f, 0xfc00003f, TRAP, 0, I32 }, +-{"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 }, +-{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, INSN2_M_FP_D, I2 }, +-{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I2 }, +-{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, 0, I2 }, +-{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, 0, I2 }, +-{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, 0, I2 }, +-{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, +-{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, INSN2_M_FP_D, I1 }, +-{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, INSN2_M_FP_D, I1 }, +-{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, ++/* sdc1 is at the bottom of the table. */ ++/* sdc2 is at the bottom of the table. */ ++/* sdc3 is at the bottom of the table. */ ++/* s.d (sdc1 is at the bottom of the table. */ ++{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, 0, I3|AL }, + {"sdl", "t,A(b)", 0, (int) M_SDL_AB, INSN_MACRO, 0, I3 }, + {"sdr", "t,o(b)", 0xb4000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, + {"sdr", "t,A(b)", 0, (int) M_SDR_AB, INSN_MACRO, 0, I3 }, + {"sdxc1", "S,t(b)", 0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_D, 0, I4_33 }, +-{"seb", "d,w", 0x7c000420, 0xffe007ff, WR_d|RD_t, 0, I33 }, +-{"seh", "d,w", 0x7c000620, 0xffe007ff, WR_d|RD_t, 0, I33 }, ++{"seb", "d,w", 0x7c000420, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, ++{"seh", "d,w", 0x7c000620, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, + {"selsl", "d,v,t", 0x00000005, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, + {"selsr", "d,v,t", 0x00000001, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, + {"seq", "d,v,t", 0x7000002a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IOCT }, +@@ -1399,8 +1391,7 @@ + {"swc1", "E,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, + {"s.s", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, 0, I1 }, /* swc1 */ + {"s.s", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, INSN2_M_FP_S, I1 }, +-{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I1 }, +-{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, 0, I1 }, ++/* swc2 is at the bottom of the table. */ + {"swc3", "E,o(b)", 0xec000000, 0xfc000000, SM|RD_C3|RD_b, 0, I1 }, + {"swc3", "E,A(b)", 0, (int) M_SWC3_AB, INSN_MACRO, 0, I1 }, + {"swl", "t,o(b)", 0xa8000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, +@@ -1497,7 +1488,8 @@ + {"wait", "J", 0x42000020, 0xfe00003f, NODS, 0, I32|N55 }, + {"waiti", "", 0x42000020, 0xffffffff, NODS, 0, L1 }, + {"wrpgpr", "d,w", 0x41c00000, 0xffe007ff, RD_t, 0, I33 }, +-{"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33 }, ++{"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33|AL }, ++{"wsbw", "d,t", 0x7c0000e0, 0xffe007ff, WR_d|RD_t, 0, AL }, + {"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, + {"xor", "t,r,I", 0, (int) M_XOR_I, INSN_MACRO, 0, I1 }, + {"xor", "D,S,T", 0x47800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, +@@ -1511,6 +1503,321 @@ + {"yield", "s", 0x7c000009, 0xfc1fffff, NODS|RD_s, 0, MT32 }, + {"yield", "d,s", 0x7c000009, 0xfc1f07ff, NODS|WR_d|RD_s, 0, MT32 }, + ++/* Sony Allegrex CPU core. */ ++{"bitrev", "d,t", 0x7c000520, 0xffe007ff, WR_d|RD_t, 0, AL }, ++/* From "MIPS DSP ASU", because instructions with the same name need to be next to each other */ ++{"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, ++{"mfic", "t,G", 0x70000024, 0xffe007ff, LCD|WR_t|RD_C0, 0, AL }, ++{"mtic", "t,G", 0x70000026, 0xffe007ff, COD|RD_t|WR_C0, 0, AL }, ++ ++/* Sony Allegrex VFPU instructions. */ ++{"bvf", "?c,p", 0x49000000, 0xffe30000, CBD|RD_CC, 0, AL }, ++{"bvfl", "?c,p", 0x49020000, 0xffe30000, CBL|RD_CC, 0, AL }, ++{"bvt", "?c,p", 0x49010000, 0xffe30000, CBD|RD_CC, 0, AL }, ++{"bvtl", "?c,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, AL }, ++{"lv.s", "?m0x,?o(b)", 0xc8000000, 0xfc000000, CLD|RD_s|WR_CC, 0, AL }, ++{"lv.s", "?m0x,A(b)", 0, (int) M_LV_Q_AB, INSN_MACRO, 0, AL }, ++{"ulv.s", "?m0x,o(b)", 0, (int) M_ULV_S, INSN_MACRO, 0, AL }, ++{"lv.q", "?n3x,?o(b)", 0xd8000000, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, ++{"lv.q", "?n3x,A(b)", 0, (int) M_LV_Q_AB_2, INSN_MACRO, 0, AL }, ++{"ulv.q", "?n3x,?o(b)", 0, (int) M_ULV_Q, INSN_MACRO, 0, AL }, ++{"ulv.q", "?n3x,A(b)", 0, (int) M_ULV_Q_AB, INSN_MACRO, 0, AL }, ++{"lvi.s", "?t0x,l?y0", 0, (int) M_LVI_S, INSN_MACRO, 0, AL }, ++{"lvi.p", "?t1x,?[l?y0,l?y1?]", 0, (int) M_LVI_P, INSN_MACRO, 0, AL }, ++{"lvi.t", "?t2x,?[l?y0,l?y1,l?y2?]", 0, (int) M_LVI_T, INSN_MACRO, 0, AL }, ++{"lvi.q", "?t3x,?[l?y0,l?y1,l?y2,l?y3?]", 0, (int) M_LVI_Q, INSN_MACRO, 0, AL }, ++{"lvhi.s", "?t0x,?[?u?y0,?u?y1?]", 0, (int) M_LVHI_S, INSN_MACRO, 0, AL }, ++{"lvhi.p", "?t1x,?[?u?y0,?u?y1,?u?y2,?u?y3?]", 0, (int) M_LVHI_P, INSN_MACRO, 0, AL }, ++{"sv.s", "?m0x,?o(b)", 0xe8000000, 0xfc000000, SM|RD_s|RD_C2, 0, AL }, ++{"sv.s", "?m0x,A(b)", 0, (int) M_SV_S_AB, INSN_MACRO, 0, AL }, ++{"usv.s", "?m0x,o(b)", 0, (int) M_USV_S, INSN_MACRO, 0, AL }, ++{"sv.q", "?n3x,?o(b)", 0xf8000000, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, ++{"sv.q", "?n3x,?o(b),?z", 0xf8000000, 0xfc000000, SM|RD_s|RD_C2, 0, AL }, ++{"sv.q", "?n3x,A(b)", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, ++{"sv.q", "?n3x,A(b),?z", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, ++{"sv.q", "?n3x,A,?z", 0, (int) M_SV_Q_AB, INSN_MACRO, 0, AL }, ++{"usv.q", "?n3x,?o(b)", 0, (int) M_USV_Q, INSN_MACRO, 0, AL }, ++{"usv.q", "?n3x,A(b)", 0, (int) M_USV_Q_AB, INSN_MACRO, 0, AL }, ++{"vwb.q", "?n3x,?o(b)", 0xf8000002, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, ++{"lvl.q", "?n3x,?o(b)", 0xd4000000, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, ++{"lvl.q", "?n3x,A(b)", 0, (int) M_LVL_Q_AB, INSN_MACRO, 0, AL }, ++{"lvr.q", "?n3x,?o(b)", 0xd4000002, 0xfc000002, CLD|RD_s|WR_CC, 0, AL }, ++{"lvr.q", "?n3x,A(b)", 0, (int) M_LVR_Q_AB, INSN_MACRO, 0, AL }, ++{"svl.q", "?n3x,?o(b)", 0xf4000000, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, ++{"svl.q", "?n3x,A(b)", 0, (int) M_SVL_Q_AB, INSN_MACRO, 0, AL }, ++{"svr.q", "?n3x,?o(b)", 0xf4000002, 0xfc000002, SM|RD_s|RD_C2, 0, AL }, ++{"svr.q", "?n3x,A(b)", 0, (int) M_SVR_Q_AB, INSN_MACRO, 0, AL }, ++{"mtv", "t,?d0z", 0x48e00000, 0xffe0ff80, LCD|WR_t|WR_C2, 0, AL }, ++{"mfv", "t,?d0z", 0x48600000, 0xffe0ff80, COD|RD_t|WR_CC|RD_C2, 0, AL }, ++{"mtvc", "t,?q", 0x48e00000, 0xffe0ff00, LCD|WR_t|WR_C2, 0, AL }, ++{"mfvc", "t,?q", 0x48600000, 0xffe0ff00, COD|RD_t|WR_CC|RD_C2, 0, AL }, ++{"vmtvc", "?q,?s0y", 0xd0510000, 0xffff8000, WR_C2, 0, AL }, ++{"vmfvc", "?d0z,?r", 0xd0500000, 0xffff0080, RD_C2, 0, AL }, ++{"vadd.q", "?d3d,?s3s,?t3t", 0x60008080, 0xff808080, RD_C2, 0, AL }, ++{"vsub.q", "?d3d,?s3s,?t3t", 0x60808080, 0xff808080, RD_C2, 0, AL }, ++{"vdiv.q", "?x3z,?s3y,?t3x", 0x63808080, 0xff808080, RD_C2, 0, AL }, ++{"vmul.q", "?d3d,?s3s,?t3t", 0x64008080, 0xff808080, RD_C2, 0, AL }, ++{"vdot.q", "?d0d,?s3s,?t3t", 0x64808080, 0xff808080, RD_C2, 0, AL }, ++{"vscl.q", "?d3d,?s3s,?t0x", 0x65008080, 0xff808080, RD_C2, 0, AL }, ++{"vhdp.q", "?d0d,?s3y,?t3t", 0x66008080, 0xff808080, RD_C2, 0, AL }, ++{"vcmp.q", "?f2,?s3s,?t3t", 0x6c008080, 0xff8080f0, RD_C2, 0, AL }, ++{"vcmp.q", "?f1,?s3s", 0x6c008080, 0xffff80f0, RD_C2, 0, AL }, ++{"vcmp.q", "?f0", 0x6c008080, 0xfffffff0, RD_C2, 0, AL }, ++{"vmin.q", "?d3d,?s3s,?t3t", 0x6d008080, 0xff808080, RD_C2, 0, AL }, ++{"vmax.q", "?d3d,?s3s,?t3t", 0x6d808080, 0xff808080, RD_C2, 0, AL }, ++{"vsgn.q", "?d3d,?s3s", 0xd04a8080, 0xffff8080, RD_C2, 0, AL }, ++{"vcst.q", "?d3d,?a", 0xd0608080, 0xffe0ff80, RD_C2, 0, AL }, ++{"vscmp.q", "?d3d,?s3s,?t3t", 0x6e808080, 0xff808080, RD_C2, 0, AL }, ++{"vsge.q", "?d3d,?s3s,?t3t", 0x6f008080, 0xff808080, RD_C2, 0, AL }, ++{"vslt.q", "?d3d,?s3s,?t3t", 0x6f808080, 0xff808080, RD_C2, 0, AL }, ++{"vi2uc.q", "?d0m,?s3w", 0xd03c8080, 0xffff8080, RD_C2, 0, AL }, ++{"vi2c.q", "?d0m,?s3w", 0xd03d8080, 0xffff8080, RD_C2, 0, AL }, ++{"vi2us.q", "?d1m,?s3w", 0xd03e8080, 0xffff8080, RD_C2, 0, AL }, ++{"vi2s.q", "?d1m,?s3w", 0xd03f8080, 0xffff8080, RD_C2, 0, AL }, ++{"vmov.q", "?d3d,?s3s", 0xd0008080, 0xffff8080, RD_C2, 0, AL }, ++{"vabs.q", "?d3d,?s3w", 0xd0018080, 0xffff8080, RD_C2, 0, AL }, ++{"vneg.q", "?d3d,?s3w", 0xd0028080, 0xffff8080, RD_C2, 0, AL }, ++{"vidt.q", "?d3d", 0xd0038080, 0xffffff80, RD_C2, 0, AL }, ++{"vsat0.q", "?d3z,?s3s", 0xd0048080, 0xffff8080, RD_C2, 0, AL }, ++{"vsat1.q", "?d3z,?s3s", 0xd0058080, 0xffff8080, RD_C2, 0, AL }, ++{"vzero.q", "?d3d", 0xd0068080, 0xffffff80, RD_C2, 0, AL }, ++{"vone.q", "?d3d", 0xd0078080, 0xffffff80, RD_C2, 0, AL }, ++{"vrcp.q", "?x3z,?s3y", 0xd0108080, 0xffff8080, RD_C2, 0, AL }, ++{"vrsq.q", "?x3z,?s3y", 0xd0118080, 0xffff8080, RD_C2, 0, AL }, ++{"vsin.q", "?x3z,?s3y", 0xd0128080, 0xffff8080, RD_C2, 0, AL }, ++{"vcos.q", "?x3z,?s3y", 0xd0138080, 0xffff8080, RD_C2, 0, AL }, ++{"vexp2.q", "?x3z,?s3y", 0xd0148080, 0xffff8080, RD_C2, 0, AL }, ++{"vlog2.q", "?x3z,?s3y", 0xd0158080, 0xffff8080, RD_C2, 0, AL }, ++{"vsqrt.q", "?x3z,?s3y", 0xd0168080, 0xffff8080, RD_C2, 0, AL }, ++{"vasin.q", "?x3z,?s3y", 0xd0178080, 0xffff8080, RD_C2, 0, AL }, ++{"vnrcp.q", "?x3z,?s3y", 0xd0188080, 0xffff8080, RD_C2, 0, AL }, ++{"vnsin.q", "?x3z,?s3y", 0xd01a8080, 0xffff8080, RD_C2, 0, AL }, ++{"vrexp2.q", "?x3z,?s3y", 0xd01c8080, 0xffff8080, RD_C2, 0, AL }, ++{"vrndi.q", "?d3z", 0xd0218080, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf1.q", "?d3z", 0xd0228080, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf2.q", "?d3z", 0xd0238080, 0xffffff80, RD_C2, 0, AL }, ++{"vf2h.q", "?d1m,?s3s", 0xd0328080, 0xffff8080, RD_C2, 0, AL }, ++{"vsrt1.q", "?d3d,?s3s", 0xd0408080, 0xffff8080, RD_C2, 0, AL }, ++{"vsrt2.q", "?d3d,?s3s", 0xd0418080, 0xffff8080, RD_C2, 0, AL }, ++{"vsrt3.q", "?d3d,?s3s", 0xd0488080, 0xffff8080, RD_C2, 0, AL }, ++{"vsrt4.q", "?d3d,?s3s", 0xd0498080, 0xffff8080, RD_C2, 0, AL }, ++{"vbfy1.q", "?d3d,?s3s", 0xd0428080, 0xffff8080, RD_C2, 0, AL }, ++{"vbfy2.q", "?d3d,?s3s", 0xd0438080, 0xffff8080, RD_C2, 0, AL }, ++{"vocp.q", "?d3d,?s3y", 0xd0448080, 0xffff8080, RD_C2, 0, AL }, ++{"vfad.q", "?d0d,?s3s", 0xd0468080, 0xffff8080, RD_C2, 0, AL }, ++{"vavg.q", "?d0d,?s3s", 0xd0478080, 0xffff8080, RD_C2, 0, AL }, ++{"vf2in.q", "?d3m,?s3s,?b", 0xd2008080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iz.q", "?d3m,?s3s,?b", 0xd2208080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iu.q", "?d3m,?s3s,?b", 0xd2408080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2id.q", "?d3m,?s3s,?b", 0xd2608080, 0xffe08080, RD_C2, 0, AL }, ++{"vi2f.q", "?d3d,?s3w,?b", 0xd2808080, 0xffe08080, RD_C2, 0, AL }, ++{"vcmov.q", "?d3d,?s3s,?e", 0, (int) M_VCMOV_Q, INSN_MACRO, 0, AL }, ++{"vcmovt.q", "?d3d,?s3s,?e", 0xd2a08080, 0xfff88080, RD_C2, 0, AL }, ++{"vcmovf.q", "?d3d,?s3s,?e", 0xd2a88080, 0xfff88080, RD_C2, 0, AL }, ++{"vmmul.q", "?v7z,?s7y,?t7x", 0xf0008080, 0xff808080, RD_C2, 0, AL }, ++{"vtfm4.q", "?v3z,?s7y,?t3x", 0xf1808080, 0xff808080, RD_C2, 0, AL }, ++{"vhtfm4.q", "?v3z,?s7y,?t3x", 0xf1808000, 0xff808080, RD_C2, 0, AL }, ++{"vmscl.q", "?x7z,?s7y,?t0x", 0xf2008080, 0xff808080, RD_C2, 0, AL }, ++{"vqmul.q", "?v3z,?s3y,?t3x", 0xf2808080, 0xff808080, RD_C2, 0, AL }, ++{"vmmov.q", "?x7z,?s7y", 0xf3808080, 0xffff8080, RD_C2, 0, AL }, ++{"vmidt.q", "?d7z", 0xf3838080, 0xffffff80, RD_C2, 0, AL }, ++{"vmzero.q", "?d7z", 0xf3868080, 0xffffff80, RD_C2, 0, AL }, ++{"vmone.q", "?d7z", 0xf3878080, 0xffffff80, RD_C2, 0, AL }, ++{"vrot.q", "?x3z,?s0y,?w", 0xf3a08080, 0xffe08080, RD_C2, 0, AL }, ++{"vt4444.q", "?d1z,?s3w", 0xd0598080, 0xffff8080, RD_C2, 0, AL }, ++{"vt5551.q", "?d1z,?s3w", 0xd05a8080, 0xffff8080, RD_C2, 0, AL }, ++{"vt5650.q", "?d1z,?s3w", 0xd05b8080, 0xffff8080, RD_C2, 0, AL }, ++{"vadd.t", "?d2d,?s2s,?t2t", 0x60008000, 0xff808080, RD_C2, 0, AL }, ++{"vsub.t", "?d2d,?s2s,?t2t", 0x60808000, 0xff808080, RD_C2, 0, AL }, ++{"vdiv.t", "?x2z,?s2y,?t2x", 0x63808000, 0xff808080, RD_C2, 0, AL }, ++{"vmul.t", "?d2d,?s2s,?t2t", 0x64008000, 0xff808080, RD_C2, 0, AL }, ++{"vdot.t", "?d0d,?s2s,?t2t", 0x64808000, 0xff808080, RD_C2, 0, AL }, ++{"vscl.t", "?d2d,?s2s,?t0x", 0x65008000, 0xff808080, RD_C2, 0, AL }, ++{"vhdp.t", "?d0d,?s2y,?t2t", 0x66008000, 0xff808080, RD_C2, 0, AL }, ++{"vcrs.t", "?d2d,?s2y,?t2x", 0x66808000, 0xff808080, RD_C2, 0, AL }, ++{"vcmp.t", "?f2,?s2s,?t2t", 0x6c008000, 0xff8080f0, RD_C2, 0, AL }, ++{"vcmp.t", "?f1,?s2s", 0x6c008000, 0xffff80f0, RD_C2, 0, AL }, ++{"vcmp.t", "?f0", 0x6c008000, 0xfffffff0, RD_C2, 0, AL }, ++{"vmin.t", "?d2d,?s2s,?t2t", 0x6d008000, 0xff808080, RD_C2, 0, AL }, ++{"vmax.t", "?d2d,?s2s,?t2t", 0x6d808000, 0xff808080, RD_C2, 0, AL }, ++{"vsgn.t", "?d2d,?s2s", 0xd04a8000, 0xffff8080, RD_C2, 0, AL }, ++{"vcst.t", "?d2d,?a", 0xd0608000, 0xffe0ff80, RD_C2, 0, AL }, ++{"vscmp.t", "?d2d,?s2s,?t2t", 0x6e808000, 0xff808080, RD_C2, 0, AL }, ++{"vsge.t", "?d2d,?s2s,?t2t", 0x6f008000, 0xff808080, RD_C2, 0, AL }, ++{"vslt.t", "?d2d,?s2s,?t2t", 0x6f808000, 0xff808080, RD_C2, 0, AL }, ++{"vmov.t", "?d2d,?s2s", 0xd0008000, 0xffff8080, RD_C2, 0, AL }, ++{"vabs.t", "?d2d,?s2w", 0xd0018000, 0xffff8080, RD_C2, 0, AL }, ++{"vneg.t", "?d2d,?s2w", 0xd0028000, 0xffff8080, RD_C2, 0, AL }, ++{"vsat0.t", "?d2z,?s2s", 0xd0048000, 0xffff8080, RD_C2, 0, AL }, ++{"vsat1.t", "?d2z,?s2s", 0xd0058000, 0xffff8080, RD_C2, 0, AL }, ++{"vzero.t", "?d2d", 0xd0068000, 0xffffff80, RD_C2, 0, AL }, ++{"vone.t", "?d2d", 0xd0078000, 0xffffff80, RD_C2, 0, AL }, ++{"vrcp.t", "?x2z,?s2y", 0xd0108000, 0xffff8080, RD_C2, 0, AL }, ++{"vrsq.t", "?x2z,?s2y", 0xd0118000, 0xffff8080, RD_C2, 0, AL }, ++{"vsin.t", "?x2z,?s2y", 0xd0128000, 0xffff8080, RD_C2, 0, AL }, ++{"vcos.t", "?x2z,?s2y", 0xd0138000, 0xffff8080, RD_C2, 0, AL }, ++{"vexp2.t", "?x2z,?s2y", 0xd0148000, 0xffff8080, RD_C2, 0, AL }, ++{"vlog2.t", "?x2z,?s2y", 0xd0158000, 0xffff8080, RD_C2, 0, AL }, ++{"vsqrt.t", "?x2z,?s2y", 0xd0168000, 0xffff8080, RD_C2, 0, AL }, ++{"vasin.t", "?x2z,?s2y", 0xd0178000, 0xffff8080, RD_C2, 0, AL }, ++{"vnrcp.t", "?x2z,?s2y", 0xd0188000, 0xffff8080, RD_C2, 0, AL }, ++{"vnsin.t", "?x2z,?s2y", 0xd01a8000, 0xffff8080, RD_C2, 0, AL }, ++{"vrexp2.t", "?x2z,?s2y", 0xd01c8000, 0xffff8080, RD_C2, 0, AL }, ++{"vrndi.t", "?d2z", 0xd0218000, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf1.t", "?d2z", 0xd0228000, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf2.t", "?d2z", 0xd0238000, 0xffffff80, RD_C2, 0, AL }, ++{"vocp.t", "?d2d,?s2y", 0xd0448000, 0xffff8080, RD_C2, 0, AL }, ++{"vfad.t", "?d0d,?s2s", 0xd0468000, 0xffff8080, RD_C2, 0, AL }, ++{"vavg.t", "?d0d,?s2s", 0xd0478000, 0xffff8080, RD_C2, 0, AL }, ++{"vf2in.t", "?d2m,?s2s,?b", 0xd2008000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iz.t", "?d2m,?s2s,?b", 0xd2208000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iu.t", "?d2m,?s2s,?b", 0xd2408000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2id.t", "?d2m,?s2s,?b", 0xd2608000, 0xffe08080, RD_C2, 0, AL }, ++{"vi2f.t", "?d2d,?s2w,?b", 0xd2808000, 0xffe08080, RD_C2, 0, AL }, ++{"vcmov.t", "?d2d,?s2s,?e", 0, (int) M_VCMOV_T, INSN_MACRO, 0, AL }, ++{"vcmovt.t", "?d2d,?s2s,?e", 0xd2a08000, 0xfff88080, RD_C2, 0, AL }, ++{"vcmovf.t", "?d2d,?s2s,?e", 0xd2a88000, 0xfff88080, RD_C2, 0, AL }, ++{"vmmul.t", "?v6z,?s6y,?t6x", 0xf0008000, 0xff808080, RD_C2, 0, AL }, ++{"vtfm3.t", "?v2z,?s6y,?t2x", 0xf1008000, 0xff808080, RD_C2, 0, AL }, ++{"vhtfm3.t", "?v2z,?s6y,?t2x", 0xf1000080, 0xff808080, RD_C2, 0, AL }, ++{"vmscl.t", "?x6z,?s6y,?t0x", 0xf2008000, 0xff808080, RD_C2, 0, AL }, ++{"vmmov.t", "?x6z,?s6y", 0xf3808000, 0xffff8080, RD_C2, 0, AL }, ++{"vmidt.t", "?d6z", 0xf3838000, 0xffffff80, RD_C2, 0, AL }, ++{"vmzero.t", "?d6z", 0xf3868000, 0xffffff80, RD_C2, 0, AL }, ++{"vmone.t", "?d6z", 0xf3878000, 0xffffff80, RD_C2, 0, AL }, ++{"vrot.t", "?x2z,?s0y,?w", 0xf3a08000, 0xffe08080, RD_C2, 0, AL }, ++{"vcrsp.t", "?d2z,?s2y,?t2x", 0xf2808000, 0xff808080, RD_C2, 0, AL }, ++{"vadd.p", "?d1d,?s1s,?t1t", 0x60000080, 0xff808080, RD_C2, 0, AL }, ++{"vsub.p", "?d1d,?s1s,?t1t", 0x60800080, 0xff808080, RD_C2, 0, AL }, ++{"vdiv.p", "?x1z,?s1y,?t1x", 0x63800080, 0xff808080, RD_C2, 0, AL }, ++{"vmul.p", "?d1d,?s1s,?t1t", 0x64000080, 0xff808080, RD_C2, 0, AL }, ++{"vdot.p", "?d0d,?s1s,?t1t", 0x64800080, 0xff808080, RD_C2, 0, AL }, ++{"vscl.p", "?d1d,?s1s,?t0x", 0x65000080, 0xff808080, RD_C2, 0, AL }, ++{"vhdp.p", "?d0d,?s1y,?t1t", 0x66000080, 0xff808080, RD_C2, 0, AL }, ++{"vdet.p", "?d0d,?s1s,?t1x", 0x67000080, 0xff808080, RD_C2, 0, AL }, ++{"vcmp.p", "?f2,?s1s,?t1t", 0x6c000080, 0xff8080f0, RD_C2, 0, AL }, ++{"vcmp.p", "?f1,?s1s", 0x6c000080, 0xffff80f0, RD_C2, 0, AL }, ++{"vcmp.p", "?f0", 0x6c000080, 0xfffffff0, RD_C2, 0, AL }, ++{"vmin.p", "?d1d,?s1s,?t1t", 0x6d000080, 0xff808080, RD_C2, 0, AL }, ++{"vmax.p", "?d1d,?s1s,?t1t", 0x6d800080, 0xff808080, RD_C2, 0, AL }, ++{"vsgn.p", "?d1d,?s1s", 0xd04a0080, 0xffff8080, RD_C2, 0, AL }, ++{"vcst.p", "?d1d,?a", 0xd0600080, 0xffe0ff80, RD_C2, 0, AL }, ++{"vscmp.p", "?d1d,?s1s,?t1t", 0x6e800080, 0xff808080, RD_C2, 0, AL }, ++{"vsge.p", "?d1d,?s1s,?t1t", 0x6f000080, 0xff808080, RD_C2, 0, AL }, ++{"vslt.p", "?d1d,?s1s,?t1t", 0x6f800080, 0xff808080, RD_C2, 0, AL }, ++{"vus2i.p", "?d3m,?s1y", 0xd03a0080, 0xffff8080, RD_C2, 0, AL }, ++{"vs2i.p", "?d3m,?s1y", 0xd03b0080, 0xffff8080, RD_C2, 0, AL }, ++{"vi2us.p", "?d0m,?s1w", 0xd03e0080, 0xffff8080, RD_C2, 0, AL }, ++{"vi2s.p", "?d0m,?s1w", 0xd03f0080, 0xffff8080, RD_C2, 0, AL }, ++{"vmov.p", "?d1d,?s1s", 0xd0000080, 0xffff8080, RD_C2, 0, AL }, ++{"vabs.p", "?d1d,?s1w", 0xd0010080, 0xffff8080, RD_C2, 0, AL }, ++{"vneg.p", "?d1d,?s1w", 0xd0020080, 0xffff8080, RD_C2, 0, AL }, ++{"vidt.p", "?d1d", 0xd0030080, 0xffffff80, RD_C2, 0, AL }, ++{"vsat0.p", "?d1z,?s1s", 0xd0040080, 0xffff8080, RD_C2, 0, AL }, ++{"vsat1.p", "?d1z,?s1s", 0xd0050080, 0xffff8080, RD_C2, 0, AL }, ++{"vzero.p", "?d1d", 0xd0060080, 0xffffff80, RD_C2, 0, AL }, ++{"vone.p", "?d1d", 0xd0070080, 0xffffff80, RD_C2, 0, AL }, ++{"vrcp.p", "?x1z,?s1y", 0xd0100080, 0xffff8080, RD_C2, 0, AL }, ++{"vrsq.p", "?x1z,?s1y", 0xd0110080, 0xffff8080, RD_C2, 0, AL }, ++{"vsin.p", "?x1z,?s1y", 0xd0120080, 0xffff8080, RD_C2, 0, AL }, ++{"vcos.p", "?x1z,?s1y", 0xd0130080, 0xffff8080, RD_C2, 0, AL }, ++{"vexp2.p", "?x1z,?s1y", 0xd0140080, 0xffff8080, RD_C2, 0, AL }, ++{"vlog2.p", "?x1z,?s1y", 0xd0150080, 0xffff8080, RD_C2, 0, AL }, ++{"vsqrt.p", "?x1z,?s1y", 0xd0160080, 0xffff8080, RD_C2, 0, AL }, ++{"vasin.p", "?x1z,?s1y", 0xd0170080, 0xffff8080, RD_C2, 0, AL }, ++{"vnrcp.p", "?x1z,?s1y", 0xd0180080, 0xffff8080, RD_C2, 0, AL }, ++{"vnsin.p", "?x1z,?s1y", 0xd01a0080, 0xffff8080, RD_C2, 0, AL }, ++{"vrexp2.p", "?x1z,?s1y", 0xd01c0080, 0xffff8080, RD_C2, 0, AL }, ++{"vrndi.p", "?d1z", 0xd0210080, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf1.p", "?d1z", 0xd0220080, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf2.p", "?d1z", 0xd0230080, 0xffffff80, RD_C2, 0, AL }, ++{"vf2h.p", "?d0m,?s1s", 0xd0320080, 0xffff8080, RD_C2, 0, AL }, ++{"vh2f.p", "?d3d,?s1y", 0xd0330080, 0xffff8080, RD_C2, 0, AL }, ++{"vbfy1.p", "?d1d,?s1s", 0xd0420080, 0xffff8080, RD_C2, 0, AL }, ++{"vocp.p", "?d1d,?s1y", 0xd0440080, 0xffff8080, RD_C2, 0, AL }, ++{"vsocp.p", "?d3z,?s1y", 0xd0450080, 0xffff8080, RD_C2, 0, AL }, ++{"vfad.p", "?d0d,?s1s", 0xd0460080, 0xffff8080, RD_C2, 0, AL }, ++{"vavg.p", "?d0d,?s1s", 0xd0470080, 0xffff8080, RD_C2, 0, AL }, ++{"vf2in.p", "?d1m,?s1s,?b", 0xd2000080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iz.p", "?d1m,?s1s,?b", 0xd2200080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iu.p", "?d1m,?s1s,?b", 0xd2400080, 0xffe08080, RD_C2, 0, AL }, ++{"vf2id.p", "?d1m,?s1s,?b", 0xd2600080, 0xffe08080, RD_C2, 0, AL }, ++{"vi2f.p", "?d1d,?s1w,?b", 0xd2800080, 0xffe08080, RD_C2, 0, AL }, ++{"vcmov.p", "?d1d,?s1s,?e", 0, (int) M_VCMOV_P, INSN_MACRO, 0, AL }, ++{"vcmovt.p", "?d1d,?s1s,?e", 0xd2a00080, 0xfff88080, RD_C2, 0, AL }, ++{"vcmovf.p", "?d1d,?s1s,?e", 0xd2a80080, 0xfff88080, RD_C2, 0, AL }, ++{"vmmul.p", "?v5z,?s5y,?t5x", 0xf0000080, 0xff808080, RD_C2, 0, AL }, ++{"vtfm2.p", "?v1z,?s5y,?t1x", 0xf0800080, 0xff808080, RD_C2, 0, AL }, ++{"vhtfm2.p", "?v1z,?s5y,?t1x", 0xf0800000, 0xff808080, RD_C2, 0, AL }, ++{"vmscl.p", "?x5z,?s5y,?t0x", 0xf2000080, 0xff808080, RD_C2, 0, AL }, ++{"vmmov.p", "?x5z,?s5y", 0xf3800080, 0xffff8080, RD_C2, 0, AL }, ++{"vmidt.p", "?d5z", 0xf3830080, 0xffffff80, RD_C2, 0, AL }, ++{"vmzero.p", "?d5z", 0xf3860080, 0xffffff80, RD_C2, 0, AL }, ++{"vmone.p", "?d5z", 0xf3870080, 0xffffff80, RD_C2, 0, AL }, ++{"vrot.p", "?x1z,?s0y,?w", 0xf3a00080, 0xffe08080, RD_C2, 0, AL }, ++{"vadd.s", "?d0d,?s0s,?t0t", 0x60000000, 0xff808080, RD_C2, 0, AL }, ++{"vsub.s", "?d0d,?s0s,?t0t", 0x60800000, 0xff808080, RD_C2, 0, AL }, ++{"vdiv.s", "?x0d,?s0s,?t0t", 0x63800000, 0xff808080, RD_C2, 0, AL }, ++{"vmul.s", "?d0d,?s0s,?t0t", 0x64000000, 0xff808080, RD_C2, 0, AL }, ++{"vcmp.s", "?f2,?s0s,?t0t", 0x6c000000, 0xff8080f0, RD_C2, 0, AL }, ++{"vcmp.s", "?f1,?s0s", 0x6c000000, 0xffff80f0, RD_C2, 0, AL }, ++{"vcmp.s", "?f0", 0x6c000000, 0xfffffff0, RD_C2, 0, AL }, ++{"vmin.s", "?d0d,?s0s,?t0t", 0x6d000000, 0xff808080, RD_C2, 0, AL }, ++{"vmax.s", "?d0d,?s0s,?t0t", 0x6d800000, 0xff808080, RD_C2, 0, AL }, ++{"vsgn.s", "?d0d,?s0s", 0xd04a0000, 0xffff8080, RD_C2, 0, AL }, ++{"vcst.s", "?d0d,?a", 0xd0600000, 0xffe0ff80, RD_C2, 0, AL }, ++{"vscmp.s", "?d0d,?s0s,?t0t", 0x6e800000, 0xff808080, RD_C2, 0, AL }, ++{"vsge.s", "?d0d,?s0s,?t0t", 0x6f000000, 0xff808080, RD_C2, 0, AL }, ++{"vslt.s", "?d0d,?s0s,?t0t", 0x6f800000, 0xff808080, RD_C2, 0, AL }, ++{"vus2i.s", "?d1m,?s0y", 0xd03a0000, 0xffff8080, RD_C2, 0, AL }, ++{"vs2i.s", "?d1m,?s0y", 0xd03b0000, 0xffff8080, RD_C2, 0, AL }, ++{"vmov.s", "?d0d,?s0s", 0xd0000000, 0xffff8080, RD_C2, 0, AL }, ++{"vabs.s", "?d0d,?s0w", 0xd0010000, 0xffff8080, RD_C2, 0, AL }, ++{"vneg.s", "?d0d,?s0w", 0xd0020000, 0xffff8080, RD_C2, 0, AL }, ++{"vsat0.s", "?d0z,?s0s", 0xd0040000, 0xffff8080, RD_C2, 0, AL }, ++{"vsat1.s", "?d0z,?s0s", 0xd0050000, 0xffff8080, RD_C2, 0, AL }, ++{"vzero.s", "?d0d", 0xd0060000, 0xffffff80, RD_C2, 0, AL }, ++{"vone.s", "?d0d", 0xd0070000, 0xffffff80, RD_C2, 0, AL }, ++{"vrcp.s", "?x0d,?s0s", 0xd0100000, 0xffff8080, RD_C2, 0, AL }, ++{"vrsq.s", "?x0d,?s0s", 0xd0110000, 0xffff8080, RD_C2, 0, AL }, ++{"vsin.s", "?x0d,?s0s", 0xd0120000, 0xffff8080, RD_C2, 0, AL }, ++{"vcos.s", "?x0d,?s0s", 0xd0130000, 0xffff8080, RD_C2, 0, AL }, ++{"vexp2.s", "?x0d,?s0s", 0xd0140000, 0xffff8080, RD_C2, 0, AL }, ++{"vlog2.s", "?x0d,?s0s", 0xd0150000, 0xffff8080, RD_C2, 0, AL }, ++{"vsqrt.s", "?x0d,?s0s", 0xd0160000, 0xffff8080, RD_C2, 0, AL }, ++{"vasin.s", "?x0d,?s0s", 0xd0170000, 0xffff8080, RD_C2, 0, AL }, ++{"vnrcp.s", "?x0d,?s0y", 0xd0180000, 0xffff8080, RD_C2, 0, AL }, ++{"vnsin.s", "?x0d,?s0y", 0xd01a0000, 0xffff8080, RD_C2, 0, AL }, ++{"vrexp2.s", "?x0d,?s0y", 0xd01c0000, 0xffff8080, RD_C2, 0, AL }, ++{"vrnds.s", "?s0y", 0xd0200000, 0xffff80ff, RD_C2, 0, AL }, ++{"vrndi.s", "?d0d", 0xd0210000, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf1.s", "?d0d", 0xd0220000, 0xffffff80, RD_C2, 0, AL }, ++{"vrndf2.s", "?d0d", 0xd0230000, 0xffffff80, RD_C2, 0, AL }, ++{"vh2f.s", "?d1d,?s0y", 0xd0330000, 0xffff8080, RD_C2, 0, AL }, ++{"vsbz.s", "?d0d,?s0s", 0xd0360000, 0xffff8080, RD_C2, 0, AL }, ++{"vsbn.s", "?d0d,?s0s,?t0t", 0x61000000, 0xff808080, RD_C2, 0, AL }, ++{"vlgb.s", "?d0d,?s0s", 0xd0370000, 0xffff8080, RD_C2, 0, AL }, ++{"vocp.s", "?d0d,?s0y", 0xd0440000, 0xffff8080, RD_C2, 0, AL }, ++{"vsocp.s", "?d1z,?s0y", 0xd0450000, 0xffff8080, RD_C2, 0, AL }, ++{"vf2in.s", "?d0m,?s0s,?b", 0xd2000000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iz.s", "?d0m,?s0s,?b", 0xd2200000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2iu.s", "?d0m,?s0s,?b", 0xd2400000, 0xffe08080, RD_C2, 0, AL }, ++{"vf2id.s", "?d0m,?s0s,?b", 0xd2600000, 0xffe08080, RD_C2, 0, AL }, ++{"vi2f.s", "?d0d,?s0w,?b", 0xd2800000, 0xffe08080, RD_C2, 0, AL }, ++{"vcmov.s", "?d0d,?s0s,?e", 0, (int) M_VCMOV_S, INSN_MACRO, 0, AL }, ++{"vcmovt.s", "?d0d,?s0s,?e", 0xd2a00000, 0xfff88080, RD_C2, 0, AL }, ++{"vcmovf.s", "?d0d,?s0s,?e", 0xd2a80000, 0xfff88080, RD_C2, 0, AL }, ++{"vwbn.s", "?d0d,?s0s,?i", 0xd3000000, 0xff008080, RD_C2, 0, AL }, ++{"vpfxs", "?0,?1,?2,?3", 0xdc000000, 0xff000000, RD_C2, 0, AL }, ++{"vpfxt", "?0,?1,?2,?3", 0xdd000000, 0xff000000, RD_C2, 0, AL }, ++{"vpfxd", "?4,?5,?6,?7", 0xde000000, 0xff000000, RD_C2, 0, AL }, ++{"viim.s", "?t0d,j", 0xdf000000, 0xff800000, RD_C2, 0, AL }, ++{"vfim.s", "?t0d,?u", 0xdf800000, 0xff800000, RD_C2, 0, AL }, ++{"vnop", "", 0xffff0000, 0xffffffff, RD_C2, 0, AL }, ++{"vflush", "", 0xffff040d, 0xffffffff, RD_C2, 0, AL }, ++{"vsync", "", 0xffff0320, 0xffffffff, RD_C2, 0, AL }, ++{"vsync", "i", 0xffff0000, 0xffff0000, RD_C2, 0, AL }, ++ + /* User Defined Instruction. */ + {"udi0", "s,t,d,+1",0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, + {"udi0", "s,t,+2", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, +@@ -1606,6 +1913,36 @@ + {"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33 }, + {"mthc2", "t,i", 0x48e00000, 0xffe00000, COD|RD_t|WR_C2|WR_CC, 0, I33 }, + ++/* Coprocessor 2 load/store operations overlap with the Allegrex VFPU ++ instructions so they are here for the latters to take precedence. */ ++/* COP1 ldc1 and sdc1 and COP3 ldc3 and sdc3 also overlap with the VFPU. */ ++{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, ++{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, ++{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, ++{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, ++{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, /* ldc1 */ ++{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, 0, I1 }, ++{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, 0, I1 }, ++{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, ++{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, 0, I2 }, ++{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, ++{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, 0, I2 }, ++{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, ++{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, 0, I1 }, ++{"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, 0, I2 }, ++{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, 0, I2 }, ++{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, ++{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, 0, I1 }, ++{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, 0, I1 }, ++{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I2 }, ++{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, 0, I2 }, ++{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, 0, I2 }, ++{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, 0, I2 }, ++{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I1 }, ++{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, 0, I1 }, ++ + /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X + instructions, so they are here for the latters to take precedence. */ + {"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1 }, +@@ -1643,7 +1980,6 @@ + {"addu_s.ob", "d,s,t", 0x7c000114, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, + {"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 }, + {"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 }, diff --git a/binutils-2.22-texinfofix.patch b/binutils-2.22-texinfofix.patch new file mode 100644 index 000000000000..6f994c124bbc --- /dev/null +++ b/binutils-2.22-texinfofix.patch @@ -0,0 +1,24 @@ +diff -burN orig.binutils-2.22/bfd/doc/bfd.texinfo binutils-2.22/bfd/doc/bfd.texinfo +--- orig.binutils-2.22/bfd/doc/bfd.texinfo 2010-10-28 13:40:25.000000000 +0200 ++++ binutils-2.22/bfd/doc/bfd.texinfo 2013-08-29 22:15:26.795913686 +0200 +@@ -321,9 +321,9 @@ + @unnumbered BFD Index + @printindex cp + ++@c I think something like @colophon should be in texinfo. In the ++@c meantime: + @tex +-% I think something like @colophon should be in texinfo. In the +-% meantime: + \long\def\colophon{\hbox to0pt{}\vfill + \centerline{The body of this manual is set in} + \centerline{\fontname\tenrm,} +@@ -333,7 +333,7 @@ + \centerline{{\sl\fontname\tensl\/}} + \centerline{are used for emphasis.}\vfill} + \page\colophon +-% Blame: doc@cygnus.com, 28mar91. + @end tex ++@c Blame: doc@cygnus.com, 28mar91. + + @bye |