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