summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/common/src/disasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/common/src/disasm.c')
-rw-r--r--cfe/cfe/arch/mips/common/src/disasm.c2111
1 files changed, 2111 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/common/src/disasm.c b/cfe/cfe/arch/mips/common/src/disasm.c
new file mode 100644
index 0000000..1b76fee
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/disasm.c
@@ -0,0 +1,2111 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS disassembler File: disasm.c
+ *
+ * MIPS disassembler (used by ui_examcmds.c)
+ *
+ * Author: Justin Carlson (carlson@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "disasm.h"
+#include "lib_printf.h"
+
+#define UINT64_T(x) ((uint64_t) (x))
+#define PF_64 "ll"
+#define PF_32 ""
+/* These aren't guaranteed to be portable, either */
+#define SEXT_32(bit, val) \
+ ((((int32_t)(val))<<(31-(bit)))>>(31-(bit)))
+#define SEXT_64(bit, val) \
+ ((((int64_t)(val))<<(63-(bit)))>>(63-(bit)))
+
+#define DATASEG __attribute__ ((section(".text")))
+
+
+#define REGNAME(r) (&_regnames[(r)*5])
+static const char * const _regnames =
+ "zero\0"
+ "AT\0 "
+ "v0\0 "
+ "v1\0 "
+ "a0\0 "
+ "a1\0 "
+ "a2\0 "
+ "a3\0 "
+ "t0\0 "
+ "t1\0 "
+ "t2\0 "
+ "t3\0 "
+ "t4\0 "
+ "t5\0 "
+ "t6\0 "
+ "t7\0 "
+ "s0\0 "
+ "s1\0 "
+ "s2\0 "
+ "s3\0 "
+ "s4\0 "
+ "s5\0 "
+ "s6\0 "
+ "s7\0 "
+ "t8\0 "
+ "t9\0 "
+ "k0\0 "
+ "k1\0 "
+ "gp\0 "
+ "sp\0 "
+ "fp\0 "
+ "ra\0 ";
+
+#define CP0REGNAME(r) (&_cp0names[(r)*12])
+static const char * const _cp0names =
+ "C0_INX\0 "
+ "C0_RAND\0 "
+ "C0_TLBLO0\0 "
+ "C0_TLBLO1\0 "
+
+ "C0_CTEXT\0 "
+ "C0_PGMASK\0 "
+ "C0_WIRED\0 "
+ "C0_reserved\0"
+
+ "C0_BADVADDR\0"
+ "C0_COUNT\0 "
+ "C0_TLBHI\0 "
+ "C0_COMPARE\0 "
+
+ "C0_SR\0 "
+ "C0_CAUSE\0 "
+ "C0_EPC\0 "
+ "C0_PRID\0 "
+
+ "C0_CONFIG\0 "
+ "C0_LLADDR\0 "
+ "C0_WATCHLO\0 "
+ "C0_WATCHHI\0 "
+
+ "C0_XCTEXT\0 "
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_TAGLO\0 "
+ "C0_TAGHI\0 "
+ "C0_ERREPC\0 "
+ "C0_reserved\0";
+
+
+
+/*
+ * MIPS instruction set disassembly module.
+ */
+
+typedef enum {
+ DC_RD_RS_RT,
+ DC_RD_RT_RS,
+ DC_RT_RS_SIMM,
+ DC_RT_RS_XIMM,
+ DC_RS_RT_OFS,
+ DC_RS_OFS,
+ DC_RD_RT_SA,
+ DC_RT_UIMM,
+ DC_RD,
+ DC_J,
+ DC_RD_RS,
+ DC_RS_RT,
+ DC_RT_RS,
+ DC_RT_RD_SEL,
+ DC_RT_CR_SEL,
+ DC_RS,
+ DC_RS_SIMM,
+ DC_RT_OFS_BASE,
+ DC_FT_OFS_BASE,
+ DC_FD_IDX_BASE,
+ DC_FS_IDX_BASE,
+ DC_FD_FS_FT,
+ DC_FD_FS_RT,
+ DC_FD_FS,
+ DC_PREF_OFS,
+ DC_PREF_IDX,
+ DC_CC_OFS,
+ DC_FD_FS_CC,
+ DC_RD_RS_CC,
+ DC_FD_FR_FS_FT,
+ DC_FD_FS_FT_RS,
+ DC_CC_FS_FT,
+ DC_BARE,
+ DC_RT_FS,
+ DC_SYSCALL,
+ DC_BREAK,
+ DC_VD_VS_VT_VEC,
+ DC_VD_VS_VT,
+ DC_VS_VT,
+ DC_VS_VT_VEC,
+ DC_VD_VS_VT_RS,
+ DC_VD_VS_VT_IMM,
+ DC_VD_VT,
+ DC_VD,
+ DC_VS,
+ DC_DEREF,
+ DC_OOPS
+} DISASM_CLASS;
+
+
+
+
+/* We're pulling some trickery here. Most of the time, this structure operates
+ exactly as one would expect. The special case, when type == DC_DREF,
+ means name points to a byte that is an index into a dereferencing array. */
+
+/*
+ * To make matters worse, the whole module has been coded to reduce the
+ * number of relocations present, so we don't actually store pointers
+ * in the dereferencing array. Instead, we store fixed-width strings
+ * and use digits to represent indicies into the deref array.
+ *
+ * This is all to make more things fit in the relocatable version,
+ * since every initialized pointer goes into our small data segment.
+ */
+
+typedef struct {
+ char name[15];
+ char type;
+} disasm_t;
+
+typedef struct {
+ const disasm_t *ptr;
+ int shift;
+ uint32_t mask;
+} disasm_deref_t;
+
+/* Forward declaration of deref array, we need this for the disasm_t definitions */
+
+
+extern const disasm_deref_t disasm_deref[];
+
+static const disasm_t disasm_normal[64] DATASEG =
+{{"$1" , DC_DEREF },
+ {"$2" , DC_DEREF },
+ {"j" , DC_J },
+ {"jal" , DC_J },
+ {"beq" , DC_RS_RT_OFS },
+ {"bne" , DC_RS_RT_OFS },
+ {"blez" , DC_RS_OFS },
+ {"bgtz" , DC_RS_OFS },
+ {"addi" , DC_RT_RS_SIMM },
+ {"addiu" , DC_RT_RS_SIMM },
+ {"slti" , DC_RT_RS_SIMM },
+ {"sltiu" , DC_RT_RS_SIMM },
+ {"andi" , DC_RT_RS_XIMM },
+ {"ori" , DC_RT_RS_XIMM },
+ {"xori" , DC_RT_RS_XIMM },
+ {"lui" , DC_RT_UIMM },
+ {"$4" , DC_DEREF },
+ {"$6" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$15" , DC_DEREF },
+ {"beql" , DC_RS_RT_OFS },
+ {"bnel" , DC_RS_RT_OFS },
+ {"blezl" , DC_RS_OFS },
+ {"bgtzl" , DC_RS_OFS },
+ {"daddi" , DC_RT_RS_SIMM },
+ {"daddiu" , DC_RT_RS_SIMM },
+ {"ldl" , DC_RT_OFS_BASE },
+ {"ldr" , DC_RT_OFS_BASE },
+ {"$3" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$18" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"lb" , DC_RT_OFS_BASE },
+ {"lh" , DC_RT_OFS_BASE },
+ {"lwl" , DC_RT_OFS_BASE },
+ {"lw" , DC_RT_OFS_BASE },
+ {"lbu" , DC_RT_OFS_BASE },
+ {"lhu" , DC_RT_OFS_BASE },
+ {"lwr" , DC_RT_OFS_BASE },
+ {"lwu" , DC_RT_OFS_BASE },
+ {"sb" , DC_RT_OFS_BASE },
+ {"sh" , DC_RT_OFS_BASE },
+ {"swl" , DC_RT_OFS_BASE },
+ {"sw" , DC_RT_OFS_BASE },
+ {"sdl" , DC_RT_OFS_BASE },
+ {"sdr" , DC_RT_OFS_BASE },
+ {"swr" , DC_RT_OFS_BASE },
+ {"cache" , DC_BARE },
+ {"ll" , DC_RT_OFS_BASE },
+ {"lwc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"pref" , DC_PREF_OFS },
+ {"lld" , DC_RT_OFS_BASE },
+ {"ldc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"ld" , DC_RT_OFS_BASE },
+ {"sc" , DC_RT_OFS_BASE },
+ {"swc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"scd" , DC_RT_OFS_BASE },
+ {"sdc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"sd" , DC_RT_OFS_BASE }};
+
+static const disasm_t disasm_special[64] DATASEG =
+{{"sll" , DC_RD_RT_SA },
+ {"$16" , DC_DEREF },
+ {"srl" , DC_RD_RT_SA },
+ {"sra" , DC_RD_RT_SA },
+ {"sllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"srlv" , DC_RD_RT_RS },
+ {"srav" , DC_RD_RT_RS },
+ {"jr" , DC_RS },
+ {"jalr" , DC_RD_RS },
+ {"movz" , DC_RD_RS_RT },
+ {"movn" , DC_RD_RS_RT },
+ {"syscall" , DC_SYSCALL },
+ {"break" , DC_BREAK },
+ {"invalid" , DC_BARE },
+ {"sync" , DC_BARE },
+ {"mfhi" , DC_RD },
+ {"mthi" , DC_RS },
+ {"mflo" , DC_RD },
+ {"mtlo" , DC_RS },
+ {"dsllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"dsrlv" , DC_RD_RT_RS },
+ {"dsrav" , DC_RD_RT_RS },
+ {"mult" , DC_RS_RT },
+ {"multu" , DC_RS_RT },
+ {"div" , DC_RS_RT },
+ {"divu" , DC_RS_RT },
+ {"dmult" , DC_RS_RT },
+ {"dmultu" , DC_RS_RT },
+ {"ddiv" , DC_RS_RT },
+ {"ddivu" , DC_RS_RT },
+ {"add" , DC_RD_RS_RT },
+ {"addu" , DC_RD_RS_RT },
+ {"sub" , DC_RD_RS_RT },
+ {"subu" , DC_RD_RS_RT },
+ {"and" , DC_RD_RS_RT },
+ {"or" , DC_RD_RS_RT },
+ {"xor" , DC_RD_RS_RT },
+ {"nor" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"slt" , DC_RD_RS_RT },
+ {"sltu" , DC_RD_RS_RT },
+ {"dadd" , DC_RD_RS_RT },
+ {"daddu" , DC_RD_RS_RT },
+ {"dsub" , DC_RD_RS_RT },
+ {"dsubu" , DC_RD_RS_RT },
+ {"tge" , DC_RS_RT },
+ {"tgeu" , DC_RS_RT },
+ {"tlt" , DC_RS_RT },
+ {"tltu" , DC_RS_RT },
+ {"teq" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"tne" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"dsll" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl" , DC_RD_RT_SA },
+ {"dsra" , DC_RD_RT_SA },
+ {"dsll32" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl32" , DC_RD_RT_SA },
+ {"dsra32" , DC_RD_RT_SA }};
+
+static const disasm_t disasm_movci[2] DATASEG =
+{{"movf" , DC_RD_RS_CC },
+ {"movt" , DC_RD_RS_CC }};
+
+static const disasm_t disasm_regimm[32] DATASEG =
+{{"bltz" , DC_RS_OFS },
+ {"bgez" , DC_RS_OFS },
+ {"bltzl" , DC_RS_OFS },
+ {"bgezl" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tgei" , DC_RS_SIMM },
+ {"tgeiu" , DC_RS_SIMM },
+ {"tlti" , DC_RS_SIMM },
+ {"tltiu" , DC_RS_SIMM },
+ {"teqi" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"tnei" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"bltzal" , DC_RS_OFS },
+ {"bgezal" , DC_RS_OFS },
+ {"bltzall" , DC_RS_OFS },
+ {"bgezall" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_spec2[64] DATASEG =
+{{"madd" , DC_RS_RT },
+ {"maddu" , DC_RS_RT },
+ {"mul" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"msub" , DC_RS_RT },
+ {"msubu" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"clz" , DC_RT_RS },
+ {"clo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"dclz" , DC_RT_RS },
+ {"dclo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"sdbbp" , DC_BARE }};
+
+static const disasm_t disasm_cop0[32] DATASEG =
+{{"mfc0@1" , DC_RT_CR_SEL },
+ {"dmfc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"mtc0@1" , DC_RT_CR_SEL },
+ {"dmtc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF }};
+
+static const disasm_t disasm_cop0_c0[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"tlbr" , DC_BARE },
+ {"tlbwi" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbwr" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbp" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"eret" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"deret" , DC_BARE },
+ {"wait" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1[32] DATASEG =
+{{"mfc1" , DC_RT_FS },
+ {"dmfc1" , DC_RT_FS },
+ {"cfc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"mtc1" , DC_RT_FS },
+ {"dmtc1" , DC_RT_FS },
+ {"ctc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"$17" , DC_DEREF },
+ {"$36" , DC_DEREF },
+ {"$37" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$7" , DC_DEREF },
+ {"$9" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$11" , DC_DEREF },
+ {"$12" , DC_DEREF },
+ {"$13" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_bc1[4] DATASEG =
+{{"bc1f" , DC_CC_OFS },
+ {"bc1t" , DC_CC_OFS },
+ {"bc1fl" , DC_CC_OFS },
+ {"bc1tl" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any2[2] DATASEG =
+{{"bc1any2f" , DC_CC_OFS },
+ {"bc1any2t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any4[2] DATASEG =
+{{"bc1any4f" , DC_CC_OFS },
+ {"bc1any4t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_s[64] DATASEG =
+{{"add.s" , DC_FD_FS_FT },
+ {"sub.s" , DC_FD_FS_FT },
+ {"mul.s" , DC_FD_FS_FT },
+ {"div.s" , DC_FD_FS_FT },
+ {"sqrt.s" , DC_FD_FS },
+ {"abs.s" , DC_FD_FS },
+ {"mov.s" , DC_FD_FS },
+ {"neg.s" , DC_FD_FS },
+ {"round.l.s" , DC_FD_FS },
+ {"trunc.l.s" , DC_FD_FS },
+ {"ceil.l.s" , DC_FD_FS },
+ {"floor.l.s" , DC_FD_FS },
+ {"round.w.s" , DC_FD_FS },
+ {"trunc.w.s" , DC_FD_FS },
+ {"ceil.w.s" , DC_FD_FS },
+ {"floor.w.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$8" , DC_DEREF },
+ {"movz.s" , DC_FD_FS_RT },
+ {"movn.s" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.s" , DC_FD_FS },
+ {"rsqrt.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.s" , DC_FD_FS_FT },
+ {"recip1.s" , DC_FD_FS },
+ {"rsqrt1.s" , DC_FD_FS },
+ {"rsqrt2.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"cvt.d.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.s" , DC_FD_FS },
+ {"cvt.l.s" , DC_FD_FS },
+ {"cvt.ps.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$38" , DC_DEREF },
+ {"$39" , DC_DEREF },
+ {"$40" , DC_DEREF },
+ {"$41" , DC_DEREF },
+ {"$42" , DC_DEREF },
+ {"$43" , DC_DEREF },
+ {"$44" , DC_DEREF },
+ {"$45" , DC_DEREF },
+ {"$46" , DC_DEREF },
+ {"$47" , DC_DEREF },
+ {"$48" , DC_DEREF },
+ {"$49" , DC_DEREF },
+ {"$50" , DC_DEREF },
+ {"$51" , DC_DEREF },
+ {"$52" , DC_DEREF },
+ {"$53" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_s_mvcf[2] DATASEG =
+{{"movf.s" , DC_FD_FS_CC },
+ {"movt.s" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_d[64] DATASEG =
+{{"add.d" , DC_FD_FS_FT },
+ {"sub.d" , DC_FD_FS_FT },
+ {"mul.d" , DC_FD_FS_FT },
+ {"div.d" , DC_FD_FS_FT },
+ {"sqrt.d" , DC_FD_FS },
+ {"abs.d" , DC_FD_FS },
+ {"mov.d" , DC_FD_FS },
+ {"neg.d" , DC_FD_FS },
+ {"round.l.d" , DC_FD_FS },
+ {"trunc.l.d" , DC_FD_FS },
+ {"ceil.l.d" , DC_FD_FS },
+ {"floor.l.d" , DC_FD_FS },
+ {"round.w.d" , DC_FD_FS },
+ {"trunc.w.d" , DC_FD_FS },
+ {"ceil.w.d" , DC_FD_FS },
+ {"floor.w.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$10" , DC_DEREF },
+ {"movz.d" , DC_FD_FS_RT },
+ {"movn.d" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.d" , DC_FD_FS },
+ {"rsqrt.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.d" , DC_FD_FS_FT },
+ {"recip1.d" , DC_FD_FS },
+ {"rsqrt1.d" , DC_FD_FS },
+ {"rsqrt2.d" , DC_FD_FS_FT },
+ {"cvt.s.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.d" , DC_FD_FS },
+ {"cvt.l.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$54" , DC_DEREF },
+ {"$55" , DC_DEREF },
+ {"$56" , DC_DEREF },
+ {"$57" , DC_DEREF },
+ {"$58" , DC_DEREF },
+ {"$59" , DC_DEREF },
+ {"$60" , DC_DEREF },
+ {"$61" , DC_DEREF },
+ {"$62" , DC_DEREF },
+ {"$63" , DC_DEREF },
+ {"$64" , DC_DEREF },
+ {"$65" , DC_DEREF },
+ {"$66" , DC_DEREF },
+ {"$67" , DC_DEREF },
+ {"$68" , DC_DEREF },
+ {"$69" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_d_mvcf[2] DATASEG =
+{{"movf.d" , DC_FD_FS_CC },
+ {"movt.d" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_w[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.w" , DC_FD_FS },
+ {"cvt.d.w" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.ps.pw" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_l[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.l" , DC_FD_FS },
+ {"cvt.d.l" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_ps[64] DATASEG =
+{{"add.ps" , DC_FD_FS_FT },
+ {"sub.ps" , DC_FD_FS_FT },
+ {"mul.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"abs.ps" , DC_FD_FS },
+ {"mov.ps" , DC_FD_FS },
+ {"neg.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$14" , DC_DEREF },
+ {"movz.ps" , DC_FD_FS_RT },
+ {"movn.ps" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"addr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"mulr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"recip2.ps" , DC_FD_FS_FT },
+ {"recip1.ps" , DC_FD_FS },
+ {"rsqrt1.ps" , DC_FD_FS },
+ {"rsqrt2.ps" , DC_FD_FS_FT },
+ {"cvt.s.pu" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.pw.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.pl" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"pll.ps" , DC_FD_FS_FT },
+ {"plu.ps" , DC_FD_FS_FT },
+ {"pul.ps" , DC_FD_FS_FT },
+ {"puu.ps" , DC_FD_FS_FT },
+ {"$70" , DC_DEREF },
+ {"$71" , DC_DEREF },
+ {"$72" , DC_DEREF },
+ {"$73" , DC_DEREF },
+ {"$74" , DC_DEREF },
+ {"$75" , DC_DEREF },
+ {"$76" , DC_DEREF },
+ {"$77" , DC_DEREF },
+ {"$78" , DC_DEREF },
+ {"$79" , DC_DEREF },
+ {"$80" , DC_DEREF },
+ {"$81" , DC_DEREF },
+ {"$82" , DC_DEREF },
+ {"$83" , DC_DEREF },
+ {"$84" , DC_DEREF },
+ {"$85" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_c_f_s[2] DATASEG =
+{{"c.f.s" , DC_CC_FS_FT },
+ {"cabs.f.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_s[2] DATASEG =
+{{"c.un.s" , DC_CC_FS_FT },
+ {"cabs.un.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_s[2] DATASEG =
+{{"c.eq.s" , DC_CC_FS_FT },
+ {"cabs.eq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_s[2] DATASEG =
+{{"c.ueq.s" , DC_CC_FS_FT },
+ {"cabs.ueq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_s[2] DATASEG =
+{{"c.olt.s" , DC_CC_FS_FT },
+ {"cabs.olt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_s[2] DATASEG =
+{{"c.ult.s" , DC_CC_FS_FT },
+ {"cabs.ult.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_s[2] DATASEG =
+{{"c.ole.s" , DC_CC_FS_FT },
+ {"cabs.ole.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_s[2] DATASEG =
+{{"c.ule.s" , DC_CC_FS_FT },
+ {"cabs.ule.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_s[2] DATASEG =
+{{"c.sf.s" , DC_CC_FS_FT },
+ {"cabs.sf.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_s[2] DATASEG =
+{{"c.ngle.s" , DC_CC_FS_FT },
+ {"cabs.ngle.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_s[2] DATASEG =
+{{"c.seq.s" , DC_CC_FS_FT },
+ {"cabs.seq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_s[2] DATASEG =
+{{"c.ngl.s" , DC_CC_FS_FT },
+ {"cabs.ngl.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_s[2] DATASEG =
+{{"c.lt.s" , DC_CC_FS_FT },
+ {"cabs.lt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_s[2] DATASEG =
+{{"c.nge.s" , DC_CC_FS_FT },
+ {"cabs.nge.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_s[2] DATASEG =
+{{"c.le.s" , DC_CC_FS_FT },
+ {"cabs.le.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_s[2] DATASEG =
+{{"c.ngt.s" , DC_CC_FS_FT },
+ {"cabs.ngt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_d[2] DATASEG =
+{{"c.f.d" , DC_CC_FS_FT },
+ {"cabs.f.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_d[2] DATASEG =
+{{"c.un.d" , DC_CC_FS_FT },
+ {"cabs.un.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_d[2] DATASEG =
+{{"c.eq.d" , DC_CC_FS_FT },
+ {"cabs.eq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_d[2] DATASEG =
+{{"c.ueq.d" , DC_CC_FS_FT },
+ {"cabs.ueq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_d[2] DATASEG =
+{{"c.olt.d" , DC_CC_FS_FT },
+ {"cabs.olt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_d[2] DATASEG =
+{{"c.ult.d" , DC_CC_FS_FT },
+ {"cabs.ult.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_d[2] DATASEG =
+{{"c.ole.d" , DC_CC_FS_FT },
+ {"cabs.ole.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_d[2] DATASEG =
+{{"c.ule.d" , DC_CC_FS_FT },
+ {"cabs.ule.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_d[2] DATASEG =
+{{"c.sf.d" , DC_CC_FS_FT },
+ {"cabs.sf.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_d[2] DATASEG =
+{{"c.ngle.d" , DC_CC_FS_FT },
+ {"cabs.ngle.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_d[2] DATASEG =
+{{"c.seq.d" , DC_CC_FS_FT },
+ {"cabs.seq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_d[2] DATASEG =
+{{"c.ngl.d" , DC_CC_FS_FT },
+ {"cabs.ngl.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_d[2] DATASEG =
+{{"c.lt.d" , DC_CC_FS_FT },
+ {"cabs.lt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_d[2] DATASEG =
+{{"c.nge.d" , DC_CC_FS_FT },
+ {"cabs.nge.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_d[2] DATASEG =
+{{"c.le.d" , DC_CC_FS_FT },
+ {"cabs.le.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_d[2] DATASEG =
+{{"c.ngt.d" , DC_CC_FS_FT },
+ {"cabs.ngt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_ps[2] DATASEG =
+{{"c.f.ps" , DC_CC_FS_FT },
+ {"cabs.f.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_ps[2] DATASEG =
+{{"c.un.ps" , DC_CC_FS_FT },
+ {"cabs.un.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_ps[2] DATASEG =
+{{"c.eq.ps" , DC_CC_FS_FT },
+ {"cabs.eq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_ps[2] DATASEG =
+{{"c.ueq.ps" , DC_CC_FS_FT },
+ {"cabs.ueq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_ps[2] DATASEG =
+{{"c.olt.ps" , DC_CC_FS_FT },
+ {"cabs.olt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_ps[2] DATASEG =
+{{"c.ult.ps" , DC_CC_FS_FT },
+ {"cabs.ult.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_ps[2] DATASEG =
+{{"c.ole.ps" , DC_CC_FS_FT },
+ {"cabs.ole.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_ps[2] DATASEG =
+{{"c.ule.ps" , DC_CC_FS_FT },
+ {"cabs.ule.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_ps[2] DATASEG =
+{{"c.sf.ps" , DC_CC_FS_FT },
+ {"cabs.sf.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_ps[2] DATASEG =
+{{"c.ngle.ps" , DC_CC_FS_FT },
+ {"cabs.ngle.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_ps[2] DATASEG =
+{{"c.seq.ps" , DC_CC_FS_FT },
+ {"cabs.seq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_ps[2] DATASEG =
+{{"c.ngl.ps" , DC_CC_FS_FT },
+ {"cabs.ngl.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_ps[2] DATASEG =
+{{"c.lt.ps" , DC_CC_FS_FT },
+ {"cabs.lt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_ps[2] DATASEG =
+{{"c.nge.ps" , DC_CC_FS_FT },
+ {"cabs.nge.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_ps[2] DATASEG =
+{{"c.le.ps" , DC_CC_FS_FT },
+ {"cabs.le.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_ps[2] DATASEG =
+{{"c.ngt.ps" , DC_CC_FS_FT },
+ {"cabs.ngt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_ps_mvcf[2] DATASEG =
+{{"movf.ps" , DC_FD_FS_CC },
+ {"movt.ps" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1x[64] DATASEG =
+{{"lwxc1" , DC_FD_IDX_BASE },
+ {"ldxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"luxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"swxc1" , DC_FS_IDX_BASE },
+ {"sdxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"suxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"prefx" , DC_PREF_IDX },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"alnv.ps" , DC_FD_FS_FT_RS },
+ {"invalid" , DC_BARE },
+ {"madd.s" , DC_FD_FR_FS_FT },
+ {"madd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"madd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"msub.s" , DC_FD_FR_FS_FT },
+ {"msub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"msub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmadd.s" , DC_FD_FR_FS_FT },
+ {"nmadd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmadd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmsub.s" , DC_FD_FR_FS_FT },
+ {"nmsub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmsub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_mdmx[8] DATASEG =
+{{ "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_qh[64] DATASEG =
+{{ "msgn.qh" , DC_VD_VS_VT_VEC},
+ { "c.eq.qh" , DC_VS_VT_VEC },
+ { "pickf.qh" , DC_VD_VS_VT_VEC},
+ { "pickt.qh" , DC_VD_VS_VT_VEC},
+ { "c.lt.qh" , DC_VS_VT_VEC },
+ { "c.le.qh" , DC_VS_VT_VEC },
+ { "min.qh" , DC_VD_VS_VT_VEC},
+ { "max.qh" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.qh" , DC_VD_VS_VT_VEC},
+ { "add.qh" , DC_VD_VS_VT_VEC},
+ { "and.qh" , DC_VD_VS_VT_VEC},
+ { "xor.qh" , DC_VD_VS_VT_VEC},
+ { "or.qh" , DC_VD_VS_VT_VEC},
+ { "nor.qh" , DC_VD_VS_VT_VEC},
+
+ { "sll.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.qh" , DC_VD_VS_VT_VEC},
+ { "sra.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$34" , DC_DEREF },
+
+ { "rzu.qh" , DC_VD_VT },
+ { "rnau.qh" , DC_VD_VT },
+ { "rneu.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "rzs.qh" , DC_VD_VT },
+ { "rnas.qh" , DC_VD_VT },
+ { "rnes.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$21" , DC_DEREF },
+ { "$22" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$23" , DC_DEREF },
+ { "$24" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$25" , DC_DEREF },
+ { "$26" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_ob[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "c.eq.ob" , DC_VS_VT_VEC },
+ { "pickf.ob" , DC_VD_VS_VT_VEC},
+ { "pickt.ob" , DC_VD_VS_VT_VEC},
+ { "c.lt.ob" , DC_VS_VT_VEC },
+ { "c.le.ob" , DC_VS_VT_VEC },
+ { "min.ob" , DC_VD_VS_VT_VEC},
+ { "max.ob" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.ob" , DC_VD_VS_VT_VEC},
+ { "add.ob" , DC_VD_VS_VT_VEC},
+ { "and.ob" , DC_VD_VS_VT_VEC},
+ { "xor.ob" , DC_VD_VS_VT_VEC},
+ { "or.ob" , DC_VD_VS_VT_VEC},
+ { "nor.ob" , DC_VD_VS_VT_VEC},
+
+ { "sll.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$35" , DC_DEREF },
+
+ { "rzu.ob" , DC_VD_VT },
+ { "rnau.ob" , DC_VD_VT },
+ { "rneu.ob" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$27" , DC_DEREF },
+ { "$28" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$29" , DC_DEREF },
+ { "$30" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$31" , DC_DEREF },
+ { "$32" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_alni[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_qh[2] DATASEG =
+{{ "muls.qh" , DC_VS_VT_VEC },
+ { "mulsl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_qh[2] DATASEG =
+{{ "mula.qh" , DC_VS_VT_VEC },
+ { "mull.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_qh[2] DATASEG =
+{{ "suba.qh" , DC_VS_VT_VEC },
+ { "subl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_qh[2] DATASEG =
+{{ "adda.qh" , DC_VS_VT_VEC },
+ { "addl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_qh[4] DATASEG =
+{{ "wacl.qh" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.qh" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_qh[4] DATASEG =
+{{ "racl.qh" , DC_VD },
+ { "racm.qh" , DC_VD },
+ { "rach.qh" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_ob[2] DATASEG =
+{{ "muls.ob" , DC_VS_VT_VEC },
+ { "mulsl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_ob[2] DATASEG =
+{{ "mula.ob" , DC_VS_VT_VEC },
+ { "mull.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_ob[2] DATASEG =
+{{ "suba.ob" , DC_VS_VT_VEC },
+ { "subl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_ob[2] DATASEG =
+{{ "adda.ob" , DC_VS_VT_VEC },
+ { "addl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_ob[4] DATASEG =
+{{ "wacl.ob" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.ob" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_ob[4] DATASEG =
+{{ "racl.ob" , DC_VD },
+ { "racm.ob" , DC_VD },
+ { "rach.ob" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_ob[16] DATASEG =
+{{ "shfl.upsl.ob" , DC_VD_VS_VT },
+ { "shfl.pach.ob" , DC_VD_VS_VT },
+ { "shfl.mixh.ob" , DC_VD_VS_VT },
+ { "shfl.mixl.ob" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_qh[8] DATASEG =
+{{ "shfl.bfla.qh" , DC_VD_VS_VT },
+ { "shfl.pach.qh" , DC_VD_VS_VT },
+ { "shfl.mixh.qh" , DC_VD_VS_VT },
+ { "shfl.mixl.qh" , DC_VD_VS_VT },
+ { "shfl.repa.qh" , DC_VD_VS_VT },
+ { "shfl.repb.qh" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+
+
+const disasm_deref_t disasm_deref[] =
+/* Disasm array shft msk */
+{{ disasm_normal , 26, 0x3f }, /* 0 */
+ { disasm_special , 0, 0x3f }, /* 1 */
+ { disasm_regimm , 16, 0x1f }, /* 2 */
+ { disasm_spec2 , 0, 0x3f }, /* 3 */
+ { disasm_cop0 , 21, 0x1f }, /* 4 */
+ { disasm_cop0_c0 , 0, 0x3f }, /* 5 */
+ { disasm_cop1 , 21, 0x1f }, /* 6 */
+ { disasm_cop1_s , 0, 0x3f }, /* 7 */
+ { disasm_cop1_s_mvcf , 16, 0x1 }, /* 8 */
+ { disasm_cop1_d , 0, 0x3f }, /* 9 */
+ { disasm_cop1_d_mvcf , 16, 0x1 }, /* 10 */
+ { disasm_cop1_w , 0, 0x3f }, /* 11 */
+ { disasm_cop1_l , 0, 0x3f }, /* 12 */
+ { disasm_cop1_ps , 0, 0x3f }, /* 13 */
+ { disasm_cop1_ps_mvcf, 16, 0x1 }, /* 14 */
+ { disasm_cop1x , 0, 0x3f }, /* 15 */
+ { disasm_movci , 16, 0x1 }, /* 16 */
+ { disasm_cop1_bc1 , 16, 0x3 }, /* 17 */
+ { disasm_mdmx , 21, 0x7 }, /* 18 */
+ { disasm_mdmx_qh , 0, 0x3f }, /* 19 */
+ { disasm_mdmx_ob , 0, 0x3f }, /* 20 */
+ { disasm_mdmx_muls_qh, 10, 0x1 }, /* 21 */
+ { disasm_mdmx_mul_qh , 10, 0x1 }, /* 22 */
+ { disasm_mdmx_sub_qh , 10, 0x1 }, /* 23 */
+ { disasm_mdmx_add_qh , 10, 0x1 }, /* 24 */
+ { disasm_mdmx_wac_qh , 24, 0x3 }, /* 25 */
+ { disasm_mdmx_rac_qh , 24, 0x3 }, /* 26 */
+ { disasm_mdmx_muls_ob, 10, 0x1 }, /* 27 */
+ { disasm_mdmx_mul_ob , 10, 0x1 }, /* 28 */
+ { disasm_mdmx_sub_ob , 10, 0x1 }, /* 29 */
+ { disasm_mdmx_add_ob , 10, 0x1 }, /* 30 */
+ { disasm_mdmx_wac_ob , 24, 0x3 }, /* 31 */
+ { disasm_mdmx_rac_ob , 24, 0x3 }, /* 32 */
+ { disasm_mdmx_alni , 0, 0x3f }, /* 33 */
+ { disasm_mdmx_shfl_ob, 22, 0xf }, /* 34 */
+ { disasm_mdmx_shfl_qh, 23, 0x7 }, /* 35 */
+ { disasm_cop1_bc1any2, 16, 0x1 }, /* 36 */
+ { disasm_cop1_bc1any4, 16, 0x1 }, /* 37 */
+ { disasm_cop1_c_f_s , 6, 0x1 }, /* 38 */
+ { disasm_cop1_c_un_s , 6, 0x1 }, /* 39 */
+ { disasm_cop1_c_eq_s , 6, 0x1 }, /* 40 */
+ { disasm_cop1_c_ueq_s, 6, 0x1 }, /* 41 */
+ { disasm_cop1_c_olt_s, 6, 0x1 }, /* 42 */
+ { disasm_cop1_c_ult_s, 6, 0x1 }, /* 43 */
+ { disasm_cop1_c_ole_s, 6, 0x1 }, /* 44 */
+ { disasm_cop1_c_ule_s, 6, 0x1 }, /* 45 */
+ { disasm_cop1_c_sf_s , 6, 0x1 }, /* 46 */
+ { disasm_cop1_c_ngle_s, 6, 0x1 }, /* 47 */
+ { disasm_cop1_c_seq_s, 6, 0x1 }, /* 48 */
+ { disasm_cop1_c_ngl_s, 6, 0x1 }, /* 49 */
+ { disasm_cop1_c_lt_s , 6, 0x1 }, /* 50 */
+ { disasm_cop1_c_nge_s, 6, 0x1 }, /* 51 */
+ { disasm_cop1_c_le_s , 6, 0x1 }, /* 52 */
+ { disasm_cop1_c_ngt_s, 6, 0x1 }, /* 53 */
+ { disasm_cop1_c_f_d , 6, 0x1 }, /* 54 */
+ { disasm_cop1_c_un_d , 6, 0x1 }, /* 55 */
+ { disasm_cop1_c_eq_d , 6, 0x1 }, /* 56 */
+ { disasm_cop1_c_ueq_d, 6, 0x1 }, /* 57 */
+ { disasm_cop1_c_olt_d, 6, 0x1 }, /* 58 */
+ { disasm_cop1_c_ult_d, 6, 0x1 }, /* 59 */
+ { disasm_cop1_c_ole_d, 6, 0x1 }, /* 60 */
+ { disasm_cop1_c_ule_d, 6, 0x1 }, /* 61 */
+ { disasm_cop1_c_sf_d , 6, 0x1 }, /* 62 */
+ { disasm_cop1_c_ngle_d, 6, 0x1 }, /* 63 */
+ { disasm_cop1_c_seq_d, 6, 0x1 }, /* 64 */
+ { disasm_cop1_c_ngl_d, 6, 0x1 }, /* 65 */
+ { disasm_cop1_c_lt_d , 6, 0x1 }, /* 66 */
+ { disasm_cop1_c_nge_d, 6, 0x1 }, /* 67 */
+ { disasm_cop1_c_le_d , 6, 0x1 }, /* 68 */
+ { disasm_cop1_c_ngt_d, 6, 0x1 }, /* 69 */
+ { disasm_cop1_c_f_ps , 6, 0x1 }, /* 70 */
+ { disasm_cop1_c_un_ps, 6, 0x1 }, /* 71 */
+ { disasm_cop1_c_eq_ps, 6, 0x1 }, /* 72 */
+ { disasm_cop1_c_ueq_ps, 6, 0x1 }, /* 73 */
+ { disasm_cop1_c_olt_ps, 6, 0x1 }, /* 74 */
+ { disasm_cop1_c_ult_ps, 6, 0x1 }, /* 75 */
+ { disasm_cop1_c_ole_ps, 6, 0x1 }, /* 76 */
+ { disasm_cop1_c_ule_ps, 6, 0x1 }, /* 77 */
+ { disasm_cop1_c_sf_ps, 6, 0x1 }, /* 78 */
+ { disasm_cop1_c_ngle_ps, 6, 0x1 }, /* 79 */
+ { disasm_cop1_c_seq_ps, 6, 0x1 }, /* 80 */
+ { disasm_cop1_c_ngl_ps, 6, 0x1 }, /* 81 */
+ { disasm_cop1_c_lt_ps, 6, 0x1 }, /* 82 */
+ { disasm_cop1_c_nge_ps, 6, 0x1 }, /* 83 */
+ { disasm_cop1_c_le_ps, 6, 0x1 }, /* 84 */
+ { disasm_cop1_c_ngt_ps, 6, 0x1 }, /* 85 */
+};
+
+#define PREFHINT(x) (&pref_hints[(x)*9])
+static char *pref_hints =
+ "load \0"
+ "store \0"
+ "reserved\0"
+ "reserved\0"
+
+ "ld_strm \0"
+ "st_strm \0"
+ "ld_retn \0"
+ "st_retn \0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "wb_inval\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0";
+
+
+static int snprintf(char *buf,int len,const char *templat,...)
+{
+ va_list marker;
+ int count;
+
+ va_start(marker,templat);
+ count = xvsprintf(buf,templat,marker);
+ va_end(marker);
+
+ return count;
+}
+
+static const disasm_t *get_disasm_field(uint32_t inst)
+{
+ const disasm_deref_t *tmp = &disasm_deref[0];
+ const disasm_t *rec;
+ do {
+ rec = &(tmp->ptr[(inst>>tmp->shift) & tmp->mask]);
+ tmp = &disasm_deref[atoi(&(rec->name[1]))];
+ } while (rec->type == DC_DEREF);
+ return rec;
+}
+
+char *disasm_inst_name(uint32_t inst)
+{
+ return (char *)(get_disasm_field(inst)->name);
+}
+
+void disasm_inst(char *buf, int buf_size, uint32_t inst, uint64_t pc)
+{
+ const disasm_t *tmp;
+ char instname[32];
+ int commentmode = 0;
+ char *x;
+
+ tmp = get_disasm_field(inst);
+
+ strcpy(instname,(char *) tmp->name);
+
+ if ((x = strchr(instname,'@'))) {
+ *x++ = 0;
+ commentmode = atoi(x);
+ }
+
+ switch (tmp->type) {
+ case DC_RD_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RD_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_RS_XIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#0x%" PF_32 "x",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RS_RT_OFS:
+ snprintf(buf, buf_size, "%-8s %s,%s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RS_OFS:
+ snprintf(buf, buf_size, "%-8s %s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ pc + 4 + (SEXT_64(16, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RT_SA:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>6) & 0x1f);
+ break;
+ case DC_RT_UIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RD:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>11) & 0x1f));
+ break;
+ case DC_J:
+ snprintf(buf, buf_size, "%-8s 0x%" PF_64 "x",
+ instname,
+ (pc & UINT64_T(0xfffffffff0000000)) | ((inst & 0x3ffffff)<<2));
+ break;
+ case DC_RD_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RD_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>11) & 0x1f),
+ inst & 0x3);
+ break;
+ case DC_RT_CR_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%d,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f,
+ inst & 0x3);
+ break;
+ case DC_RS:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d(%s)",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,#%" PF_32 "d(%s)",
+ instname,
+ (inst>>16) & 0x1f,
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>6) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FS_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_RT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_FD_FS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d",
+ instname,
+ (inst>>6)&0x1f,
+ (inst>>11)&0x1f);
+ break;
+ case DC_PREF_OFS:
+ snprintf(buf, buf_size, "%-8s #%" PF_32 "d(%s) /* %s */",
+ instname,
+ SEXT_32(15, inst & 0xffff),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_PREF_IDX:
+ snprintf(buf, buf_size, "%-8s %s(%s) /* %s */",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_CC_OFS:
+ snprintf(buf, buf_size, "%-8s %d,0x%" PF_64 "x",
+ instname,
+ (inst>>18) & 0x7,
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RS_CC:
+ snprintf(buf, buf_size, "%-8s %s,%s,%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FS_CC:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FR_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>21) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_FT_RS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_CC_FS_FT:
+ snprintf(buf, buf_size, "%-8s %d,f%d,f%d",
+ instname,
+ (inst>>8) & 0x7,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_BARE:
+ snprintf(buf, buf_size, "%-8s", instname);
+ break;
+ case DC_RT_FS:
+ snprintf(buf, buf_size, "%-8s %s,f%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VS:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VD:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>6) & 0x1f);
+ break;
+ case DC_VD_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VD_VS_VT_IMM:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>21) & 0x7);
+ break;
+ case DC_VD_VS_VT_RS:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_VD_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$#%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_VD_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_SYSCALL:
+ snprintf(buf, buf_size, "%-8s #%d",
+ instname,
+ (inst>>6) & 0xfffff);
+ break;
+ case DC_BREAK:
+ snprintf(buf, buf_size, "%-8s %d", instname, (inst>>6)&0xfffff);
+ break;
+ case DC_OOPS:
+ snprintf(buf, buf_size, "%s OOPS! FIXME!", instname);
+ break;
+ default:
+ /* Hit something we don't know about...Shouldn't happen. */
+ break;
+ }
+
+ /*
+ * Handle comment field
+ */
+
+
+ switch (commentmode) {
+ case 1: /* CP0 ops */
+ if ((inst & 3) == 0) { /* select 0 */
+ snprintf(buf + strlen(buf),buf_size-strlen(buf)," /* %s */",
+ CP0REGNAME((inst >> 11) & 0x1f));
+ }
+ break;
+ default:
+ break;
+ }
+
+ buf[buf_size-1] = 0;
+
+}