1 /* radare - LGPL - Copyright 2016 - bobby.smiles32@gmail.com */
2 
3 #include "rsp_idec.h"
4 
5 
6 const char* rsp_gp_reg_soft_names[] = {
7 	"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
8 	"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
9 	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
10 	"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
11 };
12 
13 const char* rsp_c0_reg_soft_names[] = {
14 	"SP_MEM_ADDR", "SP_DRAM_ADDR", "SP_RD_LEN",     "SP_WR_LEN",
15 	"SP_STATUS",   "SP_DMA_FULL",  "SP_DMA_BUSY",   "SP_SEMAPHORE",
16 	"DPC_START",   "DPC_END",      "DPC_CURRENT",   "DPC_STATUS",
17 	"DPC_CLOCK",   "DPC_BUF_BUSY", "DPC_PIPE_BUSY", "DPC_TMEM_BUSY"
18 };
19 
20 const char* rsp_gp_reg_names[] = {
21 	"$0",  "$1",  "$2",  "$3",  "$4",  "$5",  "$6",  "$7",
22 	"$8",  "$9",  "$10", "$11", "$12", "$13", "$14", "$15",
23 	"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
24 	"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
25 };
26 
27 const char* rsp_c0_reg_names[] = {
28 	"$c0", "$c1", "$c2",  "$c3",  "$c4",  "$c5",  "$c6",  "$c7",
29 	"$c8", "$c9", "$c10", "$c11", "$c12", "$c13", "$c14", "$c15"
30 };
31 
32 const char* rsp_c2_creg_names[] = {
33 	"$vco", "$vcc", "$vce", "???"
34 };
35 
36 const char* rsp_c2_accu_names[] = {
37 	"ACC_H", "ACC_M", "ACC_L", "???"
38 };
39 
40 const char* rsp_c2_vreg_names[] = {
41 	"$v0",  "$v1",  "$v2",  "$v3",  "$v4",  "$v5",  "$v6",  "$v7",
42 	"$v8",  "$v9",  "$v10", "$v11", "$v12", "$v13", "$v14", "$v15",
43 	"$v16", "$v17", "$v18", "$v19", "$v20", "$v21", "$v22", "$v23",
44 	"$v24", "$v25", "$v26", "$v27", "$v28", "$v29", "$v30", "$v31"
45 };
46 
47 const char* rsp_c2_vreg_element_names[] = {
48 	"",    "[?]", "[0q]", "[1q]", "[0h]", "[1h]", "[2h]", "[3h]",
49 	"[0]", "[1]", "[2]",  "[3]",  "[4]",  "[5]",  "[6]",  "[7]"
50 };
51 
52 /* Operand decoders description */
53 #define RS_DECODER              { RSP_OPND_GP_REG,          21, 0x1f,    0, 0, 0, 0, 0 }
54 #define RT_DECODER              { RSP_OPND_GP_REG,          16, 0x1f,    0, 0, 0, 0, 0 }
55 #define RD_DECODER              { RSP_OPND_GP_REG,          11, 0x1f,    0, 0, 0, 0, 0 }
56 #define SA_DECODER              { RSP_OPND_SHIFT_AMOUNT,     6, 0x1f,    0, 0, 0, 0, 0 }
57 #define LUI_DECODER             { RSP_OPND_ZIMM,             0, 0xffff, 16, 0, 0, 0, 0 }
58 #define ZIMM_DECODER            { RSP_OPND_ZIMM,             0, 0xffff,  0, 0, 0, 0, 0 }
59 #define SIMM_DECODER            { RSP_OPND_SIMM,             0, 0,       0, 0, 0xffff, 0x8000, 0 }
60 #define OFFSET_DECODER          { RSP_OPND_OFFSET,           0, 0,       0, 0, 0xffff, 0x8000, 2 }
61 #define BASE_OFFSET_DECODER     { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0xffff, 0x8000, 0 }
62 #define TARGET_DECODER          { RSP_OPND_TARGET,           0, 0x03ff,  2, 0, 0, 0, 0 }
63 #define C0_REG_DECODER          { RSP_OPND_C0_REG,          11, 0x0f,    0, 0, 0, 0, 0 }
64 #define C2_CREG_DECODER         { RSP_OPND_C2_CREG,         11, 0x03,    0, 0, 0, 0, 0 }
65 #define C2_ACCU_DECODER         { RSP_OPND_C2_ACCU,         21, 0x03,    0, 0, 0, 0, 0 }
66 #define VS_DECODER              { RSP_OPND_C2_VREG,         11, 0x1f,    0, 0, 0, 0, 0 }
67 #define VD_DECODER              { RSP_OPND_C2_VREG,          6, 0x1f,    0, 0, 0, 0, 0 }
68 #define VT_BYTE_DECODER         { RSP_OPND_C2_VREG_BYTE,    16, 0x1f,    0, 7, 0xf, 0, 0 }
69 #define VS_BYTE_DECODER         { RSP_OPND_C2_VREG_BYTE,    11, 0x1f,    0, 7, 0xf, 0, 0 }
70 #define VT_SCALAR_DECODER       { RSP_OPND_C2_VREG_SCALAR,  16, 0x1f,    0,21, 0x7, 0, 0 }
71 #define VD_SCALAR_DECODER       { RSP_OPND_C2_VREG_SCALAR,   6, 0x1f,    0,11, 0x7, 0, 0 }
72 #define VT_ELEMENT_DECODER      { RSP_OPND_C2_VREG_ELEMENT, 16, 0x1f,    0,21, 0xf, 0, 0 }
73 #define BASE_VOFFSET1_DECODER   { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0x7f, 0x40, 0 }
74 #define BASE_VOFFSET2_DECODER   { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0x7f, 0x40, 1 }
75 #define BASE_VOFFSET4_DECODER   { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0x7f, 0x40, 2 }
76 #define BASE_VOFFSET8_DECODER   { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0x7f, 0x40, 3 }
77 #define BASE_VOFFSET16_DECODER  { RSP_OPND_BASE_OFFSET,     21, 0x1f,    0, 0, 0x7f, 0x40, 4 }
78 
79 /* Operands description */
80 #define OPNDS_NONE              0,
81 #define OPNDS_TARGET            1, { TARGET_DECODER }
82 #define OPNDS_RS_OFFSET         2, { RS_DECODER, OFFSET_DECODER }
83 #define OPNDS_RS_RT_OFFSET      3, { RS_DECODER, RT_DECODER, OFFSET_DECODER }
84 #define OPNDS_RT_BASE_OFFSET    2, { RT_DECODER, BASE_OFFSET_DECODER }
85 #define OPNDS_RS                1, { RS_DECODER }
86 #define OPNDS_RT_LUI            2, { RT_DECODER, LUI_DECODER }
87 #define OPNDS_RT_RS_SIMM        3, { RT_DECODER, RS_DECODER, SIMM_DECODER }
88 #define OPNDS_RT_RS_ZIMM        3, { RT_DECODER, RS_DECODER, ZIMM_DECODER }
89 #define OPNDS_RD_RT_SA          3, { RD_DECODER, RT_DECODER, SA_DECODER }
90 #define OPNDS_RD_RT_RS          3, { RD_DECODER, RT_DECODER, RS_DECODER }
91 #define OPNDS_RD_RS_RT          3, { RD_DECODER, RS_DECODER, RT_DECODER }
92 #define OPNDS_RT_C0_REG         2, { RT_DECODER, C0_REG_DECODER }
93 #define OPNDS_RT_C2_CREG        2, { RT_DECODER, C2_CREG_DECODER }
94 #define OPNDS_RT_VSB            2, { RT_DECODER, VS_BYTE_DECODER }
95 #define OPNDS_VDS_VTS           2, { VD_SCALAR_DECODER, VT_SCALAR_DECODER }
96 #define OPNDS_VTB_BASE_OFFSET1  2, { VT_BYTE_DECODER, BASE_VOFFSET1_DECODER }
97 #define OPNDS_VTB_BASE_OFFSET2  2, { VT_BYTE_DECODER, BASE_VOFFSET2_DECODER }
98 #define OPNDS_VTB_BASE_OFFSET4  2, { VT_BYTE_DECODER, BASE_VOFFSET4_DECODER }
99 #define OPNDS_VTB_BASE_OFFSET8  2, { VT_BYTE_DECODER, BASE_VOFFSET8_DECODER }
100 #define OPNDS_VTB_BASE_OFFSET16 2, { VT_BYTE_DECODER, BASE_VOFFSET16_DECODER }
101 #define OPNDS_VD_VS_C2_ACCU     3, { VD_DECODER, VS_DECODER, C2_ACCU_DECODER }
102 #define OPNDS_VD_VS_VTE         3, { VD_DECODER, VS_DECODER, VT_ELEMENT_DECODER }
103 
104 /* Instructions description */
105 #define INVALID { "invalid", RSP_OP_INVALID,   OPNDS_NONE }
106 #define NOP     { "nop",     RSP_OP_NOP,       OPNDS_NONE }
107 #define SLL     { "sll",     RSP_OP_SLL,       OPNDS_RD_RT_SA }
108 #define SRL     { "srl",     RSP_OP_SRL,       OPNDS_RD_RT_SA }
109 #define SRA     { "sra",     RSP_OP_SRA,       OPNDS_RD_RT_SA }
110 #define SLLV    { "sllv",    RSP_OP_SLLV,      OPNDS_RD_RT_RS }
111 #define SRLV    { "srlv",    RSP_OP_SRLV,      OPNDS_RD_RT_RS }
112 #define SRAV    { "srav",    RSP_OP_SRAV,      OPNDS_RD_RT_RS }
113 #define JR      { "jr",      RSP_OP_JR,        OPNDS_RS }
114 #define BREAK   { "break",   RSP_OP_BREAK,     OPNDS_NONE }
115 #define ADD     { "add",     RSP_OP_ADD,       OPNDS_RD_RS_RT }
116 #define ADDU    { "addu",    RSP_OP_ADDU,      OPNDS_RD_RS_RT }
117 #define SUB     { "sub",     RSP_OP_SUB,       OPNDS_RD_RS_RT }
118 #define SUBU    { "subu",    RSP_OP_SUBU,      OPNDS_RD_RS_RT }
119 #define AND     { "and",     RSP_OP_AND,       OPNDS_RD_RS_RT }
120 #define OR      { "or",      RSP_OP_OR,        OPNDS_RD_RS_RT }
121 #define XOR     { "xor",     RSP_OP_XOR,       OPNDS_RD_RS_RT }
122 #define NOR     { "nor",     RSP_OP_NOR,       OPNDS_RD_RS_RT }
123 #define SLT     { "slt",     RSP_OP_SLT,       OPNDS_RD_RS_RT }
124 #define SLTU    { "sltu",    RSP_OP_SLTU,      OPNDS_RD_RS_RT }
125 #define BLTZ    { "bltz",    RSP_OP_BLTZ,      OPNDS_RS_OFFSET }
126 #define BGEZ    { "bgez",    RSP_OP_BGEZ,      OPNDS_RS_OFFSET }
127 #define BLTZAL  { "bltzal",  RSP_OP_BLTZAL,    OPNDS_RS_OFFSET }
128 #define BGEZAL  { "bgezal",  RSP_OP_BGEZAL,    OPNDS_RS_OFFSET }
129 #define MFC0    { "mfc0",    RSP_OP_MFC0,      OPNDS_RT_C0_REG }
130 #define MTC0    { "mtc0",    RSP_OP_MTC0,      OPNDS_RT_C0_REG }
131 #define MFC2    { "mfc2",    RSP_OP_MFC2,      OPNDS_RT_VSB }
132 #define MTC2    { "mtc2",    RSP_OP_MTC2,      OPNDS_RT_VSB }
133 #define CFC2    { "cfc2",    RSP_OP_CFC2,      OPNDS_RT_C2_CREG }
134 #define CTC2    { "ctc2",    RSP_OP_CTC2,      OPNDS_RT_C2_CREG }
135 #define VMULF   { "vmulf",   RSP_OP_VMULF,     OPNDS_VD_VS_VTE }
136 #define VMULU   { "vmulu",   RSP_OP_VMULU,     OPNDS_VD_VS_VTE }
137 #define VMUDL   { "vmudl",   RSP_OP_VMUDL,     OPNDS_VD_VS_VTE }
138 #define VMUDM   { "vmudm",   RSP_OP_VMUDM,     OPNDS_VD_VS_VTE }
139 #define VMUDN   { "vmudn",   RSP_OP_VMUDN,     OPNDS_VD_VS_VTE }
140 #define VMUDH   { "vmudh",   RSP_OP_VMUDH,     OPNDS_VD_VS_VTE }
141 #define VMACF   { "vmacf",   RSP_OP_VMACF,     OPNDS_VD_VS_VTE }
142 #define VMACU   { "vmacu",   RSP_OP_VMACU,     OPNDS_VD_VS_VTE }
143 #define VMADL   { "vmadl",   RSP_OP_VMADL,     OPNDS_VD_VS_VTE }
144 #define VMADM   { "vmadm",   RSP_OP_VMADM,     OPNDS_VD_VS_VTE }
145 #define VMADN   { "vmadn",   RSP_OP_VMADN,     OPNDS_VD_VS_VTE }
146 #define VMADH   { "vmadh",   RSP_OP_VMADH,     OPNDS_VD_VS_VTE }
147 #define VADD    { "vadd",    RSP_OP_VADD,      OPNDS_VD_VS_VTE }
148 #define VSUB    { "vsub",    RSP_OP_VSUB,      OPNDS_VD_VS_VTE }
149 #define VABS    { "vabs",    RSP_OP_VABS,      OPNDS_VD_VS_VTE }
150 #define VADDC   { "vaddc",   RSP_OP_VADDC,     OPNDS_VD_VS_VTE }
151 #define VSUBC   { "vsubc",   RSP_OP_VSUBC,     OPNDS_VD_VS_VTE }
152 #define VSAR    { "vsar",    RSP_OP_VSAR,      OPNDS_VD_VS_C2_ACCU }
153 #define VLT     { "vlt",     RSP_OP_VLT,       OPNDS_VD_VS_VTE }
154 #define VEQ     { "veq",     RSP_OP_VEQ,       OPNDS_VD_VS_VTE }
155 #define VNE     { "vne",     RSP_OP_VNE,       OPNDS_VD_VS_VTE }
156 #define VGE     { "vge",     RSP_OP_VGE,       OPNDS_VD_VS_VTE }
157 #define VCL     { "vcl",     RSP_OP_VCL,       OPNDS_VD_VS_VTE }
158 #define VCH     { "vch",     RSP_OP_VCH,       OPNDS_VD_VS_VTE }
159 #define VCR     { "vcr",     RSP_OP_VCR,       OPNDS_VD_VS_VTE }
160 #define VMRG    { "vmrg",    RSP_OP_VMRG,      OPNDS_VD_VS_VTE }
161 #define VAND    { "vand",    RSP_OP_VAND,      OPNDS_VD_VS_VTE }
162 #define VNAND   { "vnand",   RSP_OP_VNAND,     OPNDS_VD_VS_VTE }
163 #define VOR     { "vor",     RSP_OP_VOR,       OPNDS_VD_VS_VTE }
164 #define VNOR    { "vnor",    RSP_OP_VNOR,      OPNDS_VD_VS_VTE }
165 #define VXOR    { "vxor",    RSP_OP_VXOR,      OPNDS_VD_VS_VTE }
166 #define VNXOR   { "vnxor",   RSP_OP_VNXOR,     OPNDS_VD_VS_VTE }
167 #define VRCP    { "vrcp",    RSP_OP_VRCP,      OPNDS_VDS_VTS }
168 #define VRCPL   { "vrcpl",   RSP_OP_VRCPL,     OPNDS_VDS_VTS }
169 #define VRCPH   { "vrcph",   RSP_OP_VRCPH,     OPNDS_VDS_VTS }
170 #define VMOV    { "vmov",    RSP_OP_VMOV,      OPNDS_VDS_VTS }
171 #define VRSQ    { "vrsq",    RSP_OP_VRSQ,      OPNDS_VDS_VTS }
172 #define VRSQL   { "vrsql",   RSP_OP_VRSQL,     OPNDS_VDS_VTS }
173 #define VRSQH   { "vrsqh",   RSP_OP_VRSQH,     OPNDS_VDS_VTS }
174 #define VNOP    { "vnop",    RSP_OP_VNOP,      OPNDS_NONE }
175 #define LBV     { "lbv",     RSP_OP_LBV,       OPNDS_VTB_BASE_OFFSET1 }
176 #define LSV     { "lsv",     RSP_OP_LSV,       OPNDS_VTB_BASE_OFFSET2 }
177 #define LLV     { "llv",     RSP_OP_LLV,       OPNDS_VTB_BASE_OFFSET4 }
178 #define LDV     { "ldv",     RSP_OP_LDV,       OPNDS_VTB_BASE_OFFSET8 }
179 #define LQV     { "lqv",     RSP_OP_LQV,       OPNDS_VTB_BASE_OFFSET16 }
180 #define LRV     { "lrv",     RSP_OP_LRV,       OPNDS_VTB_BASE_OFFSET16 }
181 #define LPV     { "lpv",     RSP_OP_LPV,       OPNDS_VTB_BASE_OFFSET8 }
182 #define LUV     { "luv",     RSP_OP_LUV,       OPNDS_VTB_BASE_OFFSET8 }
183 #define LHV     { "lhv",     RSP_OP_LHV,       OPNDS_VTB_BASE_OFFSET16 }
184 #define LFV     { "lfv",     RSP_OP_LFV,       OPNDS_VTB_BASE_OFFSET16 }
185 #define LTV     { "ltv",     RSP_OP_LTV,       OPNDS_VTB_BASE_OFFSET16 }
186 #define SBV     { "sbv",     RSP_OP_SBV,       OPNDS_VTB_BASE_OFFSET1 }
187 #define SSV     { "ssv",     RSP_OP_SSV,       OPNDS_VTB_BASE_OFFSET2 }
188 #define SLV     { "slv",     RSP_OP_SLV,       OPNDS_VTB_BASE_OFFSET4 }
189 #define SDV     { "sdv",     RSP_OP_SDV,       OPNDS_VTB_BASE_OFFSET8 }
190 #define SQV     { "sqv",     RSP_OP_SQV,       OPNDS_VTB_BASE_OFFSET16 }
191 #define SRV     { "srv",     RSP_OP_SRV,       OPNDS_VTB_BASE_OFFSET8 }
192 #define SPV     { "spv",     RSP_OP_SPV,       OPNDS_VTB_BASE_OFFSET8 }
193 #define SUV     { "suv",     RSP_OP_SUV,       OPNDS_VTB_BASE_OFFSET16 }
194 #define SHV     { "shv",     RSP_OP_SHV,       OPNDS_VTB_BASE_OFFSET16 }
195 #define SFV     { "sfv",     RSP_OP_SFV,       OPNDS_VTB_BASE_OFFSET16 }
196 #define SWV     { "swv",     RSP_OP_SWV,       OPNDS_VTB_BASE_OFFSET16 }
197 #define STV     { "stv",     RSP_OP_STV,       OPNDS_VTB_BASE_OFFSET16 }
198 #define J       { "j",       RSP_OP_J,         OPNDS_TARGET }
199 #define JAL     { "jal",     RSP_OP_JAL,       OPNDS_TARGET }
200 #define BEQ     { "beq",     RSP_OP_BEQ,       OPNDS_RS_RT_OFFSET }
201 #define BNE     { "bne",     RSP_OP_BNE,       OPNDS_RS_RT_OFFSET }
202 #define BLEZ    { "blez",    RSP_OP_BLEZ,      OPNDS_RS_RT_OFFSET }
203 #define BGTZ    { "bgtz",    RSP_OP_BGTZ,      OPNDS_RS_RT_OFFSET }
204 #define ADDI    { "addi",    RSP_OP_ADDI,      OPNDS_RT_RS_SIMM }
205 #define ADDIU   { "addiu",   RSP_OP_ADDIU,     OPNDS_RT_RS_SIMM }
206 #define SLTI    { "slti",    RSP_OP_SLTI,      OPNDS_RT_RS_SIMM }
207 #define SLTIU   { "sltiu",   RSP_OP_SLTIU,     OPNDS_RT_RS_SIMM }
208 #define ANDI    { "andi",    RSP_OP_ANDI,      OPNDS_RT_RS_ZIMM }
209 #define ORI     { "ori",     RSP_OP_ORI,       OPNDS_RT_RS_ZIMM }
210 #define XORI    { "xori",    RSP_OP_XORI,      OPNDS_RT_RS_ZIMM }
211 #define LUI     { "lui",     RSP_OP_LUI,       OPNDS_RT_LUI }
212 #define LB      { "lb",      RSP_OP_LB,        OPNDS_RT_BASE_OFFSET }
213 #define LH      { "lh",      RSP_OP_LH,        OPNDS_RT_BASE_OFFSET }
214 #define LW      { "lw",      RSP_OP_LW,        OPNDS_RT_BASE_OFFSET }
215 #define LBU     { "lbu",     RSP_OP_LBU,       OPNDS_RT_BASE_OFFSET }
216 #define LHU     { "lhu",     RSP_OP_LHU,       OPNDS_RT_BASE_OFFSET }
217 #define SB      { "sb",      RSP_OP_SB,        OPNDS_RT_BASE_OFFSET }
218 #define SH      { "sh",      RSP_OP_SH,        OPNDS_RT_BASE_OFFSET }
219 #define SW      { "sw",      RSP_OP_SW,        OPNDS_RT_BASE_OFFSET }
220 
221 typedef struct {
222 	rsp_operand_type type;
223 	unsigned int u_shift;
224 	ut32 u_mask;
225 	unsigned int u_lshift;
226 	unsigned int s_shift;
227 	ut32 s_mask;
228 	ut32 s_smask;
229 	unsigned int s_lshift;
230 } rsp_operand_decoder;
231 
232 typedef struct {
233 	const char* mnemonic;
234 	rsp_opcode opcode;
235 	int noperands;
236 	rsp_operand_decoder odecs[RSP_MAX_OPNDS];
237 } rsp_instruction_priv;
238 
239 static const rsp_instruction_priv rsp_op_table[] = {
240 /* SPECIAL opcodes table
241  * 0-63
242  */
243 	SLL,     INVALID, SRL,     SRA,     SLLV,    INVALID, SRLV,    SRAV,
244 	JR,      INVALID, INVALID, INVALID, INVALID, BREAK,   INVALID, INVALID,
245 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
246 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
247 	ADD,     ADDU,    SUB,     SUBU,    AND,     OR,      XOR,     NOR,
248 	INVALID, INVALID, SLT,     SLTU,    INVALID, INVALID, INVALID, INVALID,
249 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
250 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
251 /* REGIMM opcodes table
252 * 64-95
253 */
254 	BLTZ,    BGEZ,    INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
255 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
256 	BLTZAL,  BGEZAL,  INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
257 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
258 /* COP0 opcodes table
259 * 96-127
260 */
261 	MFC0,    INVALID, INVALID, INVALID, MTC0,    INVALID, INVALID, INVALID,
262 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
263 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
264 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
265 /* COP2/1 opcodes table
266 * 128-159
267 */
268 	MFC2,    INVALID, CFC2,    INVALID, MTC2,    INVALID, CTC2,    INVALID,
269 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
270 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
271 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
272 /* COP2/2 opcodes table
273 * 160-223
274 */
275 	VMULF,   VMULU,   INVALID, INVALID, VMUDL,   VMUDM,   VMUDN,   VMUDH,
276 	VMACF,   VMACU,   INVALID, INVALID, VMADL,   VMADM,   VMADN,   VMADH,
277 	VADD,    VSUB,    INVALID, VABS,    VADDC,   VSUBC,   INVALID, INVALID,
278 	INVALID, INVALID, INVALID, INVALID, INVALID, VSAR,    INVALID, INVALID,
279 	VLT,     VEQ,     VNE,     VGE,     VCL,     VCH,     VCR,     VMRG,
280 	VAND,    VNAND,   VOR,     VNOR,    VXOR,    VNXOR,   INVALID, INVALID,
281 	VRCP,    VRCPL,   VRCPH,   VMOV,    VRSQ,    VRSQL,   VRSQH,   VNOP,
282 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
283 /* LWC2 opcodes table
284 * 224-255
285 */
286 	LBV,     LSV,     LLV,     LDV,     LQV,     LRV,     LPV,     LUV,
287 	LHV,     LFV,     INVALID, LTV,     INVALID, INVALID, INVALID, INVALID,
288 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
289 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
290 /* SWC2 opcodes table
291 * 256-287
292 */
293 	SBV,     SSV,     SLV,     SDV,     SQV,     SRV,     SPV,     SUV,
294 	SHV,     SFV,     SWV,     STV,     INVALID, INVALID, INVALID, INVALID,
295 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
296 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
297 /* Main opcodes table
298 * 288-351
299 */
300 	INVALID, INVALID, J,       JAL,     BEQ,     BNE,     BLEZ,    BGTZ,
301 	ADDI,    ADDIU,   SLTI,    SLTIU,   ANDI,    ORI,     XORI,    LUI,
302 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
303 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
304 	LB,      LH,      INVALID, LW,      LBU,     LHU,     INVALID, INVALID,
305 	SB,      SH,      INVALID, SW,      INVALID, INVALID, INVALID, INVALID,
306 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
307 	INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
308 /* Pseudo opcodes
309 * 352 - ???
310 */
311 	NOP
312 };
313 
314 #define SPECIAL   { 0,    0, 0x3f }
315 #define REGIMM    { 64,  16, 0x1f }
316 #define COP0      { 96,  21, 0x1f }
317 #define COP2      { 128, 21, 0x1f }
318 #define VECTOP    { 160,  0, 0x3f }
319 #define LWC2      { 224, 11, 0x1f }
320 #define SWC2      { 256, 11, 0x1f }
321 #define MAIN      { 288, 26, 0x3f }
322 
323 typedef struct {
324 	ut16 offset;
325 	ut8 shift;
326 	ut8 mask;
327 } rsp_op_escape;
328 
329 static const rsp_op_escape rsp_escapes_table[] = {
330 	SPECIAL, SPECIAL, REGIMM,  REGIMM, MAIN,    MAIN,    MAIN,    MAIN,
331 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
332 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
333 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
334 	COP0,    COP0,    MAIN,    MAIN,   COP2,    VECTOP,  MAIN,    MAIN,
335 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
336 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
337 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
338 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
339 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
340 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
341 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
342 	MAIN,    MAIN,    MAIN,    MAIN,   LWC2,    LWC2,    MAIN,    MAIN,
343 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN,
344 	MAIN,    MAIN,    MAIN,    MAIN,   SWC2,    SWC2,    MAIN,    MAIN,
345 	MAIN,    MAIN,    MAIN,    MAIN,   MAIN,    MAIN,    MAIN,    MAIN
346 };
347 
348 
rsp_decode_priv(ut32 iw)349 static const rsp_instruction_priv* rsp_decode_priv(ut32 iw) {
350 	const rsp_op_escape* escape;
351 
352 	/* handle NOP pseudo instruction */
353 	if (iw == 0) {
354 		return &rsp_op_table[352];
355 	}
356 
357 	escape = &rsp_escapes_table[(iw >> 25)];
358 	return &rsp_op_table[escape->offset + ((iw >> escape->shift) & escape->mask)];
359 }
360 
rsp_sign_extend(st32 x,st32 m)361 static inline st32 rsp_sign_extend(st32 x, st32 m)
362 {
363 	/* assume that bits of x above the m are already zeros
364 	* which is the case when called from rsp_operand_decode
365 	*/
366 	return (x ^ m) - m;
367 }
368 
rsp_operand_decode(ut64 pc,ut32 iw,const rsp_operand_decoder * odec)369 static rsp_operand rsp_operand_decode(ut64 pc, ut32 iw, const rsp_operand_decoder* odec) {
370 	rsp_operand opnd;
371 
372 	opnd.type = odec->type;
373 	opnd.u = ((iw >> odec->u_shift) & odec->u_mask) << odec->u_lshift;
374 	opnd.s = rsp_sign_extend ((iw >> odec->s_shift) & odec->s_mask, odec->s_smask) << odec->s_lshift;
375 
376 	/* handle targets/offsets IMEM addresses */
377 	switch (opnd.type) {
378 	case RSP_OPND_TARGET:
379 		opnd.u = rsp_mem_addr (opnd.u, RSP_IMEM_OFFSET);
380 		break;
381 	case RSP_OPND_OFFSET:
382 		/* +4 for delay slot */
383 		opnd.u = rsp_mem_addr (pc + 4 + opnd.s, RSP_IMEM_OFFSET);
384 		break;
385 	default: /* do nothing */ break;
386 	}
387 
388 	return opnd;
389 }
390 
rsp_instruction_decode(ut64 pc,ut32 iw)391 rsp_instruction rsp_instruction_decode(ut64 pc, ut32 iw) {
392 	int opnd;
393 	const rsp_instruction_priv* priv = rsp_decode_priv (iw);
394 
395 	rsp_instruction r_instr;
396 
397 	r_instr.mnemonic = priv->mnemonic;
398 	r_instr.opcode = priv->opcode;
399 	r_instr.noperands = priv->noperands;
400 	for (opnd = 0; opnd < r_instr.noperands; opnd++) {
401 		r_instr.operands[opnd] = rsp_operand_decode (pc, iw, &priv->odecs[opnd]);
402 	}
403 
404 	return r_instr;
405 }
406