diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra_qt/debugger/callstack.cpp | 2 | ||||
| -rw-r--r-- | src/citra_qt/debugger/disassembler.cpp | 8 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 260 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.h | 63 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 9 |
5 files changed, 147 insertions, 195 deletions
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp index f59f2d8c8..77fb0c9ed 100644 --- a/src/citra_qt/debugger/callstack.cpp +++ b/src/citra_qt/debugger/callstack.cpp | |||
| @@ -37,7 +37,7 @@ void CallstackWidget::OnCPUStepped() | |||
| 37 | 37 | ||
| 38 | /* TODO (mattvail) clean me, move to debugger interface */ | 38 | /* TODO (mattvail) clean me, move to debugger interface */ |
| 39 | u32 insn = Memory::Read32(call_addr); | 39 | u32 insn = Memory::Read32(call_addr); |
| 40 | if (disasm->decode(insn) == OP_BL) | 40 | if (disasm->Decode(insn) == OP_BL) |
| 41 | { | 41 | { |
| 42 | std::string name; | 42 | std::string name; |
| 43 | // ripped from disasm | 43 | // ripped from disasm |
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp index 507a35718..856baf63d 100644 --- a/src/citra_qt/debugger/disassembler.cpp +++ b/src/citra_qt/debugger/disassembler.cpp | |||
| @@ -36,22 +36,20 @@ QVariant DisassemblerModel::data(const QModelIndex& index, int role) const { | |||
| 36 | switch (role) { | 36 | switch (role) { |
| 37 | case Qt::DisplayRole: | 37 | case Qt::DisplayRole: |
| 38 | { | 38 | { |
| 39 | static char result[255]; | ||
| 40 | |||
| 41 | u32 address = base_address + index.row() * 4; | 39 | u32 address = base_address + index.row() * 4; |
| 42 | u32 instr = Memory::Read32(address); | 40 | u32 instr = Memory::Read32(address); |
| 43 | ARM_Disasm::disasm(address, instr, result); | 41 | std::string disassembly = ARM_Disasm::Disassemble(address, instr); |
| 44 | 42 | ||
| 45 | if (index.column() == 0) { | 43 | if (index.column() == 0) { |
| 46 | return QString("0x%1").arg((uint)(address), 8, 16, QLatin1Char('0')); | 44 | return QString("0x%1").arg((uint)(address), 8, 16, QLatin1Char('0')); |
| 47 | } else if (index.column() == 1) { | 45 | } else if (index.column() == 1) { |
| 48 | return QString::fromLatin1(result); | 46 | return QString::fromStdString(disassembly); |
| 49 | } else if (index.column() == 2) { | 47 | } else if (index.column() == 2) { |
| 50 | if(Symbols::HasSymbol(address)) { | 48 | if(Symbols::HasSymbol(address)) { |
| 51 | TSymbol symbol = Symbols::GetSymbol(address); | 49 | TSymbol symbol = Symbols::GetSymbol(address); |
| 52 | return QString("%1 - Size:%2").arg(QString::fromStdString(symbol.name)) | 50 | return QString("%1 - Size:%2").arg(QString::fromStdString(symbol.name)) |
| 53 | .arg(symbol.size / 4); // divide by 4 to get instruction count | 51 | .arg(symbol.size / 4); // divide by 4 to get instruction count |
| 54 | } else if (ARM_Disasm::decode(instr) == OP_BL) { | 52 | } else if (ARM_Disasm::Decode(instr) == OP_BL) { |
| 55 | u32 offset = instr & 0xFFFFFF; | 53 | u32 offset = instr & 0xFFFFFF; |
| 56 | 54 | ||
| 57 | // Sign-extend the 24-bit offset | 55 | // Sign-extend the 24-bit offset |
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index db1567498..33e036cbf 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | // Copyright 2006 The Android Open Source Project | 1 | // Copyright 2006 The Android Open Source Project |
| 2 | 2 | ||
| 3 | #include <stdio.h> | 3 | #include <string> |
| 4 | #include <string.h> | ||
| 5 | 4 | ||
| 5 | #include "common/string_util.h" | ||
| 6 | #include "core/arm/disassembler/arm_disasm.h" | 6 | #include "core/arm/disassembler/arm_disasm.h" |
| 7 | 7 | ||
| 8 | static const char *cond_names[] = { | 8 | static const char *cond_names[] = { |
| @@ -135,20 +135,14 @@ static const char* cond_to_str(int cond) { | |||
| 135 | return cond_names[cond]; | 135 | return cond_names[cond]; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | char *ARM_Disasm::disasm(uint32_t addr, uint32_t insn, char *result) | 138 | std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) |
| 139 | { | 139 | { |
| 140 | static char buf[80]; | 140 | Opcode opcode = Decode(insn); |
| 141 | char *ptr; | ||
| 142 | |||
| 143 | ptr = result ? result : buf; | ||
| 144 | Opcode opcode = decode(insn); | ||
| 145 | switch (opcode) { | 141 | switch (opcode) { |
| 146 | case OP_INVALID: | 142 | case OP_INVALID: |
| 147 | sprintf(ptr, "Invalid"); | 143 | return "Invalid"; |
| 148 | return ptr; | ||
| 149 | case OP_UNDEFINED: | 144 | case OP_UNDEFINED: |
| 150 | sprintf(ptr, "Undefined"); | 145 | return "Undefined"; |
| 151 | return ptr; | ||
| 152 | case OP_ADC: | 146 | case OP_ADC: |
| 153 | case OP_ADD: | 147 | case OP_ADD: |
| 154 | case OP_AND: | 148 | case OP_AND: |
| @@ -165,28 +159,26 @@ char *ARM_Disasm::disasm(uint32_t addr, uint32_t insn, char *result) | |||
| 165 | case OP_SUB: | 159 | case OP_SUB: |
| 166 | case OP_TEQ: | 160 | case OP_TEQ: |
| 167 | case OP_TST: | 161 | case OP_TST: |
| 168 | return disasm_alu(opcode, insn, ptr); | 162 | return DisassembleALU(opcode, insn); |
| 169 | case OP_B: | 163 | case OP_B: |
| 170 | case OP_BL: | 164 | case OP_BL: |
| 171 | return disasm_branch(addr, opcode, insn, ptr); | 165 | return DisassembleBranch(addr, opcode, insn); |
| 172 | case OP_BKPT: | 166 | case OP_BKPT: |
| 173 | return disasm_bkpt(insn, ptr); | 167 | return DisassembleBKPT(insn); |
| 174 | case OP_BLX: | 168 | case OP_BLX: |
| 175 | // not supported yet | 169 | // not supported yet |
| 176 | break; | 170 | break; |
| 177 | case OP_BX: | 171 | case OP_BX: |
| 178 | return disasm_bx(insn, ptr); | 172 | return DisassembleBX(insn); |
| 179 | case OP_CDP: | 173 | case OP_CDP: |
| 180 | sprintf(ptr, "cdp"); | 174 | return "cdp"; |
| 181 | return ptr; | ||
| 182 | case OP_CLZ: | 175 | case OP_CLZ: |
| 183 | return disasm_clz(insn, ptr); | 176 | return DisassembleCLZ(insn); |
| 184 | case OP_LDC: | 177 | case OP_LDC: |
| 185 | sprintf(ptr, "ldc"); | 178 | return "ldc"; |
| 186 | return ptr; | ||
| 187 | case OP_LDM: | 179 | case OP_LDM: |
| 188 | case OP_STM: | 180 | case OP_STM: |
| 189 | return disasm_memblock(opcode, insn, ptr); | 181 | return DisassembleMemblock(opcode, insn); |
| 190 | case OP_LDR: | 182 | case OP_LDR: |
| 191 | case OP_LDRB: | 183 | case OP_LDRB: |
| 192 | case OP_LDRBT: | 184 | case OP_LDRBT: |
| @@ -195,53 +187,52 @@ char *ARM_Disasm::disasm(uint32_t addr, uint32_t insn, char *result) | |||
| 195 | case OP_STRB: | 187 | case OP_STRB: |
| 196 | case OP_STRBT: | 188 | case OP_STRBT: |
| 197 | case OP_STRT: | 189 | case OP_STRT: |
| 198 | return disasm_mem(insn, ptr); | 190 | return DisassembleMem(insn); |
| 199 | case OP_LDRH: | 191 | case OP_LDRH: |
| 200 | case OP_LDRSB: | 192 | case OP_LDRSB: |
| 201 | case OP_LDRSH: | 193 | case OP_LDRSH: |
| 202 | case OP_STRH: | 194 | case OP_STRH: |
| 203 | return disasm_memhalf(insn, ptr); | 195 | return DisassembleMemHalf(insn); |
| 204 | case OP_MCR: | 196 | case OP_MCR: |
| 205 | case OP_MRC: | 197 | case OP_MRC: |
| 206 | return disasm_mcr(opcode, insn, ptr); | 198 | return DisassembleMCR(opcode, insn); |
| 207 | case OP_MLA: | 199 | case OP_MLA: |
| 208 | return disasm_mla(opcode, insn, ptr); | 200 | return DisassembleMLA(opcode, insn); |
| 209 | case OP_MRS: | 201 | case OP_MRS: |
| 210 | return disasm_mrs(insn, ptr); | 202 | return DisassembleMRS(insn); |
| 211 | case OP_MSR: | 203 | case OP_MSR: |
| 212 | return disasm_msr(insn, ptr); | 204 | return DisassembleMSR(insn); |
| 213 | case OP_MUL: | 205 | case OP_MUL: |
| 214 | return disasm_mul(opcode, insn, ptr); | 206 | return DisassembleMUL(opcode, insn); |
| 215 | case OP_PLD: | 207 | case OP_PLD: |
| 216 | return disasm_pld(insn, ptr); | 208 | return DisassemblePLD(insn); |
| 217 | case OP_STC: | 209 | case OP_STC: |
| 218 | sprintf(ptr, "stc"); | 210 | return "stc"; |
| 219 | return ptr; | ||
| 220 | case OP_SWI: | 211 | case OP_SWI: |
| 221 | return disasm_swi(insn, ptr); | 212 | return DisassembleSWI(insn); |
| 222 | case OP_SWP: | 213 | case OP_SWP: |
| 223 | case OP_SWPB: | 214 | case OP_SWPB: |
| 224 | return disasm_swp(opcode, insn, ptr); | 215 | return DisassembleSWP(opcode, insn); |
| 225 | case OP_UMLAL: | 216 | case OP_UMLAL: |
| 226 | case OP_UMULL: | 217 | case OP_UMULL: |
| 227 | case OP_SMLAL: | 218 | case OP_SMLAL: |
| 228 | case OP_SMULL: | 219 | case OP_SMULL: |
| 229 | return disasm_umlal(opcode, insn, ptr); | 220 | return DisassembleUMLAL(opcode, insn); |
| 230 | default: | 221 | default: |
| 231 | sprintf(ptr, "Error"); | 222 | return "Error"; |
| 232 | return ptr; | ||
| 233 | } | 223 | } |
| 234 | return NULL; | 224 | return NULL; |
| 235 | } | 225 | } |
| 236 | 226 | ||
| 237 | char *ARM_Disasm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr) | 227 | std::string ARM_Disasm::DisassembleALU(Opcode opcode, uint32_t insn) |
| 238 | { | 228 | { |
| 239 | static const uint8_t kNoOperand1 = 1; | 229 | static const uint8_t kNoOperand1 = 1; |
| 240 | static const uint8_t kNoDest = 2; | 230 | static const uint8_t kNoDest = 2; |
| 241 | static const uint8_t kNoSbit = 4; | 231 | static const uint8_t kNoSbit = 4; |
| 242 | 232 | ||
| 243 | char rn_str[20]; | 233 | std::string rn_str; |
| 244 | char rd_str[20]; | 234 | std::string rd_str; |
| 235 | |||
| 245 | uint8_t flags = 0; | 236 | uint8_t flags = 0; |
| 246 | uint8_t cond = (insn >> 28) & 0xf; | 237 | uint8_t cond = (insn >> 28) & 0xf; |
| 247 | uint8_t is_immed = (insn >> 25) & 0x1; | 238 | uint8_t is_immed = (insn >> 25) & 0x1; |
| @@ -250,7 +241,7 @@ char *ARM_Disasm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr) | |||
| 250 | uint8_t rd = (insn >> 12) & 0xf; | 241 | uint8_t rd = (insn >> 12) & 0xf; |
| 251 | uint8_t immed = insn & 0xff; | 242 | uint8_t immed = insn & 0xff; |
| 252 | 243 | ||
| 253 | const char *opname = opcode_names[opcode]; | 244 | const char* opname = opcode_names[opcode]; |
| 254 | switch (opcode) { | 245 | switch (opcode) { |
| 255 | case OP_CMN: | 246 | case OP_CMN: |
| 256 | case OP_CMP: | 247 | case OP_CMP: |
| @@ -269,14 +260,14 @@ char *ARM_Disasm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr) | |||
| 269 | // The "mov" instruction ignores the first operand (rn). | 260 | // The "mov" instruction ignores the first operand (rn). |
| 270 | rn_str[0] = 0; | 261 | rn_str[0] = 0; |
| 271 | if ((flags & kNoOperand1) == 0) { | 262 | if ((flags & kNoOperand1) == 0) { |
| 272 | sprintf(rn_str, "r%d, ", rn); | 263 | rn_str = StringFromFormat("r%d, ", rn); |
| 273 | } | 264 | } |
| 274 | 265 | ||
| 275 | // The following instructions do not write the result register (rd): | 266 | // The following instructions do not write the result register (rd): |
| 276 | // tst, teq, cmp, cmn. | 267 | // tst, teq, cmp, cmn. |
| 277 | rd_str[0] = 0; | 268 | rd_str[0] = 0; |
| 278 | if ((flags & kNoDest) == 0) { | 269 | if ((flags & kNoDest) == 0) { |
| 279 | sprintf(rd_str, "r%d, ", rd); | 270 | rd_str = StringFromFormat("r%d, ", rd); |
| 280 | } | 271 | } |
| 281 | 272 | ||
| 282 | const char *sbit_str = ""; | 273 | const char *sbit_str = ""; |
| @@ -284,9 +275,8 @@ char *ARM_Disasm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr) | |||
| 284 | sbit_str = "s"; | 275 | sbit_str = "s"; |
| 285 | 276 | ||
| 286 | if (is_immed) { | 277 | if (is_immed) { |
| 287 | sprintf(ptr, "%s%s%s\t%s%s#%u ; 0x%x", | 278 | return StringFromFormat("%s%s%s\t%s%s#%u ; 0x%x", |
| 288 | opname, cond_to_str(cond), sbit_str, rd_str, rn_str, immed, immed); | 279 | opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), immed, immed); |
| 289 | return ptr; | ||
| 290 | } | 280 | } |
| 291 | 281 | ||
| 292 | uint8_t shift_is_reg = (insn >> 4) & 1; | 282 | uint8_t shift_is_reg = (insn >> 4) & 1; |
| @@ -300,33 +290,29 @@ char *ARM_Disasm::disasm_alu(Opcode opcode, uint32_t insn, char *ptr) | |||
| 300 | rotated_val = (rotated_val >> rotate2) | (rotated_val << (32 - rotate2)); | 290 | rotated_val = (rotated_val >> rotate2) | (rotated_val << (32 - rotate2)); |
| 301 | 291 | ||
| 302 | if (!shift_is_reg && shift_type == 0 && shift_amount == 0) { | 292 | if (!shift_is_reg && shift_type == 0 && shift_amount == 0) { |
| 303 | sprintf(ptr, "%s%s%s\t%s%sr%d", | 293 | return StringFromFormat("%s%s%s\t%s%sr%d", |
| 304 | opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm); | 294 | opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); |
| 305 | return ptr; | ||
| 306 | } | 295 | } |
| 307 | 296 | ||
| 308 | const char *shift_name = shift_names[shift_type]; | 297 | const char *shift_name = shift_names[shift_type]; |
| 309 | if (shift_is_reg) { | 298 | if (shift_is_reg) { |
| 310 | sprintf(ptr, "%s%s%s\t%s%sr%d, %s r%d", | 299 | return StringFromFormat("%s%s%s\t%s%sr%d, %s r%d", |
| 311 | opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm, | 300 | opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, |
| 312 | shift_name, rs); | 301 | shift_name, rs); |
| 313 | return ptr; | ||
| 314 | } | 302 | } |
| 315 | if (shift_amount == 0) { | 303 | if (shift_amount == 0) { |
| 316 | if (shift_type == 3) { | 304 | if (shift_type == 3) { |
| 317 | sprintf(ptr, "%s%s%s\t%s%sr%d, RRX", | 305 | return StringFromFormat("%s%s%s\t%s%sr%d, RRX", |
| 318 | opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm); | 306 | opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); |
| 319 | return ptr; | ||
| 320 | } | 307 | } |
| 321 | shift_amount = 32; | 308 | shift_amount = 32; |
| 322 | } | 309 | } |
| 323 | sprintf(ptr, "%s%s%s\t%s%sr%d, %s #%u", | 310 | return StringFromFormat("%s%s%s\t%s%sr%d, %s #%u", |
| 324 | opname, cond_to_str(cond), sbit_str, rd_str, rn_str, rm, | 311 | opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, |
| 325 | shift_name, shift_amount); | 312 | shift_name, shift_amount); |
| 326 | return ptr; | ||
| 327 | } | 313 | } |
| 328 | 314 | ||
| 329 | char *ARM_Disasm::disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr) | 315 | std::string ARM_Disasm::DisassembleBranch(uint32_t addr, Opcode opcode, uint32_t insn) |
| 330 | { | 316 | { |
| 331 | uint8_t cond = (insn >> 28) & 0xf; | 317 | uint8_t cond = (insn >> 28) & 0xf; |
| 332 | uint32_t offset = insn & 0xffffff; | 318 | uint32_t offset = insn & 0xffffff; |
| @@ -339,37 +325,34 @@ char *ARM_Disasm::disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, cha | |||
| 339 | offset += 8; | 325 | offset += 8; |
| 340 | addr += offset; | 326 | addr += offset; |
| 341 | const char *opname = opcode_names[opcode]; | 327 | const char *opname = opcode_names[opcode]; |
| 342 | sprintf(ptr, "%s%s\t0x%x", opname, cond_to_str(cond), addr); | 328 | return StringFromFormat("%s%s\t0x%x", opname, cond_to_str(cond), addr); |
| 343 | return ptr; | ||
| 344 | } | 329 | } |
| 345 | 330 | ||
| 346 | char *ARM_Disasm::disasm_bx(uint32_t insn, char *ptr) | 331 | std::string ARM_Disasm::DisassembleBX(uint32_t insn) |
| 347 | { | 332 | { |
| 348 | uint8_t cond = (insn >> 28) & 0xf; | 333 | uint8_t cond = (insn >> 28) & 0xf; |
| 349 | uint8_t rn = insn & 0xf; | 334 | uint8_t rn = insn & 0xf; |
| 350 | sprintf(ptr, "bx%s\tr%d", cond_to_str(cond), rn); | 335 | return StringFromFormat("bx%s\tr%d", cond_to_str(cond), rn); |
| 351 | return ptr; | ||
| 352 | } | 336 | } |
| 353 | 337 | ||
| 354 | char *ARM_Disasm::disasm_bkpt(uint32_t insn, char *ptr) | 338 | std::string ARM_Disasm::DisassembleBKPT(uint32_t insn) |
| 355 | { | 339 | { |
| 356 | uint32_t immed = (((insn >> 8) & 0xfff) << 4) | (insn & 0xf); | 340 | uint32_t immed = (((insn >> 8) & 0xfff) << 4) | (insn & 0xf); |
| 357 | sprintf(ptr, "bkpt\t#%d", immed); | 341 | return StringFromFormat("bkpt\t#%d", immed); |
| 358 | return ptr; | ||
| 359 | } | 342 | } |
| 360 | 343 | ||
| 361 | char *ARM_Disasm::disasm_clz(uint32_t insn, char *ptr) | 344 | std::string ARM_Disasm::DisassembleCLZ(uint32_t insn) |
| 362 | { | 345 | { |
| 363 | uint8_t cond = (insn >> 28) & 0xf; | 346 | uint8_t cond = (insn >> 28) & 0xf; |
| 364 | uint8_t rd = (insn >> 12) & 0xf; | 347 | uint8_t rd = (insn >> 12) & 0xf; |
| 365 | uint8_t rm = insn & 0xf; | 348 | uint8_t rm = insn & 0xf; |
| 366 | sprintf(ptr, "clz%s\tr%d, r%d", cond_to_str(cond), rd, rm); | 349 | return StringFromFormat("clz%s\tr%d, r%d", cond_to_str(cond), rd, rm); |
| 367 | return ptr; | ||
| 368 | } | 350 | } |
| 369 | 351 | ||
| 370 | char *ARM_Disasm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr) | 352 | std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, uint32_t insn) |
| 371 | { | 353 | { |
| 372 | char tmp_reg[10], tmp_list[80]; | 354 | std::string tmp_reg; |
| 355 | std::string tmp_list; | ||
| 373 | 356 | ||
| 374 | uint8_t cond = (insn >> 28) & 0xf; | 357 | uint8_t cond = (insn >> 28) & 0xf; |
| 375 | uint8_t write_back = (insn >> 21) & 0x1; | 358 | uint8_t write_back = (insn >> 21) & 0x1; |
| @@ -393,8 +376,7 @@ char *ARM_Disasm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr) | |||
| 393 | tmp_list[0] = 0; | 376 | tmp_list[0] = 0; |
| 394 | for (int ii = 0; ii < 16; ++ii) { | 377 | for (int ii = 0; ii < 16; ++ii) { |
| 395 | if (reg_list & (1 << ii)) { | 378 | if (reg_list & (1 << ii)) { |
| 396 | sprintf(tmp_reg, "%sr%d", comma, ii); | 379 | tmp_list += StringFromFormat("%sr%d", comma, ii); |
| 397 | strcat(tmp_list, tmp_reg); | ||
| 398 | comma = ","; | 380 | comma = ","; |
| 399 | } | 381 | } |
| 400 | } | 382 | } |
| @@ -414,12 +396,11 @@ char *ARM_Disasm::disasm_memblock(Opcode opcode, uint32_t insn, char *ptr) | |||
| 414 | } | 396 | } |
| 415 | } | 397 | } |
| 416 | 398 | ||
| 417 | sprintf(ptr, "%s%s%s\tr%d%s, {%s}%s", | 399 | return StringFromFormat("%s%s%s\tr%d%s, {%s}%s", |
| 418 | opname, cond_to_str(cond), addr_mode, rn, bang, tmp_list, carret); | 400 | opname, cond_to_str(cond), addr_mode, rn, bang, tmp_list.c_str(), carret); |
| 419 | return ptr; | ||
| 420 | } | 401 | } |
| 421 | 402 | ||
| 422 | char *ARM_Disasm::disasm_mem(uint32_t insn, char *ptr) | 403 | std::string ARM_Disasm::DisassembleMem(uint32_t insn) |
| 423 | { | 404 | { |
| 424 | uint8_t cond = (insn >> 28) & 0xf; | 405 | uint8_t cond = (insn >> 28) & 0xf; |
| 425 | uint8_t is_reg = (insn >> 25) & 0x1; | 406 | uint8_t is_reg = (insn >> 25) & 0x1; |
| @@ -451,20 +432,20 @@ char *ARM_Disasm::disasm_mem(uint32_t insn, char *ptr) | |||
| 451 | if (is_reg == 0) { | 432 | if (is_reg == 0) { |
| 452 | if (is_pre) { | 433 | if (is_pre) { |
| 453 | if (offset == 0) { | 434 | if (offset == 0) { |
| 454 | sprintf(ptr, "%s%s%s\tr%d, [r%d]", | 435 | return StringFromFormat("%s%s%s\tr%d, [r%d]", |
| 455 | opname, cond_to_str(cond), byte, rd, rn); | 436 | opname, cond_to_str(cond), byte, rd, rn); |
| 456 | } else { | 437 | } else { |
| 457 | sprintf(ptr, "%s%s%s\tr%d, [r%d, #%s%u]%s", | 438 | return StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", |
| 458 | opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang); | 439 | opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang); |
| 459 | } | 440 | } |
| 460 | } else { | 441 | } else { |
| 461 | const char *transfer = ""; | 442 | const char *transfer = ""; |
| 462 | if (write_back) | 443 | if (write_back) |
| 463 | transfer = "t"; | 444 | transfer = "t"; |
| 464 | sprintf(ptr, "%s%s%s%s\tr%d, [r%d], #%s%u", | 445 | |
| 446 | return StringFromFormat("%s%s%s%s\tr%d, [r%d], #%s%u", | ||
| 465 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, offset); | 447 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, offset); |
| 466 | } | 448 | } |
| 467 | return ptr; | ||
| 468 | } | 449 | } |
| 469 | 450 | ||
| 470 | uint8_t rm = insn & 0xf; | 451 | uint8_t rm = insn & 0xf; |
| @@ -476,21 +457,18 @@ char *ARM_Disasm::disasm_mem(uint32_t insn, char *ptr) | |||
| 476 | if (is_pre) { | 457 | if (is_pre) { |
| 477 | if (shift_amount == 0) { | 458 | if (shift_amount == 0) { |
| 478 | if (shift_type == 0) { | 459 | if (shift_type == 0) { |
| 479 | sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d]%s", | 460 | return StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", |
| 480 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); | 461 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); |
| 481 | return ptr; | ||
| 482 | } | 462 | } |
| 483 | if (shift_type == 3) { | 463 | if (shift_type == 3) { |
| 484 | sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", | 464 | return StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", |
| 485 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); | 465 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); |
| 486 | return ptr; | ||
| 487 | } | 466 | } |
| 488 | shift_amount = 32; | 467 | shift_amount = 32; |
| 489 | } | 468 | } |
| 490 | sprintf(ptr, "%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", | 469 | return StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", |
| 491 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, | 470 | opname, cond_to_str(cond), byte, rd, rn, minus, rm, |
| 492 | shift_name, shift_amount, bang); | 471 | shift_name, shift_amount, bang); |
| 493 | return ptr; | ||
| 494 | } | 472 | } |
| 495 | 473 | ||
| 496 | const char *transfer = ""; | 474 | const char *transfer = ""; |
| @@ -499,25 +477,22 @@ char *ARM_Disasm::disasm_mem(uint32_t insn, char *ptr) | |||
| 499 | 477 | ||
| 500 | if (shift_amount == 0) { | 478 | if (shift_amount == 0) { |
| 501 | if (shift_type == 0) { | 479 | if (shift_type == 0) { |
| 502 | sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d", | 480 | return StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d", |
| 503 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); | 481 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); |
| 504 | return ptr; | ||
| 505 | } | 482 | } |
| 506 | if (shift_type == 3) { | 483 | if (shift_type == 3) { |
| 507 | sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d, RRX", | 484 | return StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, RRX", |
| 508 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); | 485 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); |
| 509 | return ptr; | ||
| 510 | } | 486 | } |
| 511 | shift_amount = 32; | 487 | shift_amount = 32; |
| 512 | } | 488 | } |
| 513 | 489 | ||
| 514 | sprintf(ptr, "%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", | 490 | return StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", |
| 515 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm, | 491 | opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm, |
| 516 | shift_name, shift_amount); | 492 | shift_name, shift_amount); |
| 517 | return ptr; | ||
| 518 | } | 493 | } |
| 519 | 494 | ||
| 520 | char *ARM_Disasm::disasm_memhalf(uint32_t insn, char *ptr) | 495 | std::string ARM_Disasm::DisassembleMemHalf(uint32_t insn) |
| 521 | { | 496 | { |
| 522 | uint8_t cond = (insn >> 28) & 0xf; | 497 | uint8_t cond = (insn >> 28) & 0xf; |
| 523 | uint8_t is_load = (insn >> 20) & 0x1; | 498 | uint8_t is_load = (insn >> 20) & 0x1; |
| @@ -553,29 +528,27 @@ char *ARM_Disasm::disasm_memhalf(uint32_t insn, char *ptr) | |||
| 553 | if (is_immed) { | 528 | if (is_immed) { |
| 554 | if (is_pre) { | 529 | if (is_pre) { |
| 555 | if (offset == 0) { | 530 | if (offset == 0) { |
| 556 | sprintf(ptr, "%s%sh\tr%d, [r%d]", opname, cond_to_str(cond), rd, rn); | 531 | return StringFromFormat("%s%sh\tr%d, [r%d]", opname, cond_to_str(cond), rd, rn); |
| 557 | } else { | 532 | } else { |
| 558 | sprintf(ptr, "%s%sh\tr%d, [r%d, #%s%u]%s", | 533 | return StringFromFormat("%s%sh\tr%d, [r%d, #%s%u]%s", |
| 559 | opname, cond_to_str(cond), rd, rn, minus, offset, bang); | 534 | opname, cond_to_str(cond), rd, rn, minus, offset, bang); |
| 560 | } | 535 | } |
| 561 | } else { | 536 | } else { |
| 562 | sprintf(ptr, "%s%sh\tr%d, [r%d], #%s%u", | 537 | return StringFromFormat("%s%sh\tr%d, [r%d], #%s%u", |
| 563 | opname, cond_to_str(cond), rd, rn, minus, offset); | 538 | opname, cond_to_str(cond), rd, rn, minus, offset); |
| 564 | } | 539 | } |
| 565 | return ptr; | ||
| 566 | } | 540 | } |
| 567 | 541 | ||
| 568 | if (is_pre) { | 542 | if (is_pre) { |
| 569 | sprintf(ptr, "%s%sh\tr%d, [r%d, %sr%d]%s", | 543 | return StringFromFormat("%s%sh\tr%d, [r%d, %sr%d]%s", |
| 570 | opname, cond_to_str(cond), rd, rn, minus, rm, bang); | 544 | opname, cond_to_str(cond), rd, rn, minus, rm, bang); |
| 571 | } else { | 545 | } else { |
| 572 | sprintf(ptr, "%s%sh\tr%d, [r%d], %sr%d", | 546 | return StringFromFormat("%s%sh\tr%d, [r%d], %sr%d", |
| 573 | opname, cond_to_str(cond), rd, rn, minus, rm); | 547 | opname, cond_to_str(cond), rd, rn, minus, rm); |
| 574 | } | 548 | } |
| 575 | return ptr; | ||
| 576 | } | 549 | } |
| 577 | 550 | ||
| 578 | char *ARM_Disasm::disasm_mcr(Opcode opcode, uint32_t insn, char *ptr) | 551 | std::string ARM_Disasm::DisassembleMCR(Opcode opcode, uint32_t insn) |
| 579 | { | 552 | { |
| 580 | uint8_t cond = (insn >> 28) & 0xf; | 553 | uint8_t cond = (insn >> 28) & 0xf; |
| 581 | uint8_t crn = (insn >> 16) & 0xf; | 554 | uint8_t crn = (insn >> 16) & 0xf; |
| @@ -585,12 +558,11 @@ char *ARM_Disasm::disasm_mcr(Opcode opcode, uint32_t insn, char *ptr) | |||
| 585 | uint8_t crm = insn & 0xf; | 558 | uint8_t crm = insn & 0xf; |
| 586 | 559 | ||
| 587 | const char *opname = opcode_names[opcode]; | 560 | const char *opname = opcode_names[opcode]; |
| 588 | sprintf(ptr, "%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", | 561 | return StringFromFormat("%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", |
| 589 | opname, cond_to_str(cond), cpnum, crd, crn, crm, opcode2); | 562 | opname, cond_to_str(cond), cpnum, crd, crn, crm, opcode2); |
| 590 | return ptr; | ||
| 591 | } | 563 | } |
| 592 | 564 | ||
| 593 | char *ARM_Disasm::disasm_mla(Opcode opcode, uint32_t insn, char *ptr) | 565 | std::string ARM_Disasm::DisassembleMLA(Opcode opcode, uint32_t insn) |
| 594 | { | 566 | { |
| 595 | uint8_t cond = (insn >> 28) & 0xf; | 567 | uint8_t cond = (insn >> 28) & 0xf; |
| 596 | uint8_t rd = (insn >> 16) & 0xf; | 568 | uint8_t rd = (insn >> 16) & 0xf; |
| @@ -600,12 +572,11 @@ char *ARM_Disasm::disasm_mla(Opcode opcode, uint32_t insn, char *ptr) | |||
| 600 | uint8_t bit_s = (insn >> 20) & 1; | 572 | uint8_t bit_s = (insn >> 20) & 1; |
| 601 | 573 | ||
| 602 | const char *opname = opcode_names[opcode]; | 574 | const char *opname = opcode_names[opcode]; |
| 603 | sprintf(ptr, "%s%s%s\tr%d, r%d, r%d, r%d", | 575 | return StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", |
| 604 | opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs, rn); | 576 | opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs, rn); |
| 605 | return ptr; | ||
| 606 | } | 577 | } |
| 607 | 578 | ||
| 608 | char *ARM_Disasm::disasm_umlal(Opcode opcode, uint32_t insn, char *ptr) | 579 | std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, uint32_t insn) |
| 609 | { | 580 | { |
| 610 | uint8_t cond = (insn >> 28) & 0xf; | 581 | uint8_t cond = (insn >> 28) & 0xf; |
| 611 | uint8_t rdhi = (insn >> 16) & 0xf; | 582 | uint8_t rdhi = (insn >> 16) & 0xf; |
| @@ -615,12 +586,11 @@ char *ARM_Disasm::disasm_umlal(Opcode opcode, uint32_t insn, char *ptr) | |||
| 615 | uint8_t bit_s = (insn >> 20) & 1; | 586 | uint8_t bit_s = (insn >> 20) & 1; |
| 616 | 587 | ||
| 617 | const char *opname = opcode_names[opcode]; | 588 | const char *opname = opcode_names[opcode]; |
| 618 | sprintf(ptr, "%s%s%s\tr%d, r%d, r%d, r%d", | 589 | return StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", |
| 619 | opname, cond_to_str(cond), bit_s ? "s" : "", rdlo, rdhi, rm, rs); | 590 | opname, cond_to_str(cond), bit_s ? "s" : "", rdlo, rdhi, rm, rs); |
| 620 | return ptr; | ||
| 621 | } | 591 | } |
| 622 | 592 | ||
| 623 | char *ARM_Disasm::disasm_mul(Opcode opcode, uint32_t insn, char *ptr) | 593 | std::string ARM_Disasm::DisassembleMUL(Opcode opcode, uint32_t insn) |
| 624 | { | 594 | { |
| 625 | uint8_t cond = (insn >> 28) & 0xf; | 595 | uint8_t cond = (insn >> 28) & 0xf; |
| 626 | uint8_t rd = (insn >> 16) & 0xf; | 596 | uint8_t rd = (insn >> 16) & 0xf; |
| @@ -629,22 +599,20 @@ char *ARM_Disasm::disasm_mul(Opcode opcode, uint32_t insn, char *ptr) | |||
| 629 | uint8_t bit_s = (insn >> 20) & 1; | 599 | uint8_t bit_s = (insn >> 20) & 1; |
| 630 | 600 | ||
| 631 | const char *opname = opcode_names[opcode]; | 601 | const char *opname = opcode_names[opcode]; |
| 632 | sprintf(ptr, "%s%s%s\tr%d, r%d, r%d", | 602 | return StringFromFormat("%s%s%s\tr%d, r%d, r%d", |
| 633 | opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs); | 603 | opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs); |
| 634 | return ptr; | ||
| 635 | } | 604 | } |
| 636 | 605 | ||
| 637 | char *ARM_Disasm::disasm_mrs(uint32_t insn, char *ptr) | 606 | std::string ARM_Disasm::DisassembleMRS(uint32_t insn) |
| 638 | { | 607 | { |
| 639 | uint8_t cond = (insn >> 28) & 0xf; | 608 | uint8_t cond = (insn >> 28) & 0xf; |
| 640 | uint8_t rd = (insn >> 12) & 0xf; | 609 | uint8_t rd = (insn >> 12) & 0xf; |
| 641 | uint8_t ps = (insn >> 22) & 1; | 610 | uint8_t ps = (insn >> 22) & 1; |
| 642 | 611 | ||
| 643 | sprintf(ptr, "mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr"); | 612 | return StringFromFormat("mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr"); |
| 644 | return ptr; | ||
| 645 | } | 613 | } |
| 646 | 614 | ||
| 647 | char *ARM_Disasm::disasm_msr(uint32_t insn, char *ptr) | 615 | std::string ARM_Disasm::DisassembleMSR(uint32_t insn) |
| 648 | { | 616 | { |
| 649 | char flags[8]; | 617 | char flags[8]; |
| 650 | int flag_index = 0; | 618 | int flag_index = 0; |
| @@ -668,19 +636,17 @@ char *ARM_Disasm::disasm_msr(uint32_t insn, char *ptr) | |||
| 668 | uint8_t rotate = (insn >> 8) & 0xf; | 636 | uint8_t rotate = (insn >> 8) & 0xf; |
| 669 | uint8_t rotate2 = rotate << 1; | 637 | uint8_t rotate2 = rotate << 1; |
| 670 | uint32_t rotated_val = (immed >> rotate2) | (immed << (32 - rotate2)); | 638 | uint32_t rotated_val = (immed >> rotate2) | (immed << (32 - rotate2)); |
| 671 | sprintf(ptr, "msr%s\t%s_%s, #0x%x", | 639 | return StringFromFormat("msr%s\t%s_%s, #0x%x", |
| 672 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rotated_val); | 640 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rotated_val); |
| 673 | return ptr; | ||
| 674 | } | 641 | } |
| 675 | 642 | ||
| 676 | uint8_t rm = insn & 0xf; | 643 | uint8_t rm = insn & 0xf; |
| 677 | 644 | ||
| 678 | sprintf(ptr, "msr%s\t%s_%s, r%d", | 645 | return StringFromFormat("msr%s\t%s_%s, r%d", |
| 679 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); | 646 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); |
| 680 | return ptr; | ||
| 681 | } | 647 | } |
| 682 | 648 | ||
| 683 | char *ARM_Disasm::disasm_pld(uint32_t insn, char *ptr) | 649 | std::string ARM_Disasm::DisassemblePLD(uint32_t insn) |
| 684 | { | 650 | { |
| 685 | uint8_t is_reg = (insn >> 25) & 0x1; | 651 | uint8_t is_reg = (insn >> 25) & 0x1; |
| 686 | uint8_t is_up = (insn >> 23) & 0x1; | 652 | uint8_t is_up = (insn >> 23) & 0x1; |
| @@ -692,29 +658,26 @@ char *ARM_Disasm::disasm_pld(uint32_t insn, char *ptr) | |||
| 692 | 658 | ||
| 693 | if (is_reg) { | 659 | if (is_reg) { |
| 694 | uint8_t rm = insn & 0xf; | 660 | uint8_t rm = insn & 0xf; |
| 695 | sprintf(ptr, "pld\t[r%d, %sr%d]", rn, minus, rm); | 661 | return StringFromFormat("pld\t[r%d, %sr%d]", rn, minus, rm); |
| 696 | return ptr; | ||
| 697 | } | 662 | } |
| 698 | 663 | ||
| 699 | uint16_t offset = insn & 0xfff; | 664 | uint16_t offset = insn & 0xfff; |
| 700 | if (offset == 0) { | 665 | if (offset == 0) { |
| 701 | sprintf(ptr, "pld\t[r%d]", rn); | 666 | return StringFromFormat("pld\t[r%d]", rn); |
| 702 | } else { | 667 | } else { |
| 703 | sprintf(ptr, "pld\t[r%d, #%s%u]", rn, minus, offset); | 668 | return StringFromFormat("pld\t[r%d, #%s%u]", rn, minus, offset); |
| 704 | } | 669 | } |
| 705 | return ptr; | ||
| 706 | } | 670 | } |
| 707 | 671 | ||
| 708 | char *ARM_Disasm::disasm_swi(uint32_t insn, char *ptr) | 672 | std::string ARM_Disasm::DisassembleSWI(uint32_t insn) |
| 709 | { | 673 | { |
| 710 | uint8_t cond = (insn >> 28) & 0xf; | 674 | uint8_t cond = (insn >> 28) & 0xf; |
| 711 | uint32_t sysnum = insn & 0x00ffffff; | 675 | uint32_t sysnum = insn & 0x00ffffff; |
| 712 | 676 | ||
| 713 | sprintf(ptr, "swi%s 0x%x", cond_to_str(cond), sysnum); | 677 | return StringFromFormat("swi%s 0x%x", cond_to_str(cond), sysnum); |
| 714 | return ptr; | ||
| 715 | } | 678 | } |
| 716 | 679 | ||
| 717 | char *ARM_Disasm::disasm_swp(Opcode opcode, uint32_t insn, char *ptr) | 680 | std::string ARM_Disasm::DisassembleSWP(Opcode opcode, uint32_t insn) |
| 718 | { | 681 | { |
| 719 | uint8_t cond = (insn >> 28) & 0xf; | 682 | uint8_t cond = (insn >> 28) & 0xf; |
| 720 | uint8_t rn = (insn >> 16) & 0xf; | 683 | uint8_t rn = (insn >> 16) & 0xf; |
| @@ -722,26 +685,25 @@ char *ARM_Disasm::disasm_swp(Opcode opcode, uint32_t insn, char *ptr) | |||
| 722 | uint8_t rm = insn & 0xf; | 685 | uint8_t rm = insn & 0xf; |
| 723 | 686 | ||
| 724 | const char *opname = opcode_names[opcode]; | 687 | const char *opname = opcode_names[opcode]; |
| 725 | sprintf(ptr, "%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn); | 688 | return StringFromFormat("%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn); |
| 726 | return ptr; | ||
| 727 | } | 689 | } |
| 728 | 690 | ||
| 729 | Opcode ARM_Disasm::decode(uint32_t insn) { | 691 | Opcode ARM_Disasm::Decode(uint32_t insn) { |
| 730 | uint32_t bits27_26 = (insn >> 26) & 0x3; | 692 | uint32_t bits27_26 = (insn >> 26) & 0x3; |
| 731 | switch (bits27_26) { | 693 | switch (bits27_26) { |
| 732 | case 0x0: | 694 | case 0x0: |
| 733 | return decode00(insn); | 695 | return Decode00(insn); |
| 734 | case 0x1: | 696 | case 0x1: |
| 735 | return decode01(insn); | 697 | return Decode01(insn); |
| 736 | case 0x2: | 698 | case 0x2: |
| 737 | return decode10(insn); | 699 | return Decode10(insn); |
| 738 | case 0x3: | 700 | case 0x3: |
| 739 | return decode11(insn); | 701 | return Decode11(insn); |
| 740 | } | 702 | } |
| 741 | return OP_INVALID; | 703 | return OP_INVALID; |
| 742 | } | 704 | } |
| 743 | 705 | ||
| 744 | Opcode ARM_Disasm::decode00(uint32_t insn) { | 706 | Opcode ARM_Disasm::Decode00(uint32_t insn) { |
| 745 | uint8_t bit25 = (insn >> 25) & 0x1; | 707 | uint8_t bit25 = (insn >> 25) & 0x1; |
| 746 | uint8_t bit4 = (insn >> 4) & 0x1; | 708 | uint8_t bit4 = (insn >> 4) & 0x1; |
| 747 | if (bit25 == 0 && bit4 == 1) { | 709 | if (bit25 == 0 && bit4 == 1) { |
| @@ -767,21 +729,21 @@ Opcode ARM_Disasm::decode00(uint32_t insn) { | |||
| 767 | return OP_SWP; | 729 | return OP_SWP; |
| 768 | } | 730 | } |
| 769 | // One of the multiply instructions | 731 | // One of the multiply instructions |
| 770 | return decode_mul(insn); | 732 | return DecodeMUL(insn); |
| 771 | } | 733 | } |
| 772 | 734 | ||
| 773 | uint8_t bit7 = (insn >> 7) & 0x1; | 735 | uint8_t bit7 = (insn >> 7) & 0x1; |
| 774 | if (bit7 == 1) { | 736 | if (bit7 == 1) { |
| 775 | // One of the load/store halfword/byte instructions | 737 | // One of the load/store halfword/byte instructions |
| 776 | return decode_ldrh(insn); | 738 | return DecodeLDRH(insn); |
| 777 | } | 739 | } |
| 778 | } | 740 | } |
| 779 | 741 | ||
| 780 | // One of the data processing instructions | 742 | // One of the data processing instructions |
| 781 | return decode_alu(insn); | 743 | return DecodeALU(insn); |
| 782 | } | 744 | } |
| 783 | 745 | ||
| 784 | Opcode ARM_Disasm::decode01(uint32_t insn) { | 746 | Opcode ARM_Disasm::Decode01(uint32_t insn) { |
| 785 | uint8_t is_reg = (insn >> 25) & 0x1; | 747 | uint8_t is_reg = (insn >> 25) & 0x1; |
| 786 | uint8_t bit4 = (insn >> 4) & 0x1; | 748 | uint8_t bit4 = (insn >> 4) & 0x1; |
| 787 | if (is_reg == 1 && bit4 == 1) | 749 | if (is_reg == 1 && bit4 == 1) |
| @@ -808,7 +770,7 @@ Opcode ARM_Disasm::decode01(uint32_t insn) { | |||
| 808 | return OP_STR; | 770 | return OP_STR; |
| 809 | } | 771 | } |
| 810 | 772 | ||
| 811 | Opcode ARM_Disasm::decode10(uint32_t insn) { | 773 | Opcode ARM_Disasm::Decode10(uint32_t insn) { |
| 812 | uint8_t bit25 = (insn >> 25) & 0x1; | 774 | uint8_t bit25 = (insn >> 25) & 0x1; |
| 813 | if (bit25 == 0) { | 775 | if (bit25 == 0) { |
| 814 | // LDM/STM | 776 | // LDM/STM |
| @@ -833,7 +795,7 @@ Opcode ARM_Disasm::decode10(uint32_t insn) { | |||
| 833 | return OP_BL; | 795 | return OP_BL; |
| 834 | } | 796 | } |
| 835 | 797 | ||
| 836 | Opcode ARM_Disasm::decode11(uint32_t insn) { | 798 | Opcode ARM_Disasm::Decode11(uint32_t insn) { |
| 837 | uint8_t bit25 = (insn >> 25) & 0x1; | 799 | uint8_t bit25 = (insn >> 25) & 0x1; |
| 838 | if (bit25 == 0) { | 800 | if (bit25 == 0) { |
| 839 | // LDC, SDC | 801 | // LDC, SDC |
| @@ -882,7 +844,7 @@ Opcode ARM_Disasm::decode11(uint32_t insn) { | |||
| 882 | return OP_MCR; | 844 | return OP_MCR; |
| 883 | } | 845 | } |
| 884 | 846 | ||
| 885 | Opcode ARM_Disasm::decode_mul(uint32_t insn) { | 847 | Opcode ARM_Disasm::DecodeMUL(uint32_t insn) { |
| 886 | uint8_t bit24 = (insn >> 24) & 0x1; | 848 | uint8_t bit24 = (insn >> 24) & 0x1; |
| 887 | if (bit24 != 0) { | 849 | if (bit24 != 0) { |
| 888 | // This is an unexpected bit pattern. Create an undefined | 850 | // This is an unexpected bit pattern. Create an undefined |
| @@ -916,7 +878,7 @@ Opcode ARM_Disasm::decode_mul(uint32_t insn) { | |||
| 916 | return OP_SMLAL; | 878 | return OP_SMLAL; |
| 917 | } | 879 | } |
| 918 | 880 | ||
| 919 | Opcode ARM_Disasm::decode_ldrh(uint32_t insn) { | 881 | Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) { |
| 920 | uint8_t is_load = (insn >> 20) & 0x1; | 882 | uint8_t is_load = (insn >> 20) & 0x1; |
| 921 | uint8_t bits_65 = (insn >> 5) & 0x3; | 883 | uint8_t bits_65 = (insn >> 5) & 0x3; |
| 922 | if (is_load) { | 884 | if (is_load) { |
| @@ -946,7 +908,7 @@ Opcode ARM_Disasm::decode_ldrh(uint32_t insn) { | |||
| 946 | return OP_STRH; | 908 | return OP_STRH; |
| 947 | } | 909 | } |
| 948 | 910 | ||
| 949 | Opcode ARM_Disasm::decode_alu(uint32_t insn) { | 911 | Opcode ARM_Disasm::DecodeALU(uint32_t insn) { |
| 950 | uint8_t is_immed = (insn >> 25) & 0x1; | 912 | uint8_t is_immed = (insn >> 25) & 0x1; |
| 951 | uint8_t opcode = (insn >> 21) & 0xf; | 913 | uint8_t opcode = (insn >> 21) & 0xf; |
| 952 | uint8_t bit_s = (insn >> 20) & 1; | 914 | uint8_t bit_s = (insn >> 20) & 1; |
diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index 9600e2ade..f94bd4669 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | // Copyright 2006 The Android Open Source Project | 1 | // Copyright 2006 The Android Open Source Project |
| 2 | 2 | ||
| 3 | #ifndef ARMDIS_H | 3 | #pragma once |
| 4 | #define ARMDIS_H | ||
| 5 | 4 | ||
| 6 | #include <stdint.h> | 5 | #include <cstdint> |
| 6 | #include <string> | ||
| 7 | 7 | ||
| 8 | // Note: this list of opcodes must match the list used to initialize | 8 | // Note: this list of opcodes must match the list used to initialize |
| 9 | // the opflags[] array in opcode.cpp. | 9 | // the opflags[] array in opcode.cpp. |
| @@ -109,38 +109,33 @@ enum Opcode { | |||
| 109 | 109 | ||
| 110 | class ARM_Disasm { | 110 | class ARM_Disasm { |
| 111 | public: | 111 | public: |
| 112 | static char *disasm(uint32_t addr, uint32_t insn, char *buffer); | 112 | static std::string Disassemble(uint32_t addr, uint32_t insn); |
| 113 | static Opcode decode(uint32_t insn); | 113 | static Opcode Decode(uint32_t insn); |
| 114 | 114 | ||
| 115 | private: | 115 | private: |
| 116 | static Opcode decode00(uint32_t insn); | 116 | static Opcode Decode00(uint32_t insn); |
| 117 | static Opcode decode01(uint32_t insn); | 117 | static Opcode Decode01(uint32_t insn); |
| 118 | static Opcode decode10(uint32_t insn); | 118 | static Opcode Decode10(uint32_t insn); |
| 119 | static Opcode decode11(uint32_t insn); | 119 | static Opcode Decode11(uint32_t insn); |
| 120 | static Opcode decode_mul(uint32_t insn); | 120 | static Opcode DecodeMUL(uint32_t insn); |
| 121 | static Opcode decode_ldrh(uint32_t insn); | 121 | static Opcode DecodeLDRH(uint32_t insn); |
| 122 | static Opcode decode_alu(uint32_t insn); | 122 | static Opcode DecodeALU(uint32_t insn); |
| 123 | 123 | ||
| 124 | static char *disasm_alu(Opcode opcode, uint32_t insn, char *ptr); | 124 | static std::string DisassembleALU(Opcode opcode, uint32_t insn); |
| 125 | static char *disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr); | 125 | static std::string DisassembleBranch(uint32_t addr, Opcode opcode, uint32_t insn); |
| 126 | static char *disasm_bx(uint32_t insn, char *ptr); | 126 | static std::string DisassembleBX(uint32_t insn); |
| 127 | static char *disasm_bkpt(uint32_t insn, char *ptr); | 127 | static std::string DisassembleBKPT(uint32_t insn); |
| 128 | static char *disasm_clz(uint32_t insn, char *ptr); | 128 | static std::string DisassembleCLZ(uint32_t insn); |
| 129 | static char *disasm_memblock(Opcode opcode, uint32_t insn, char *ptr); | 129 | static std::string DisassembleMemblock(Opcode opcode, uint32_t insn); |
| 130 | static char *disasm_mem(uint32_t insn, char *ptr); | 130 | static std::string DisassembleMem(uint32_t insn); |
| 131 | static char *disasm_memhalf(uint32_t insn, char *ptr); | 131 | static std::string DisassembleMemHalf(uint32_t insn); |
| 132 | static char *disasm_mcr(Opcode opcode, uint32_t insn, char *ptr); | 132 | static std::string DisassembleMCR(Opcode opcode, uint32_t insn); |
| 133 | static char *disasm_mla(Opcode opcode, uint32_t insn, char *ptr); | 133 | static std::string DisassembleMLA(Opcode opcode, uint32_t insn); |
| 134 | static char *disasm_umlal(Opcode opcode, uint32_t insn, char *ptr); | 134 | static std::string DisassembleUMLAL(Opcode opcode, uint32_t insn); |
| 135 | static char *disasm_mul(Opcode opcode, uint32_t insn, char *ptr); | 135 | static std::string DisassembleMUL(Opcode opcode, uint32_t insn); |
| 136 | static char *disasm_mrs(uint32_t insn, char *ptr); | 136 | static std::string DisassembleMRS(uint32_t insn); |
| 137 | static char *disasm_msr(uint32_t insn, char *ptr); | 137 | static std::string DisassembleMSR(uint32_t insn); |
| 138 | static char *disasm_pld(uint32_t insn, char *ptr); | 138 | static std::string DisassemblePLD(uint32_t insn); |
| 139 | static char *disasm_swi(uint32_t insn, char *ptr); | 139 | static std::string DisassembleSWI(uint32_t insn); |
| 140 | static char *disasm_swp(Opcode opcode, uint32_t insn, char *ptr); | 140 | static std::string DisassembleSWP(Opcode opcode, uint32_t insn); |
| 141 | }; | 141 | }; |
| 142 | |||
| 143 | extern char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *result); | ||
| 144 | extern Opcode decode_insn_thumb(uint32_t given); | ||
| 145 | |||
| 146 | #endif /* ARMDIS_H */ | ||
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 219ba78ce..3d3545c65 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | //#include <util.h> | 18 | //#include <util.h> |
| 19 | 19 | ||
| 20 | #include <string> | ||
| 20 | #include "core/arm/interpreter/armdefs.h" | 21 | #include "core/arm/interpreter/armdefs.h" |
| 21 | #include "core/arm/interpreter/armemu.h" | 22 | #include "core/arm/interpreter/armemu.h" |
| 22 | #include "core/hle/coprocessor.h" | 23 | #include "core/hle/coprocessor.h" |
| @@ -870,12 +871,8 @@ ARMul_CDP (ARMul_State * state, ARMword instr) | |||
| 870 | void | 871 | void |
| 871 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) | 872 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) |
| 872 | { | 873 | { |
| 873 | /*SKYEYE_LOG_IN_CLR(RED, "In %s, line = %d, undef instr: 0x%x\n", | 874 | std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); |
| 874 | __func__, __LINE__, instr);*/ | 875 | ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); |
| 875 | char buff[512]; | ||
| 876 | ARM_Disasm disasm = ARM_Disasm(); | ||
| 877 | disasm.disasm(state->pc, instr, buff); | ||
| 878 | ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", buff, instr); | ||
| 879 | ARMul_Abort (state, ARMul_UndefinedInstrV); | 876 | ARMul_Abort (state, ARMul_UndefinedInstrV); |
| 880 | } | 877 | } |
| 881 | 878 | ||