buildscripts/dkpsp/patches/binutils-2.22.patch
2018-06-05 23:31:45 +00:00

4641 lines
182 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -Nbaur binutils-2.22/bfd/archures.c binutils-2.22-psp/bfd/archures.c
--- binutils-2.22/bfd/archures.c 2011-08-01 23:04:19.000000000 +0000
+++ binutils-2.22-psp/bfd/archures.c 2018-06-05 22:45:23.845890519 +0000
@@ -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 -Nbaur binutils-2.22/bfd/bfd-in2.h binutils-2.22-psp/bfd/bfd-in2.h
--- binutils-2.22/bfd/bfd-in2.h 2011-09-16 01:15:18.000000000 +0000
+++ binutils-2.22-psp/bfd/bfd-in2.h 2018-06-05 22:45:23.845890519 +0000
@@ -38,6 +38,8 @@
#include "ansidecl.h"
#include "symcat.h"
+#include <sys/stat.h>
+
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#ifndef SABER
/* This hack is to avoid a problem with some strict ANSI C preprocessors.
@@ -308,8 +310,6 @@
&& (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \
&& (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
-/* Forward define. */
-struct stat;
typedef enum bfd_print_symbol
{
@@ -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 -Nbaur binutils-2.22/bfd/bfd-in.h binutils-2.22-psp/bfd/bfd-in.h
--- binutils-2.22/bfd/bfd-in.h 2011-09-16 01:15:18.000000000 +0000
+++ binutils-2.22-psp/bfd/bfd-in.h 2018-06-05 22:45:23.845890519 +0000
@@ -31,6 +31,8 @@
#include "ansidecl.h"
#include "symcat.h"
+#include <sys/stat.h>
+
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#ifndef SABER
/* This hack is to avoid a problem with some strict ANSI C preprocessors.
@@ -301,8 +303,6 @@
&& (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \
&& (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
-/* Forward define. */
-struct stat;
typedef enum bfd_print_symbol
{
diff -Nbaur binutils-2.22/bfd/config.in binutils-2.22-psp/bfd/config.in
--- binutils-2.22/bfd/config.in 2011-05-12 07:41:40.000000000 +0000
+++ binutils-2.22-psp/bfd/config.in 2018-06-05 22:45:23.845890519 +0000
@@ -245,6 +245,9 @@
/* Define if <sys/procfs.h> has win32_pstatus_t. */
#undef HAVE_WIN32_PSTATUS_T
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
diff -Nbaur binutils-2.22/bfd/configure binutils-2.22-psp/bfd/configure
--- binutils-2.22/bfd/configure 2011-11-21 11:55:48.000000000 +0000
+++ binutils-2.22-psp/bfd/configure 2018-06-05 22:45:23.849891511 +0000
@@ -13508,6 +13508,22 @@
fi
+
+for ac_header in windows.h dlfcn.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5
$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; }
if test "${gcc_cv_header_string+set}" = set; then :
diff -Nbaur binutils-2.22/bfd/configure.in binutils-2.22-psp/bfd/configure.in
--- binutils-2.22/bfd/configure.in 2011-11-21 11:55:46.000000000 +0000
+++ binutils-2.22-psp/bfd/configure.in 2018-06-05 22:45:23.849891511 +0000
@@ -190,6 +190,9 @@
GCC_HEADER_STDINT(bfd_stdint.h)
AC_HEADER_TIME
AC_HEADER_DIRENT
+
+AC_CHECK_HEADERS(windows.h dlfcn.h)
+
ACX_HEADER_STRING
AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen getuid getgid fileno)
AC_CHECK_FUNCS(strtoull)
diff -Nbaur binutils-2.22/bfd/cpu-mips.c binutils-2.22-psp/bfd/cpu-mips.c
--- binutils-2.22/bfd/cpu-mips.c 2011-07-24 14:20:05.000000000 +0000
+++ binutils-2.22-psp/bfd/cpu-mips.c 2018-06-05 22:45:23.849891511 +0000
@@ -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 -Nbaur binutils-2.22/bfd/doc/bfd.texinfo binutils-2.22-psp/bfd/doc/bfd.texinfo
--- binutils-2.22/bfd/doc/bfd.texinfo 2010-10-28 11:40:25.000000000 +0000
+++ binutils-2.22-psp/bfd/doc/bfd.texinfo 2018-06-05 23:00:58.016586742 +0000
@@ -322,7 +322,7 @@
@printindex cp
@tex
-% I think something like @colophon should be in texinfo. In the
+% 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}
@@ -333,7 +333,7 @@
\centerline{{\sl\fontname\tensl\/}}
\centerline{are used for emphasis.}\vfill}
\page\colophon
-% Blame: doc@cygnus.com, 28mar91.
+% Blame: doc@@cygnus.com, 28mar91.
@end tex
@bye
diff -Nbaur binutils-2.22/bfd/elfxx-mips.c binutils-2.22-psp/bfd/elfxx-mips.c
--- binutils-2.22/bfd/elfxx-mips.c 2011-11-21 09:29:27.000000000 +0000
+++ binutils-2.22-psp/bfd/elfxx-mips.c 2018-06-05 22:45:23.853892502 +0000
@@ -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 -Nbaur binutils-2.22/bfd/plugin.c binutils-2.22-psp/bfd/plugin.c
--- binutils-2.22/bfd/plugin.c 2011-07-11 15:03:07.000000000 +0000
+++ binutils-2.22-psp/bfd/plugin.c 2018-06-05 22:45:23.853892502 +0000
@@ -25,7 +25,13 @@
#if BFD_SUPPORTS_PLUGINS
#include <assert.h>
+#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
+#elif defined (HAVE_WINDOWS_H)
+#include <windows.h>
+#else
+#error Unknown how to handle dynamic-load-libraries.
+#endif
#include <stdarg.h>
#include "plugin-api.h"
#include "sysdep.h"
@@ -34,6 +40,37 @@
#include "libiberty.h"
#include <dirent.h>
+#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
+
+#define RTLD_NOW 0 /* Dummy value. */
+
+static void *
+dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
+{
+ return LoadLibrary (file);
+}
+
+static void *
+dlsym (void *handle, const char *name)
+{
+ return GetProcAddress (handle, name);
+}
+
+static int ATTRIBUTE_UNUSED
+dlclose (void *handle)
+{
+ FreeLibrary (handle);
+ return 0;
+}
+
+static const char *
+dlerror (void)
+{
+ return "Unable to load DLL.";
+}
+
+#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */
+
#define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup
#define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
#define bfd_plugin_new_section_hook _bfd_generic_new_section_hook
diff -Nbaur binutils-2.22/bfd/version.h binutils-2.22-psp/bfd/version.h
--- binutils-2.22/bfd/version.h 2011-11-21 09:29:28.000000000 +0000
+++ binutils-2.22-psp/bfd/version.h 2018-06-05 22:45:23.857893494 +0000
@@ -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 -Nbaur binutils-2.22/binutils/readelf.c binutils-2.22-psp/binutils/readelf.c
--- binutils-2.22/binutils/readelf.c 2011-09-21 20:49:13.000000000 +0000
+++ binutils-2.22-psp/binutils/readelf.c 2018-06-05 22:45:23.857893494 +0000
@@ -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 -Nbaur binutils-2.22/config.sub binutils-2.22-psp/config.sub
--- binutils-2.22/config.sub 2011-06-06 10:36:06.000000000 +0000
+++ binutils-2.22-psp/config.sub 2018-06-05 22:45:23.857893494 +0000
@@ -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 -Nbaur binutils-2.22/configure binutils-2.22-psp/configure
--- binutils-2.22/configure 2011-08-14 12:28:15.000000000 +0000
+++ binutils-2.22-psp/configure 2018-06-05 22:45:23.861894485 +0000
@@ -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 -Nbaur binutils-2.22/gas/config/tc-mips.c binutils-2.22-psp/gas/config/tc-mips.c
--- binutils-2.22/gas/config/tc-mips.c 2011-11-21 09:29:32.000000000 +0000
+++ binutils-2.22-psp/gas/config/tc-mips.c 2018-06-05 22:45:23.865895476 +0000
@@ -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 -Nbaur binutils-2.22/gas/configure binutils-2.22-psp/gas/configure
--- binutils-2.22/gas/configure 2011-05-18 09:41:14.000000000 +0000
+++ binutils-2.22-psp/gas/configure 2018-06-05 22:45:23.865895476 +0000
@@ -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 -Nbaur binutils-2.22/gas/configure.in binutils-2.22-psp/gas/configure.in
--- binutils-2.22/gas/configure.in 2011-05-18 09:41:14.000000000 +0000
+++ binutils-2.22-psp/gas/configure.in 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/gas/testsuite/gas/mips/mips.exp binutils-2.22-psp/gas/testsuite/gas/mips/mips.exp
--- binutils-2.22/gas/testsuite/gas/mips/mips.exp 2011-11-21 09:29:32.000000000 +0000
+++ binutils-2.22-psp/gas/testsuite/gas/mips/mips.exp 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/include/elf/common.h binutils-2.22-psp/include/elf/common.h
--- binutils-2.22/include/elf/common.h 2011-07-22 20:22:36.000000000 +0000
+++ binutils-2.22-psp/include/elf/common.h 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/include/elf/mips.h binutils-2.22-psp/include/elf/mips.h
--- binutils-2.22/include/elf/mips.h 2011-07-24 14:20:12.000000000 +0000
+++ binutils-2.22-psp/include/elf/mips.h 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/include/opcode/mips.h binutils-2.22-psp/include/opcode/mips.h
--- binutils-2.22/include/opcode/mips.h 2011-08-09 15:20:03.000000000 +0000
+++ binutils-2.22-psp/include/opcode/mips.h 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/include/opcode/vfpu.h binutils-2.22-psp/include/opcode/vfpu.h
--- binutils-2.22/include/opcode/vfpu.h 1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.22-psp/include/opcode/vfpu.h 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/ld/configure.tgt binutils-2.22-psp/ld/configure.tgt
--- binutils-2.22/ld/configure.tgt 2011-11-21 09:29:37.000000000 +0000
+++ binutils-2.22-psp/ld/configure.tgt 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh binutils-2.22-psp/ld/emulparams/elf_mipsallegrexel_psp.sh
--- binutils-2.22/ld/emulparams/elf_mipsallegrexel_psp.sh 1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.22-psp/ld/emulparams/elf_mipsallegrexel_psp.sh 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/ld/Makefile.am binutils-2.22-psp/ld/Makefile.am
--- binutils-2.22/ld/Makefile.am 2011-07-22 20:22:37.000000000 +0000
+++ binutils-2.22-psp/ld/Makefile.am 2018-06-05 22:45:23.869896468 +0000
@@ -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 -Nbaur binutils-2.22/ld/Makefile.in binutils-2.22-psp/ld/Makefile.in
--- binutils-2.22/ld/Makefile.in 2011-07-22 20:22:37.000000000 +0000
+++ binutils-2.22-psp/ld/Makefile.in 2018-06-05 22:45:23.873897459 +0000
@@ -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 -Nbaur binutils-2.22/ld/scripttempl/elf_psp.sc binutils-2.22-psp/ld/scripttempl/elf_psp.sc
--- binutils-2.22/ld/scripttempl/elf_psp.sc 1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.22-psp/ld/scripttempl/elf_psp.sc 2018-06-05 22:45:23.873897459 +0000
@@ -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 -Nbaur binutils-2.22/opcodes/mips-dis.c binutils-2.22-psp/opcodes/mips-dis.c
--- binutils-2.22/opcodes/mips-dis.c 2011-08-09 15:20:03.000000000 +0000
+++ binutils-2.22-psp/opcodes/mips-dis.c 2018-06-05 22:45:23.873897459 +0000
@@ -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 -Nbaur binutils-2.22/opcodes/mips-opc.c binutils-2.22-psp/opcodes/mips-opc.c
--- binutils-2.22/opcodes/mips-opc.c 2011-08-09 15:20:03.000000000 +0000
+++ binutils-2.22-psp/opcodes/mips-opc.c 2018-06-05 22:45:23.873897459 +0000
@@ -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 },