20 #include "Disassembler.h" 22 const char *g_pOpcodes[64] = {
25 "j ",
"jal ",
"beq ",
"bne ",
"blez ",
"bgtz ",
27 "addiu ",
"slti ",
"sltiu ",
"andi ",
"ori ",
"xori ",
"lui ",
29 "cop1 ",
"cop2 ",
"cop3 ",
"beql ",
"bnel ",
"blezl ",
"bgtzl ",
33 "lh ",
"lwl ",
"lw ",
"lbu ",
"lhu ",
"lwr ", 0,
35 "sh ",
"swl ",
"sw ", 0, 0,
"swr ",
"cache ",
37 "lwc1 ",
"lwc2 ",
"lwc3 ", 0,
"ldc1 ",
"ldc2 ",
"ldc3 ",
39 "swc1 ",
"swc2 ",
"swc3 ", 0,
"sdc1 ",
"sdc2 ",
"sdc3 "};
41 const char *g_pSpecial[64] = {
42 "sll ", 0,
"srl ",
"sra ",
"sllv ", 0,
"srlv ",
45 "jalr ", 0, 0,
"syscall",
"break ", 0,
"sync ",
47 "mthi ",
"mflo ",
"mtlo ", 0, 0, 0, 0,
49 "multu ",
"div ",
"divu ", 0, 0, 0, 0,
51 "addu ",
"sub ",
"subu ",
"and ",
"or ",
"xor ",
"nor ",
53 0,
"slt ",
"sltu ", 0, 0, 0, 0,
55 "tgeu ",
"tlt ",
"tltu ",
"teq ", 0,
"tne ", 0,
59 const char *g_pRegimm[32] = {
60 "bltz ",
"bgez ",
"bltzl ",
"bgezl ", 0, 0, 0, 0,
62 "tgeiu ",
"tlti ",
"tltiu ",
"teqi ", 0,
"tnei ", 0,
64 "bgezal",
"bltzall",
"bgezall", 0, 0, 0, 0,
68 const char *g_pCopzRs[32] = {
"mfc", 0,
"cfc", 0,
"mtc", 0,
"ctc", 0,
72 "co",
"co",
"co",
"co",
"co",
"co",
"co",
74 "co",
"co",
"co",
"co",
"co",
"co",
"co"};
76 const char *g_pCopzRt[32] = {
"f",
"t",
"fl",
"tl", 0, 0, 0, 0,
84 const char *g_pCp0Function[64] = {0,
"tlbr",
"tlbwi", 0, 0, 0,
"tlbwr", 0,
100 const char *g_pRegisters[32] = {
101 "zero",
"at",
"v0",
"v1",
"a0",
"a1",
"a2",
"a3",
"t0",
"t1",
"t2",
102 "t3",
"t4",
"t5",
"t6",
"t7",
"s0",
"s1",
"s2",
"s3",
"s4",
"s5",
103 "s6",
"s7",
"t8",
"t9",
"k0",
"k1",
"gp",
"sp",
"fp",
"ra"};
105 MipsDisassembler::MipsDisassembler() : m_nLocation(0)
109 MipsDisassembler::~MipsDisassembler()
129 uint32_t nInstruction = *
reinterpret_cast<uint32_t *
>(
m_nLocation);
133 if (nInstruction == 0)
140 int nOpcode = (nInstruction >> 26) & 0x3F;
145 disassembleSpecial(nInstruction, text);
147 else if (nOpcode == 1)
149 disassembleRegImm(nInstruction, text);
153 disassembleOpcode(nInstruction, text);
157 void MipsDisassembler::disassembleSpecial(
161 uint32_t nRs = (nInstruction >> 21) & 0x1F;
162 uint32_t nRt = (nInstruction >> 16) & 0x1F;
163 uint32_t nRd = (nInstruction >> 11) & 0x1F;
164 uint32_t nShamt = (nInstruction >> 6) & 0x1F;
165 uint32_t nFunct = nInstruction & 0x3F;
167 if (g_pSpecial[nFunct] == 0)
175 text += g_pSpecial[nFunct];
177 text += g_pRegisters[nRd];
179 text += g_pRegisters[nRt];
186 text += g_pSpecial[nFunct];
188 text += g_pRegisters[nRd];
190 text += g_pRegisters[nRt];
192 text += g_pRegisters[nRs];
196 text += g_pRegisters[nRs];
203 text += g_pRegisters[nRd];
206 text += g_pRegisters[nRs];
212 text += g_pSpecial[nFunct];
216 text += g_pSpecial[nFunct];
218 text += g_pRegisters[nRd];
222 text += g_pSpecial[nFunct];
224 text += g_pRegisters[nRs];
236 text += g_pSpecial[nFunct];
238 text += g_pRegisters[nRs];
240 text += g_pRegisters[nRt];
247 text += g_pRegisters[nRd];
249 text += g_pRegisters[nRs];
255 text += g_pSpecial[nFunct];
257 text += g_pRegisters[nRd];
259 text += g_pRegisters[nRs];
261 text += g_pRegisters[nRt];
266 void MipsDisassembler::disassembleRegImm(
269 uint32_t nRs = (nInstruction >> 21) & 0x1F;
270 uint32_t nOp = (nInstruction >> 16) & 0x1F;
271 uint16_t nImmediate = nInstruction & 0xFFFF;
272 uint32_t nTarget = (nImmediate << 2) +
m_nLocation;
282 text += g_pRegimm[nOp];
284 text += g_pRegisters[nRs];
286 text.append(static_cast<int16_t>(nImmediate), 10);
289 text += g_pRegimm[nOp];
291 text += g_pRegisters[nRs];
293 text.append(nTarget, 16);
297 void MipsDisassembler::disassembleOpcode(
304 ((nInstruction & 0x03FFFFFF) << 2) | (
m_nLocation & 0xF0000000);
305 uint16_t nImmediate = nInstruction & 0x0000FFFF;
306 uint32_t nRt = (nInstruction >> 16) & 0x1F;
307 uint32_t nRs = (nInstruction >> 21) & 0x1F;
308 int nOpcode = (nInstruction >> 26) & 0x3F;
314 text += g_pOpcodes[nOpcode];
316 text.append(nTarget, 16);
322 text += g_pOpcodes[nOpcode];
324 text += g_pRegisters[nRs];
327 (static_cast<uint32_t>(nImmediate) << 2) +
m_nLocation, 16);
333 text += g_pOpcodes[nOpcode];
335 text += g_pRegisters[nRs];
337 text += g_pRegisters[nRt];
340 (static_cast<uint32_t>(nImmediate) << 2) +
m_nLocation, 16);
349 text += g_pOpcodes[nOpcode];
351 text += g_pRegisters[nRt];
353 text += g_pRegisters[nRs];
355 text.append(static_cast<short>(nImmediate), 10);
359 text += g_pRegisters[nRt];
361 text.append(nImmediate, 16);
370 text += g_pCopzRs[nRs];
371 text.append(static_cast<unsigned char>(nOpcode & 0x3));
372 text += g_pCopzRt[nRt];
376 else if (nOpcode == 020 && nRs >= 16 )
378 text += g_pCp0Function[nInstruction & 0x1F];
382 text += g_pCopzRs[nRs];
383 text.append(static_cast<unsigned char>(nOpcode & 0x3));
385 text += g_pRegisters[nRt];
387 text.append(((nInstruction >> 11) & 0x1F), 10);
392 text += g_pOpcodes[nOpcode];
394 text += g_pRegisters[nRt];
396 text.append(static_cast<short>(nImmediate), 10);
398 text += g_pRegisters[nRs];
void disassemble(LargeStaticString &text)
void setMode(size_t nMode)
void setLocation(uintptr_t nLocation)