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",
"srav",
44 "jalr", 0, 0,
"syscall",
"break", 0,
"sync",
46 "mthi",
"mflo",
"mtlo", 0, 0, 0, 0,
48 "multu",
"div",
"divu", 0, 0, 0, 0,
50 "addu",
"sub",
"subu",
"and",
"or",
"xor",
"nor",
52 0,
"slt",
"sltu", 0, 0, 0, 0,
54 "tgeu",
"tlt",
"tltu",
"teq", 0,
"tne", 0,
58 const char *g_pRegimm[32] = {
59 "bltz",
"bgez",
"bltzl",
"bgezl", 0, 0, 0, 0,
61 "tgeiu",
"tlti",
"tltiu",
"teqi", 0,
"tnei", 0,
63 "bgezal",
"bltzall",
"bgezall", 0, 0, 0, 0,
67 const char *g_pCopzRs[32] = {
"mfc", 0,
"cfc", 0,
"mtc", 0,
"ctc", 0,
71 "co",
"co",
"co",
"co",
"co",
"co",
"co",
73 "co",
"co",
"co",
"co",
"co",
"co",
"co"};
75 const char *g_pCopzRt[32] = {
"f",
"t",
"fl",
"tl", 0, 0, 0, 0,
83 const char *g_pCp0Function[64] = {0,
"tlbr",
"tlbwi", 0, 0, 0,
"tlbwr", 0,
99 const char *g_pRegisters[32] = {
100 "zero",
"at",
"v0",
"v1",
"a0",
"a1",
"a2",
"a3",
"t0",
"t1",
"t2",
101 "t3",
"t4",
"t5",
"t6",
"t7",
"s0",
"s1",
"s2",
"s3",
"s4",
"s5",
102 "s6",
"s7",
"t8",
"t9",
"k0",
"k1",
"gp",
"sp",
"fp",
"ra"};
104 Arm926EDisassembler::Arm926EDisassembler() : m_nLocation(0)
108 Arm926EDisassembler::~Arm926EDisassembler()
114 m_nLocation = nLocation;
128 uint32_t nInstruction = *
reinterpret_cast<uint32_t *
>(m_nLocation);
132 if (nInstruction == 0)
139 int nOpcode = (nInstruction >> 26) & 0x3F;
144 disassembleSpecial(nInstruction, text);
146 else if (nOpcode == 1)
148 disassembleRegImm(nInstruction, text);
152 disassembleOpcode(nInstruction, text);
156 void Arm926EDisassembler::disassembleSpecial(
160 uint32_t nRs = (nInstruction >> 21) & 0x1F;
161 uint32_t nRt = (nInstruction >> 16) & 0x1F;
162 uint32_t nRd = (nInstruction >> 11) & 0x1F;
163 uint32_t nShamt = (nInstruction >> 6) & 0x1F;
164 uint32_t nFunct = nInstruction & 0x3F;
166 if (g_pSpecial[nFunct] == 0)
174 text += g_pSpecial[nFunct];
176 text += g_pRegisters[nRd];
178 text += g_pRegisters[nRt];
185 text += g_pSpecial[nFunct];
187 text += g_pRegisters[nRd];
189 text += g_pRegisters[nRt];
191 text += g_pRegisters[nRs];
195 text += g_pRegisters[nRs];
202 text += g_pRegisters[nRd];
205 text += g_pRegisters[nRs];
211 text += g_pSpecial[nFunct];
215 text += g_pSpecial[nFunct];
217 text += g_pRegisters[nRd];
221 text += g_pSpecial[nFunct];
223 text += g_pRegisters[nRs];
235 text += g_pSpecial[nFunct];
237 text += g_pRegisters[nRs];
239 text += g_pRegisters[nRt];
246 text += g_pRegisters[nRd];
248 text += g_pRegisters[nRs];
254 text += g_pSpecial[nFunct];
256 text += g_pRegisters[nRd];
258 text += g_pRegisters[nRs];
260 text += g_pRegisters[nRt];
265 void Arm926EDisassembler::disassembleRegImm(
268 uint32_t nRs = (nInstruction >> 21) & 0x1F;
269 uint32_t nOp = (nInstruction >> 16) & 0x1F;
270 uint16_t nImmediate = nInstruction & 0xFFFF;
271 uint32_t nTarget = (nImmediate << 2) + m_nLocation;
281 text += g_pRegimm[nOp];
283 text += g_pRegisters[nRs];
285 text.append(static_cast<int16_t>(nImmediate), 10);
288 text += g_pRegimm[nOp];
290 text += g_pRegisters[nRs];
292 text.append(nTarget, 16);
296 void Arm926EDisassembler::disassembleOpcode(
303 ((nInstruction & 0x03FFFFFF) << 2) | (m_nLocation & 0xF0000000);
304 uint16_t nImmediate = nInstruction & 0x0000FFFF;
305 uint32_t nRt = (nInstruction >> 16) & 0x1F;
306 uint32_t nRs = (nInstruction >> 21) & 0x1F;
307 int nOpcode = (nInstruction >> 26) & 0x3F;
313 text += g_pOpcodes[nOpcode];
315 text.append(nTarget, 16);
321 text += g_pOpcodes[nOpcode];
323 text += g_pRegisters[nRs];
326 (static_cast<uint32_t>(nImmediate) << 2) + m_nLocation, 16);
332 text += g_pOpcodes[nOpcode];
334 text += g_pRegisters[nRs];
336 text += g_pRegisters[nRt];
339 (static_cast<uint32_t>(nImmediate) << 2) + m_nLocation, 16);
348 text += g_pOpcodes[nOpcode];
350 text += g_pRegisters[nRt];
352 text += g_pRegisters[nRs];
354 text.append(static_cast<short>(nImmediate), 10);
358 text += g_pRegisters[nRt];
360 text.append(nImmediate, 16);
369 text += g_pCopzRs[nRs];
370 text.append(static_cast<unsigned char>(nOpcode & 0x3));
371 text += g_pCopzRt[nRt];
373 text.append((nImmediate << 2) + m_nLocation, 16);
375 else if (nOpcode == 020 && nRs >= 16 )
377 text += g_pCp0Function[nInstruction & 0x1F];
381 text += g_pCopzRs[nRs];
382 text.append(static_cast<unsigned char>(nOpcode & 0x3));
384 text += g_pRegisters[nRt];
386 text.append(((nInstruction >> 11) & 0x1F), 10);
391 text += g_pOpcodes[nOpcode];
393 text += g_pRegisters[nRt];
395 text.append(static_cast<short>(nImmediate), 10);
397 text += g_pRegisters[nRs];
void setMode(size_t nMode)
void setLocation(uintptr_t nLocation)
void disassemble(LargeStaticString &text)