diff options
Diffstat (limited to 'cfe/cfe/arch/mips/common/src/disasm.c')
-rw-r--r-- | cfe/cfe/arch/mips/common/src/disasm.c | 2111 |
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; + +} |