diff options
Diffstat (limited to 'src/core/arm/disassembler')
-rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 1290 | ||||
-rw-r--r-- | src/core/arm/disassembler/arm_disasm.h | 88 | ||||
-rw-r--r-- | src/core/arm/disassembler/load_symbol_map.cpp | 2 |
3 files changed, 586 insertions, 794 deletions
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index 5ad1f1c29..b3b9971e8 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -9,401 +9,225 @@ #include "core/arm/disassembler/arm_disasm.h" #include "core/arm/skyeye_common/armsupp.h" -static const char *cond_names[] = { - "eq", - "ne", - "cs", - "cc", - "mi", - "pl", - "vs", - "vc", - "hi", - "ls", - "ge", - "lt", - "gt", - "le", - "", - "RESERVED" -}; - -static const char *opcode_names[] = { - "invalid", - "undefined", - "adc", - "add", - "and", - "b", - "bl", - "bic", - "bkpt", - "blx", - "bx", - "cdp", - "clrex", - "clz", - "cmn", - "cmp", - "eor", - "ldc", - "ldm", - "ldr", - "ldrb", - "ldrbt", - "ldrex", - "ldrexb", - "ldrexd", - "ldrexh", - "ldrh", - "ldrsb", - "ldrsh", - "ldrt", - "mcr", - "mla", - "mov", - "mrc", - "mrs", - "msr", - "mul", - "mvn", - "nop", - "orr", - "pkh", - "pld", - "qadd16", - "qadd8", - "qasx", - "qsax", - "qsub16", - "qsub8", - "rev", - "rev16", - "revsh", - "rsb", - "rsc", - "sadd16", - "sadd8", - "sasx", - "sbc", - "sel", - "sev", - "shadd16", - "shadd8", - "shasx", - "shsax", - "shsub16", - "shsub8", - "smlad", - "smlal", - "smlald", - "smlsd", - "smlsld", - "smmla", - "smmls", - "smmul", - "smuad", - "smull", - "smusd", - "ssat", - "ssat16", - "ssax", - "ssub16", - "ssub8", - "stc", - "stm", - "str", - "strb", - "strbt", - "strex", - "strexb", - "strexd", - "strexh", - "strh", - "strt", - "sub", - "swi", - "swp", - "swpb", - "sxtab", - "sxtab16", - "sxtah", - "sxtb", - "sxtb16", - "sxth", - "teq", - "tst", - "uadd16", - "uadd8", - "uasx", - "uhadd16", - "uhadd8", - "uhasx", - "uhsax", - "uhsub16", - "uhsub8", - "umlal", - "umull", - "uqadd16", - "uqadd8", - "uqasx", - "uqsax", - "uqsub16", - "uqsub8", - "usad8", - "usada8", - "usat", - "usat16", - "usax", - "usub16", - "usub8", - "uxtab", - "uxtab16", - "uxtah", - "uxtb", - "uxtb16", - "uxth", - "wfe", - "wfi", +static const char* cond_names[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", + "hi", "ls", "ge", "lt", "gt", "le", "", "RESERVED"}; + +static const char* opcode_names[] = { + "invalid", "undefined", "adc", "add", "and", "b", "bl", "bic", + "bkpt", "blx", "bx", "cdp", "clrex", "clz", "cmn", "cmp", + "eor", "ldc", "ldm", "ldr", "ldrb", "ldrbt", "ldrex", "ldrexb", + "ldrexd", "ldrexh", "ldrh", "ldrsb", "ldrsh", "ldrt", "mcr", "mla", + "mov", "mrc", "mrs", "msr", "mul", "mvn", "nop", "orr", + "pkh", "pld", "qadd16", "qadd8", "qasx", "qsax", "qsub16", "qsub8", + "rev", "rev16", "revsh", "rsb", "rsc", "sadd16", "sadd8", "sasx", + "sbc", "sel", "sev", "shadd16", "shadd8", "shasx", "shsax", "shsub16", + "shsub8", "smlad", "smlal", "smlald", "smlsd", "smlsld", "smmla", "smmls", + "smmul", "smuad", "smull", "smusd", "ssat", "ssat16", "ssax", "ssub16", + "ssub8", "stc", "stm", "str", "strb", "strbt", "strex", "strexb", + "strexd", "strexh", "strh", "strt", "sub", "swi", "swp", "swpb", + "sxtab", "sxtab16", "sxtah", "sxtb", "sxtb16", "sxth", "teq", "tst", + "uadd16", "uadd8", "uasx", "uhadd16", "uhadd8", "uhasx", "uhsax", "uhsub16", + "uhsub8", "umlal", "umull", "uqadd16", "uqadd8", "uqasx", "uqsax", "uqsub16", + "uqsub8", "usad8", "usada8", "usat", "usat16", "usax", "usub16", "usub8", + "uxtab", "uxtab16", "uxtah", "uxtb", "uxtb16", "uxth", "wfe", "wfi", "yield", - "undefined", - "adc", - "add", - "and", - "asr", - "b", - "bic", - "bkpt", - "bl", - "blx", - "bx", - "cmn", - "cmp", - "eor", - "ldmia", - "ldr", - "ldrb", - "ldrh", - "ldrsb", - "ldrsh", - "lsl", - "lsr", - "mov", - "mul", - "mvn", - "neg", - "orr", - "pop", - "push", - "ror", - "sbc", - "stmia", - "str", - "strb", - "strh", - "sub", - "swi", - "tst", - - nullptr -}; + "undefined", "adc", "add", "and", "asr", "b", "bic", "bkpt", + "bl", "blx", "bx", "cmn", "cmp", "eor", "ldmia", "ldr", + "ldrb", "ldrh", "ldrsb", "ldrsh", "lsl", "lsr", "mov", "mul", + "mvn", "neg", "orr", "pop", "push", "ror", "sbc", "stmia", + "str", "strb", "strh", "sub", "swi", "tst", + + nullptr}; // Indexed by the shift type (bits 6-5) -static const char *shift_names[] = { - "LSL", - "LSR", - "ASR", - "ROR" -}; +static const char* shift_names[] = {"LSL", "LSR", "ASR", "ROR"}; static const char* cond_to_str(u32 cond) { return cond_names[cond]; } -std::string ARM_Disasm::Disassemble(u32 addr, u32 insn) -{ +std::string ARM_Disasm::Disassemble(u32 addr, u32 insn) { Opcode opcode = Decode(insn); switch (opcode) { - case OP_INVALID: - return "Invalid"; - case OP_UNDEFINED: - return "Undefined"; - case OP_ADC: - case OP_ADD: - case OP_AND: - case OP_BIC: - case OP_CMN: - case OP_CMP: - case OP_EOR: - case OP_MOV: - case OP_MVN: - case OP_ORR: - case OP_RSB: - case OP_RSC: - case OP_SBC: - case OP_SUB: - case OP_TEQ: - case OP_TST: - return DisassembleALU(opcode, insn); - case OP_B: - case OP_BL: - return DisassembleBranch(addr, opcode, insn); - case OP_BKPT: - return DisassembleBKPT(insn); - case OP_BLX: - // not supported yet - break; - case OP_BX: - return DisassembleBX(insn); - case OP_CDP: - return "cdp"; - case OP_CLREX: - return "clrex"; - case OP_CLZ: - return DisassembleCLZ(insn); - case OP_LDC: - return "ldc"; - case OP_LDM: - case OP_STM: - return DisassembleMemblock(opcode, insn); - case OP_LDR: - case OP_LDRB: - case OP_LDRBT: - case OP_LDRT: - case OP_STR: - case OP_STRB: - case OP_STRBT: - case OP_STRT: - return DisassembleMem(insn); - case OP_LDREX: - case OP_LDREXB: - case OP_LDREXD: - case OP_LDREXH: - case OP_STREX: - case OP_STREXB: - case OP_STREXD: - case OP_STREXH: - return DisassembleREX(opcode, insn); - case OP_LDRH: - case OP_LDRSB: - case OP_LDRSH: - case OP_STRH: - return DisassembleMemHalf(insn); - case OP_MCR: - case OP_MRC: - return DisassembleMCR(opcode, insn); - case OP_MLA: - return DisassembleMLA(opcode, insn); - case OP_MRS: - return DisassembleMRS(insn); - case OP_MSR: - return DisassembleMSR(insn); - case OP_MUL: - return DisassembleMUL(opcode, insn); - case OP_NOP: - case OP_SEV: - case OP_WFE: - case OP_WFI: - case OP_YIELD: - return DisassembleNoOperands(opcode, insn); - case OP_PKH: - return DisassemblePKH(insn); - case OP_PLD: - return DisassemblePLD(insn); - case OP_QADD16: - case OP_QADD8: - case OP_QASX: - case OP_QSAX: - case OP_QSUB16: - case OP_QSUB8: - case OP_SADD16: - case OP_SADD8: - case OP_SASX: - case OP_SHADD16: - case OP_SHADD8: - case OP_SHASX: - case OP_SHSAX: - case OP_SHSUB16: - case OP_SHSUB8: - case OP_SSAX: - case OP_SSUB16: - case OP_SSUB8: - case OP_UADD16: - case OP_UADD8: - case OP_UASX: - case OP_UHADD16: - case OP_UHADD8: - case OP_UHASX: - case OP_UHSAX: - case OP_UHSUB16: - case OP_UHSUB8: - case OP_UQADD16: - case OP_UQADD8: - case OP_UQASX: - case OP_UQSAX: - case OP_UQSUB16: - case OP_UQSUB8: - case OP_USAX: - case OP_USUB16: - case OP_USUB8: - return DisassembleParallelAddSub(opcode, insn); - case OP_REV: - case OP_REV16: - case OP_REVSH: - return DisassembleREV(opcode, insn); - case OP_SEL: - return DisassembleSEL(insn); - case OP_SMLAD: - case OP_SMLALD: - case OP_SMLSD: - case OP_SMLSLD: - case OP_SMMLA: - case OP_SMMLS: - case OP_SMMUL: - case OP_SMUAD: - case OP_SMUSD: - case OP_USAD8: - case OP_USADA8: - return DisassembleMediaMulDiv(opcode, insn); - case OP_SSAT: - case OP_SSAT16: - case OP_USAT: - case OP_USAT16: - return DisassembleSAT(opcode, insn); - case OP_STC: - return "stc"; - case OP_SWI: - return DisassembleSWI(insn); - case OP_SWP: - case OP_SWPB: - return DisassembleSWP(opcode, insn); - case OP_SXTAB: - case OP_SXTAB16: - case OP_SXTAH: - case OP_SXTB: - case OP_SXTB16: - case OP_SXTH: - case OP_UXTAB: - case OP_UXTAB16: - case OP_UXTAH: - case OP_UXTB: - case OP_UXTB16: - case OP_UXTH: - return DisassembleXT(opcode, insn); - case OP_UMLAL: - case OP_UMULL: - case OP_SMLAL: - case OP_SMULL: - return DisassembleUMLAL(opcode, insn); - default: - return "Error"; + case OP_INVALID: + return "Invalid"; + case OP_UNDEFINED: + return "Undefined"; + case OP_ADC: + case OP_ADD: + case OP_AND: + case OP_BIC: + case OP_CMN: + case OP_CMP: + case OP_EOR: + case OP_MOV: + case OP_MVN: + case OP_ORR: + case OP_RSB: + case OP_RSC: + case OP_SBC: + case OP_SUB: + case OP_TEQ: + case OP_TST: + return DisassembleALU(opcode, insn); + case OP_B: + case OP_BL: + return DisassembleBranch(addr, opcode, insn); + case OP_BKPT: + return DisassembleBKPT(insn); + case OP_BLX: + // not supported yet + break; + case OP_BX: + return DisassembleBX(insn); + case OP_CDP: + return "cdp"; + case OP_CLREX: + return "clrex"; + case OP_CLZ: + return DisassembleCLZ(insn); + case OP_LDC: + return "ldc"; + case OP_LDM: + case OP_STM: + return DisassembleMemblock(opcode, insn); + case OP_LDR: + case OP_LDRB: + case OP_LDRBT: + case OP_LDRT: + case OP_STR: + case OP_STRB: + case OP_STRBT: + case OP_STRT: + return DisassembleMem(insn); + case OP_LDREX: + case OP_LDREXB: + case OP_LDREXD: + case OP_LDREXH: + case OP_STREX: + case OP_STREXB: + case OP_STREXD: + case OP_STREXH: + return DisassembleREX(opcode, insn); + case OP_LDRH: + case OP_LDRSB: + case OP_LDRSH: + case OP_STRH: + return DisassembleMemHalf(insn); + case OP_MCR: + case OP_MRC: + return DisassembleMCR(opcode, insn); + case OP_MLA: + return DisassembleMLA(opcode, insn); + case OP_MRS: + return DisassembleMRS(insn); + case OP_MSR: + return DisassembleMSR(insn); + case OP_MUL: + return DisassembleMUL(opcode, insn); + case OP_NOP: + case OP_SEV: + case OP_WFE: + case OP_WFI: + case OP_YIELD: + return DisassembleNoOperands(opcode, insn); + case OP_PKH: + return DisassemblePKH(insn); + case OP_PLD: + return DisassemblePLD(insn); + case OP_QADD16: + case OP_QADD8: + case OP_QASX: + case OP_QSAX: + case OP_QSUB16: + case OP_QSUB8: + case OP_SADD16: + case OP_SADD8: + case OP_SASX: + case OP_SHADD16: + case OP_SHADD8: + case OP_SHASX: + case OP_SHSAX: + case OP_SHSUB16: + case OP_SHSUB8: + case OP_SSAX: + case OP_SSUB16: + case OP_SSUB8: + case OP_UADD16: + case OP_UADD8: + case OP_UASX: + case OP_UHADD16: + case OP_UHADD8: + case OP_UHASX: + case OP_UHSAX: + case OP_UHSUB16: + case OP_UHSUB8: + case OP_UQADD16: + case OP_UQADD8: + case OP_UQASX: + case OP_UQSAX: + case OP_UQSUB16: + case OP_UQSUB8: + case OP_USAX: + case OP_USUB16: + case OP_USUB8: + return DisassembleParallelAddSub(opcode, insn); + case OP_REV: + case OP_REV16: + case OP_REVSH: + return DisassembleREV(opcode, insn); + case OP_SEL: + return DisassembleSEL(insn); + case OP_SMLAD: + case OP_SMLALD: + case OP_SMLSD: + case OP_SMLSLD: + case OP_SMMLA: + case OP_SMMLS: + case OP_SMMUL: + case OP_SMUAD: + case OP_SMUSD: + case OP_USAD8: + case OP_USADA8: + return DisassembleMediaMulDiv(opcode, insn); + case OP_SSAT: + case OP_SSAT16: + case OP_USAT: + case OP_USAT16: + return DisassembleSAT(opcode, insn); + case OP_STC: + return "stc"; + case OP_SWI: + return DisassembleSWI(insn); + case OP_SWP: + case OP_SWPB: + return DisassembleSWP(opcode, insn); + case OP_SXTAB: + case OP_SXTAB16: + case OP_SXTAH: + case OP_SXTB: + case OP_SXTB16: + case OP_SXTH: + case OP_UXTAB: + case OP_UXTAB16: + case OP_UXTAH: + case OP_UXTB: + case OP_UXTB16: + case OP_UXTH: + return DisassembleXT(opcode, insn); + case OP_UMLAL: + case OP_UMULL: + case OP_SMLAL: + case OP_SMULL: + return DisassembleUMLAL(opcode, insn); + default: + return "Error"; } return nullptr; } -std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) { static const u8 kNoOperand1 = 1; static const u8 kNoDest = 2; static const u8 kNoSbit = 4; @@ -421,18 +245,18 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) const char* opname = opcode_names[opcode]; switch (opcode) { - case OP_CMN: - case OP_CMP: - case OP_TEQ: - case OP_TST: - flags = kNoDest | kNoSbit; - break; - case OP_MOV: - case OP_MVN: - flags = kNoOperand1; - break; - default: - break; + case OP_CMN: + case OP_CMP: + case OP_TEQ: + case OP_TST: + flags = kNoDest | kNoSbit; + break; + case OP_MOV: + case OP_MVN: + flags = kNoOperand1; + break; + default: + break; } // The "mov" instruction ignores the first operand (rn). @@ -448,13 +272,13 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) rd_str = Common::StringFromFormat("r%d, ", rd); } - const char *sbit_str = ""; + const char* sbit_str = ""; if (bit_s && !(flags & kNoSbit)) sbit_str = "s"; if (is_immed) { - return Common::StringFromFormat("%s%s%s\t%s%s#%u ; 0x%x", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), immed, immed); + return Common::StringFromFormat("%s%s%s\t%s%s#%u ; 0x%x", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), immed, immed); } u8 shift_is_reg = (insn >> 4) & 1; @@ -468,30 +292,28 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) rotated_val = (rotated_val >> rotate2) | (rotated_val << (32 - rotate2)); if (!shift_is_reg && shift_type == 0 && shift_amount == 0) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); + return Common::StringFromFormat("%s%s%s\t%s%sr%d", opname, cond_to_str(cond), sbit_str, + rd_str.c_str(), rn_str.c_str(), rm); } - const char *shift_name = shift_names[shift_type]; + const char* shift_name = shift_names[shift_type]; if (shift_is_reg) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s r%d", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, - shift_name, rs); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s r%d", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), rm, shift_name, + rs); } if (shift_amount == 0) { if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d, RRX", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, RRX", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), rm); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s #%u", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, - shift_name, shift_amount); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s #%u", opname, cond_to_str(cond), sbit_str, + rd_str.c_str(), rn_str.c_str(), rm, shift_name, shift_amount); } -std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 offset = insn & 0xffffff; // Sign-extend the 24-bit offset @@ -502,26 +324,23 @@ std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) offset <<= 2; offset += 8; addr += offset; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; return Common::StringFromFormat("%s%s\t0x%x", opname, cond_to_str(cond), addr); } -std::string ARM_Disasm::DisassembleBX(u32 insn) -{ +std::string ARM_Disasm::DisassembleBX(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rn = insn & 0xf; return Common::StringFromFormat("bx%s\tr%d", cond_to_str(cond), rn); } -std::string ARM_Disasm::DisassembleBKPT(u32 insn) -{ +std::string ARM_Disasm::DisassembleBKPT(u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 immed = (((insn >> 8) & 0xfff) << 4) | (insn & 0xf); return Common::StringFromFormat("bkpt%s\t#%d", cond_to_str(cond), immed); } -std::string ARM_Disasm::DisassembleCLZ(u32 insn) -{ +std::string ARM_Disasm::DisassembleCLZ(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 rm = insn & 0xf; @@ -545,9 +364,8 @@ std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, u32 insn) { } std::string ext_reg = ""; - std::unordered_set<Opcode, std::hash<int>> with_ext_reg = { - OP_SMLAD, OP_SMLSD, OP_SMMLA, OP_SMMLS, OP_USADA8 - }; + std::unordered_set<Opcode, std::hash<int>> with_ext_reg = {OP_SMLAD, OP_SMLSD, OP_SMMLA, + OP_SMMLS, OP_USADA8}; if (with_ext_reg.find(opcode) != with_ext_reg.end()) ext_reg = Common::StringFromFormat(", r%u", ra); @@ -560,8 +378,7 @@ std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, u32 insn) { ext_reg.c_str()); } -std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) { std::string tmp_list; u8 cond = (insn >> 28) & 0xf; @@ -572,17 +389,17 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) u8 rn = (insn >> 16) & 0xf; u16 reg_list = insn & 0xffff; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *carret = ""; + const char* carret = ""; if (bit_s) carret = "^"; - const char *comma = ""; + const char* comma = ""; tmp_list[0] = 0; for (int ii = 0; ii < 16; ++ii) { if (reg_list & (1 << ii)) { @@ -591,7 +408,7 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) } } - const char *addr_mode = ""; + const char* addr_mode = ""; if (is_pre) { if (is_up) { addr_mode = "ib"; @@ -606,12 +423,11 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) } } - return Common::StringFromFormat("%s%s%s\tr%d%s, {%s}%s", - opname, cond_to_str(cond), addr_mode, rn, bang, tmp_list.c_str(), carret); + return Common::StringFromFormat("%s%s%s\tr%d%s, {%s}%s", opname, cond_to_str(cond), addr_mode, + rn, bang, tmp_list.c_str(), carret); } -std::string ARM_Disasm::DisassembleMem(u32 insn) -{ +std::string ARM_Disasm::DisassembleMem(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 is_reg = (insn >> 25) & 0x1; u8 is_load = (insn >> 20) & 0x1; @@ -623,38 +439,40 @@ std::string ARM_Disasm::DisassembleMem(u32 insn) u8 rd = (insn >> 12) & 0xf; u16 offset = insn & 0xfff; - const char *opname = "ldr"; + const char* opname = "ldr"; if (!is_load) opname = "str"; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; - const char *byte = ""; + const char* byte = ""; if (is_byte) byte = "b"; if (is_reg == 0) { if (is_pre) { if (offset == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", - opname, cond_to_str(cond), byte, rd, rn); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), + byte, rd, rn); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, offset, + bang); } } else { - const char *transfer = ""; + const char* transfer = ""; if (write_back) transfer = "t"; - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], #%s%u", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, offset); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], #%s%u", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, + offset); } } @@ -662,48 +480,47 @@ std::string ARM_Disasm::DisassembleMem(u32 insn) u8 shift_type = (insn >> 5) & 0x3; u8 shift_amount = (insn >> 7) & 0x1f; - const char *shift_name = shift_names[shift_type]; + const char* shift_name = shift_names[shift_type]; if (is_pre) { if (shift_amount == 0) { if (shift_type == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, bang); } if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, bang); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, - shift_name, shift_amount, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, shift_name, + shift_amount, bang); } - const char *transfer = ""; + const char* transfer = ""; if (write_back) transfer = "t"; if (shift_amount == 0) { if (shift_type == 0) { - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm); } if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, RRX", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, RRX", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm, - shift_name, shift_amount); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm, + shift_name, shift_amount); } -std::string ARM_Disasm::DisassembleMemHalf(u32 insn) -{ +std::string ARM_Disasm::DisassembleMemHalf(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 is_load = (insn >> 20) & 0x1; u8 write_back = (insn >> 21) & 0x1; @@ -716,11 +533,11 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn) u8 rm = insn & 0xf; u8 offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf); - const char *opname = "ldr"; + const char* opname = "ldr"; if (is_load == 0) opname = "str"; - const char *width = ""; + const char* width = ""; if (bits_65 == 1) width = "h"; else if (bits_65 == 2) @@ -728,38 +545,39 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn) else width = "sh"; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; if (is_immed) { if (is_pre) { if (offset == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), width, rd, rn); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), + width, rd, rn); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", - opname, cond_to_str(cond), width, rd, rn, minus, offset, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", opname, + cond_to_str(cond), width, rd, rn, minus, offset, + bang); } } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u", - opname, cond_to_str(cond), width, rd, rn, minus, offset); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u", opname, cond_to_str(cond), + width, rd, rn, minus, offset); } } if (is_pre) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", - opname, cond_to_str(cond), width, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", opname, cond_to_str(cond), + width, rd, rn, minus, rm, bang); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d", - opname, cond_to_str(cond), width, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d", opname, cond_to_str(cond), + width, rd, rn, minus, rm); } } -std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 crn = (insn >> 16) & 0xf; u8 crd = (insn >> 12) & 0xf; @@ -767,13 +585,12 @@ std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) u8 opcode2 = (insn >> 5) & 0x7; u8 crm = insn & 0xf; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", - opname, cond_to_str(cond), cpnum, crd, crn, crm, opcode2); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", opname, cond_to_str(cond), + cpnum, crd, crn, crm, opcode2); } -std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 16) & 0xf; u8 rn = (insn >> 12) & 0xf; @@ -781,13 +598,12 @@ std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs, rn); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rd, rm, rs, rn); } -std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rdhi = (insn >> 16) & 0xf; u8 rdlo = (insn >> 12) & 0xf; @@ -795,26 +611,24 @@ std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rdlo, rdhi, rm, rs); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rdlo, rdhi, rm, rs); } -std::string ARM_Disasm::DisassembleMUL(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMUL(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 16) & 0xf; u8 rs = (insn >> 8) & 0xf; u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rd, rm, rs); } -std::string ARM_Disasm::DisassembleMRS(u32 insn) -{ +std::string ARM_Disasm::DisassembleMRS(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 ps = (insn >> 22) & 1; @@ -822,8 +636,7 @@ std::string ARM_Disasm::DisassembleMRS(u32 insn) return Common::StringFromFormat("mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr"); } -std::string ARM_Disasm::DisassembleMSR(u32 insn) -{ +std::string ARM_Disasm::DisassembleMSR(u32 insn) { char flags[8]; int flag_index = 0; u8 cond = (insn >> 28) & 0xf; @@ -846,18 +659,17 @@ std::string ARM_Disasm::DisassembleMSR(u32 insn) u8 rotate = (insn >> 8) & 0xf; u8 rotate2 = rotate << 1; u32 rotated_val = (immed >> rotate2) | (immed << (32 - rotate2)); - return Common::StringFromFormat("msr%s\t%s_%s, #0x%x", - cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rotated_val); + return Common::StringFromFormat("msr%s\t%s_%s, #0x%x", cond_to_str(cond), + pd ? "spsr" : "cpsr", flags, rotated_val); } u8 rm = insn & 0xf; - return Common::StringFromFormat("msr%s\t%s_%s, r%d", - cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); + return Common::StringFromFormat("msr%s\t%s_%s, r%d", cond_to_str(cond), pd ? "spsr" : "cpsr", + flags, rm); } -std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); } @@ -872,8 +684,7 @@ std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, u32 insn) { rd, rn, rm); } -std::string ARM_Disasm::DisassemblePKH(u32 insn) -{ +std::string ARM_Disasm::DisassemblePKH(u32 insn) { u32 cond = BITS(insn, 28, 31); u32 rn = BITS(insn, 16, 19); u32 rd = BITS(insn, 12, 15); @@ -896,13 +707,12 @@ std::string ARM_Disasm::DisassemblePKH(u32 insn) rd, rn, rm, shift.c_str()); } -std::string ARM_Disasm::DisassemblePLD(u32 insn) -{ +std::string ARM_Disasm::DisassemblePLD(u32 insn) { u8 is_reg = (insn >> 25) & 0x1; u8 is_up = (insn >> 23) & 0x1; u8 rn = (insn >> 16) & 0xf; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; @@ -924,8 +734,8 @@ std::string ARM_Disasm::DisassembleREV(Opcode opcode, u32 insn) { u32 rd = BITS(insn, 12, 15); u32 rm = BITS(insn, 0, 3); - return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond), - rd, rm); + return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond), rd, + rm); } std::string ARM_Disasm::DisassembleREX(Opcode opcode, u32 insn) { @@ -935,26 +745,26 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); switch (opcode) { - case OP_STREX: - case OP_STREXB: - case OP_STREXH: - return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rt, rn); - case OP_STREXD: - return Common::StringFromFormat("%s%s\tr%d, r%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rt, rt + 1, rn); - - // for LDREX instructions, rd corresponds to Rt from reference manual - case OP_LDREX: - case OP_LDREXB: - case OP_LDREXH: - return Common::StringFromFormat("%s%s\tr%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rn); - case OP_LDREXD: - return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rd + 1, rn); - default: - return opcode_names[OP_UNDEFINED]; + case OP_STREX: + case OP_STREXB: + case OP_STREXH: + return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rt, rn); + case OP_STREXD: + return Common::StringFromFormat("%s%s\tr%d, r%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rt, rt + 1, rn); + + // for LDREX instructions, rd corresponds to Rt from reference manual + case OP_LDREX: + case OP_LDREXB: + case OP_LDREXH: + return Common::StringFromFormat("%s%s\tr%d, [r%d]", opcode_names[opcode], cond_to_str(cond), + rd, rn); + case OP_LDREXD: + return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rd + 1, rn); + default: + return opcode_names[OP_UNDEFINED]; } } @@ -982,8 +792,8 @@ std::string ARM_Disasm::DisassembleSAT(Opcode opcode, u32 insn) { if (opcode == OP_SSAT || opcode == OP_SSAT16) sat_imm++; - return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd, - sat_imm, rn, shift_part.c_str()); + return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], + cond_to_str(cond), rd, sat_imm, rn, shift_part.c_str()); } std::string ARM_Disasm::DisassembleSEL(u32 insn) { @@ -996,27 +806,24 @@ std::string ARM_Disasm::DisassembleSEL(u32 insn) { rd, rn, rm); } -std::string ARM_Disasm::DisassembleSWI(u32 insn) -{ +std::string ARM_Disasm::DisassembleSWI(u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 sysnum = insn & 0x00ffffff; return Common::StringFromFormat("swi%s 0x%x", cond_to_str(cond), sysnum); } -std::string ARM_Disasm::DisassembleSWP(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleSWP(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rn = (insn >> 16) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 rm = insn & 0xf; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn); } -std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); u32 rn = BITS(insn, 16, 19); u32 rd = BITS(insn, 12, 15); @@ -1025,9 +832,7 @@ std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) std::string rn_part = ""; static std::unordered_set<Opcode, std::hash<int>> extend_with_add = { - OP_SXTAB, OP_SXTAB16, OP_SXTAH, - OP_UXTAB, OP_UXTAB16, OP_UXTAH - }; + OP_SXTAB, OP_SXTAB16, OP_SXTAH, OP_UXTAB, OP_UXTAB16, OP_UXTAH}; if (extend_with_add.find(opcode) != extend_with_add.end()) rn_part = ", r" + std::to_string(rn); @@ -1042,14 +847,14 @@ std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) Opcode ARM_Disasm::Decode(u32 insn) { u32 bits27_26 = (insn >> 26) & 0x3; switch (bits27_26) { - case 0x0: - return Decode00(insn); - case 0x1: - return Decode01(insn); - case 0x2: - return Decode10(insn); - case 0x3: - return Decode11(insn); + case 0x0: + return Decode00(insn); + case 0x1: + return Decode01(insn); + case 0x2: + return Decode10(insn); + case 0x3: + return Decode11(insn); } return OP_INVALID; } @@ -1198,28 +1003,28 @@ Opcode ARM_Disasm::DecodeSyncPrimitive(u32 insn) { u32 op = BITS(insn, 20, 23); u32 bit22 = BIT(insn, 22); switch (op) { - case 0x0: - if (bit22) - return OP_SWPB; - return OP_SWP; - case 0x8: - return OP_STREX; - case 0x9: - return OP_LDREX; - case 0xA: - return OP_STREXD; - case 0xB: - return OP_LDREXD; - case 0xC: - return OP_STREXB; - case 0xD: - return OP_LDREXB; - case 0xE: - return OP_STREXH; - case 0xF: - return OP_LDREXH; - default: - return OP_UNDEFINED; + case 0x0: + if (bit22) + return OP_SWPB; + return OP_SWP; + case 0x8: + return OP_STREX; + case 0x9: + return OP_LDREX; + case 0xA: + return OP_STREXD; + case 0xB: + return OP_LDREXD; + case 0xC: + return OP_STREXB; + case 0xD: + return OP_LDREXB; + case 0xE: + return OP_STREXH; + case 0xF: + return OP_LDREXH; + default: + return OP_UNDEFINED; } } @@ -1240,27 +1045,14 @@ Opcode ARM_Disasm::DecodeParallelAddSub(u32 insn) { static std::vector<Opcode> opcodes = { // op1 = 0 - OP_SADD16, OP_UADD16, - OP_SASX, OP_UASX, - OP_SSAX, OP_USAX, - OP_SSUB16, OP_USUB16, - OP_SADD8, OP_UADD8, - OP_SSUB8, OP_USUB8, + OP_SADD16, OP_UADD16, OP_SASX, OP_UASX, OP_SSAX, OP_USAX, OP_SSUB16, OP_USUB16, OP_SADD8, + OP_UADD8, OP_SSUB8, OP_USUB8, // op1 = 1 - OP_QADD16, OP_UQADD16, - OP_QASX, OP_UQASX, - OP_QSAX, OP_UQSAX, - OP_QSUB16, OP_UQSUB16, - OP_QADD8, OP_UQADD8, - OP_QSUB8, OP_UQSUB8, + OP_QADD16, OP_UQADD16, OP_QASX, OP_UQASX, OP_QSAX, OP_UQSAX, OP_QSUB16, OP_UQSUB16, + OP_QADD8, OP_UQADD8, OP_QSUB8, OP_UQSUB8, // op1 = 2 - OP_SHADD16, OP_UHADD16, - OP_SHASX, OP_UHASX, - OP_SHSAX, OP_UHSAX, - OP_SHSUB16, OP_UHSUB16, - OP_SHADD8, OP_UHADD8, - OP_SHSUB8, OP_UHSUB8 - }; + OP_SHADD16, OP_UHADD16, OP_SHASX, OP_UHASX, OP_SHSAX, OP_UHSAX, OP_SHSUB16, OP_UHSUB16, + OP_SHADD8, OP_UHADD8, OP_SHSUB8, OP_UHSUB8}; u32 opcode_index = op1 * 12 + op2 * 2 + is_unsigned; return opcodes[opcode_index]; @@ -1272,66 +1064,66 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(u32 insn) { u32 op2 = BITS(insn, 5, 7); switch (op1) { - case 0x0: - if (BIT(op2, 0) == 0) - return OP_PKH; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAB16; - if (op2 == 0x3 && a == 0xf) - return OP_SXTB16; - if (op2 == 0x5) - return OP_SEL; - break; - case 0x2: - if (BIT(op2, 0) == 0) - return OP_SSAT; - if (op2 == 0x1) - return OP_SSAT16; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAB; - if (op2 == 0x3 && a == 0xf) - return OP_SXTB; - break; - case 0x3: - if (op2 == 0x1) - return OP_REV; - if (BIT(op2, 0) == 0) - return OP_SSAT; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAH; - if (op2 == 0x3 && a == 0xf) - return OP_SXTH; - if (op2 == 0x5) - return OP_REV16; - break; - case 0x4: - if (op2 == 0x3 && a != 0xf) - return OP_UXTAB16; - if (op2 == 0x3 && a == 0xf) - return OP_UXTB16; - break; - case 0x6: - if (BIT(op2, 0) == 0) - return OP_USAT; - if (op2 == 0x1) - return OP_USAT16; - if (op2 == 0x3 && a != 0xf) - return OP_UXTAB; - if (op2 == 0x3 && a == 0xf) - return OP_UXTB; - break; - case 0x7: - if (BIT(op2, 0) == 0) - return OP_USAT; - if (op2 == 0x3 && a != 0xf) - return OP_UXTAH; - if (op2 == 0x3 && a == 0xf) - return OP_UXTH; - if (op2 == 0x5) - return OP_REVSH; - break; - default: - break; + case 0x0: + if (BIT(op2, 0) == 0) + return OP_PKH; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAB16; + if (op2 == 0x3 && a == 0xf) + return OP_SXTB16; + if (op2 == 0x5) + return OP_SEL; + break; + case 0x2: + if (BIT(op2, 0) == 0) + return OP_SSAT; + if (op2 == 0x1) + return OP_SSAT16; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAB; + if (op2 == 0x3 && a == 0xf) + return OP_SXTB; + break; + case 0x3: + if (op2 == 0x1) + return OP_REV; + if (BIT(op2, 0) == 0) + return OP_SSAT; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAH; + if (op2 == 0x3 && a == 0xf) + return OP_SXTH; + if (op2 == 0x5) + return OP_REV16; + break; + case 0x4: + if (op2 == 0x3 && a != 0xf) + return OP_UXTAB16; + if (op2 == 0x3 && a == 0xf) + return OP_UXTB16; + break; + case 0x6: + if (BIT(op2, 0) == 0) + return OP_USAT; + if (op2 == 0x1) + return OP_USAT16; + if (op2 == 0x3 && a != 0xf) + return OP_UXTAB; + if (op2 == 0x3 && a == 0xf) + return OP_UXTB; + break; + case 0x7: + if (BIT(op2, 0) == 0) + return OP_USAT; + if (op2 == 0x3 && a != 0xf) + return OP_UXTAH; + if (op2 == 0x3 && a == 0xf) + return OP_UXTH; + if (op2 == 0x5) + return OP_REVSH; + break; + default: + break; } return OP_UNDEFINED; @@ -1378,18 +1170,18 @@ Opcode ARM_Disasm::DecodeMSRImmAndHints(u32 insn) { if (op == 0 && op1 == 0) { switch (op2) { - case 0x0: - return OP_NOP; - case 0x1: - return OP_YIELD; - case 0x2: - return OP_WFE; - case 0x3: - return OP_WFI; - case 0x4: - return OP_SEV; - default: - return OP_UNDEFINED; + case 0x0: + return OP_NOP; + case 0x1: + return OP_YIELD; + case 0x2: + return OP_WFE; + case 0x3: + return OP_WFI; + case 0x4: + return OP_SEV; + default: + return OP_UNDEFINED; } } @@ -1402,37 +1194,37 @@ Opcode ARM_Disasm::DecodeMediaMulDiv(u32 insn) { u32 a = BITS(insn, 12, 15); switch (op1) { - case 0x0: - if (op2_h == 0x0) { - if (a != 0xf) - return OP_SMLAD; - else - return OP_SMUAD; - } else if (op2_h == 0x1) { - if (a != 0xf) - return OP_SMLSD; - else - return OP_SMUSD; - } - break; - case 0x4: - if (op2_h == 0x0) - return OP_SMLALD; - else if (op2_h == 0x1) - return OP_SMLSLD; - break; - case 0x5: - if (op2_h == 0x0) { - if (a != 0xf) - return OP_SMMLA; - else - return OP_SMMUL; - } else if (op2_h == 0x3) { - return OP_SMMLS; - } - break; - default: - break; + case 0x0: + if (op2_h == 0x0) { + if (a != 0xf) + return OP_SMLAD; + else + return OP_SMUAD; + } else if (op2_h == 0x1) { + if (a != 0xf) + return OP_SMLSD; + else + return OP_SMUSD; + } + break; + case 0x4: + if (op2_h == 0x0) + return OP_SMLALD; + else if (op2_h == 0x1) + return OP_SMLSLD; + break; + case 0x5: + if (op2_h == 0x0) { + if (a != 0xf) + return OP_SMMLA; + else + return OP_SMMUL; + } else if (op2_h == 0x3) { + return OP_SMMLS; + } + break; + default: + break; } return OP_UNDEFINED; @@ -1444,23 +1236,23 @@ Opcode ARM_Disasm::DecodeMedia(u32 insn) { u32 op2 = BITS(insn, 5, 7); switch (BITS(op1, 3, 4)) { - case 0x0: - // unsigned and signed parallel addition and subtraction - return DecodeParallelAddSub(insn); - case 0x1: - // Packing, unpacking, saturation, and reversal - return DecodePackingSaturationReversal(insn); - case 0x2: - // Signed multiply, signed and unsigned divide - return DecodeMediaMulDiv(insn); - case 0x3: - if (op2 == 0 && rd == 0xf) - return OP_USAD8; - if (op2 == 0 && rd != 0xf) - return OP_USADA8; - break; - default: - break; + case 0x0: + // unsigned and signed parallel addition and subtraction + return DecodeParallelAddSub(insn); + case 0x1: + // Packing, unpacking, saturation, and reversal + return DecodePackingSaturationReversal(insn); + case 0x2: + // Signed multiply, signed and unsigned divide + return DecodeMediaMulDiv(insn); + case 0x3: + if (op2 == 0 && rd == 0xf) + return OP_USAD8; + if (op2 == 0 && rd != 0xf) + return OP_USADA8; + break; + default: + break; } return OP_UNDEFINED; @@ -1508,46 +1300,46 @@ Opcode ARM_Disasm::DecodeALU(u32 insn) { return OP_UNDEFINED; } switch (opcode) { - case 0x0: - return OP_AND; - case 0x1: - return OP_EOR; - case 0x2: - return OP_SUB; - case 0x3: - return OP_RSB; - case 0x4: - return OP_ADD; - case 0x5: - return OP_ADC; - case 0x6: - return OP_SBC; - case 0x7: - return OP_RSC; - case 0x8: - if (bit_s) - return OP_TST; - return OP_MRS; - case 0x9: - if (bit_s) - return OP_TEQ; - return OP_MSR; - case 0xa: - if (bit_s) - return OP_CMP; - return OP_MRS; - case 0xb: - if (bit_s) - return OP_CMN; - return OP_MSR; - case 0xc: - return OP_ORR; - case 0xd: - return OP_MOV; - case 0xe: - return OP_BIC; - case 0xf: - return OP_MVN; + case 0x0: + return OP_AND; + case 0x1: + return OP_EOR; + case 0x2: + return OP_SUB; + case 0x3: + return OP_RSB; + case 0x4: + return OP_ADD; + case 0x5: + return OP_ADC; + case 0x6: + return OP_SBC; + case 0x7: + return OP_RSC; + case 0x8: + if (bit_s) + return OP_TST; + return OP_MRS; + case 0x9: + if (bit_s) + return OP_TEQ; + return OP_MSR; + case 0xa: + if (bit_s) + return OP_CMP; + return OP_MRS; + case 0xb: + if (bit_s) + return OP_CMN; + return OP_MSR; + case 0xc: + return OP_ORR; + case 0xd: + return OP_MOV; + case 0xe: + return OP_BIC; + case 0xf: + return OP_MVN; } // Unreachable return OP_INVALID; diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index 53d9c6a74..031f973d6 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h @@ -187,53 +187,53 @@ enum Opcode { OP_THUMB_SWI, OP_THUMB_TST, - OP_END // must be last + OP_END // must be last }; class ARM_Disasm { - public: - static std::string Disassemble(u32 addr, u32 insn); - static Opcode Decode(u32 insn); +public: + static std::string Disassemble(u32 addr, u32 insn); + static Opcode Decode(u32 insn); - private: - static Opcode Decode00(u32 insn); - static Opcode Decode01(u32 insn); - static Opcode Decode10(u32 insn); - static Opcode Decode11(u32 insn); - static Opcode DecodeSyncPrimitive(u32 insn); - static Opcode DecodeParallelAddSub(u32 insn); - static Opcode DecodePackingSaturationReversal(u32 insn); - static Opcode DecodeMUL(u32 insn); - static Opcode DecodeMSRImmAndHints(u32 insn); - static Opcode DecodeMediaMulDiv(u32 insn); - static Opcode DecodeMedia(u32 insn); - static Opcode DecodeLDRH(u32 insn); - static Opcode DecodeALU(u32 insn); +private: + static Opcode Decode00(u32 insn); + static Opcode Decode01(u32 insn); + static Opcode Decode10(u32 insn); + static Opcode Decode11(u32 insn); + static Opcode DecodeSyncPrimitive(u32 insn); + static Opcode DecodeParallelAddSub(u32 insn); + static Opcode DecodePackingSaturationReversal(u32 insn); + static Opcode DecodeMUL(u32 insn); + static Opcode DecodeMSRImmAndHints(u32 insn); + static Opcode DecodeMediaMulDiv(u32 insn); + static Opcode DecodeMedia(u32 insn); + static Opcode DecodeLDRH(u32 insn); + static Opcode DecodeALU(u32 insn); - static std::string DisassembleALU(Opcode opcode, u32 insn); - static std::string DisassembleBranch(u32 addr, Opcode opcode, u32 insn); - static std::string DisassembleBX(u32 insn); - static std::string DisassembleBKPT(u32 insn); - static std::string DisassembleCLZ(u32 insn); - static std::string DisassembleMediaMulDiv(Opcode opcode, u32 insn); - static std::string DisassembleMemblock(Opcode opcode, u32 insn); - static std::string DisassembleMem(u32 insn); - static std::string DisassembleMemHalf(u32 insn); - static std::string DisassembleMCR(Opcode opcode, u32 insn); - static std::string DisassembleMLA(Opcode opcode, u32 insn); - static std::string DisassembleUMLAL(Opcode opcode, u32 insn); - static std::string DisassembleMUL(Opcode opcode, u32 insn); - static std::string DisassembleMRS(u32 insn); - static std::string DisassembleMSR(u32 insn); - static std::string DisassembleNoOperands(Opcode opcode, u32 insn); - static std::string DisassembleParallelAddSub(Opcode opcode, u32 insn); - static std::string DisassemblePKH(u32 insn); - static std::string DisassemblePLD(u32 insn); - static std::string DisassembleREV(Opcode opcode, u32 insn); - static std::string DisassembleREX(Opcode opcode, u32 insn); - static std::string DisassembleSAT(Opcode opcode, u32 insn); - static std::string DisassembleSEL(u32 insn); - static std::string DisassembleSWI(u32 insn); - static std::string DisassembleSWP(Opcode opcode, u32 insn); - static std::string DisassembleXT(Opcode opcode, u32 insn); + static std::string DisassembleALU(Opcode opcode, u32 insn); + static std::string DisassembleBranch(u32 addr, Opcode opcode, u32 insn); + static std::string DisassembleBX(u32 insn); + static std::string DisassembleBKPT(u32 insn); + static std::string DisassembleCLZ(u32 insn); + static std::string DisassembleMediaMulDiv(Opcode opcode, u32 insn); + static std::string DisassembleMemblock(Opcode opcode, u32 insn); + static std::string DisassembleMem(u32 insn); + static std::string DisassembleMemHalf(u32 insn); + static std::string DisassembleMCR(Opcode opcode, u32 insn); + static std::string DisassembleMLA(Opcode opcode, u32 insn); + static std::string DisassembleUMLAL(Opcode opcode, u32 insn); + static std::string DisassembleMUL(Opcode opcode, u32 insn); + static std::string DisassembleMRS(u32 insn); + static std::string DisassembleMSR(u32 insn); + static std::string DisassembleNoOperands(Opcode opcode, u32 insn); + static std::string DisassembleParallelAddSub(Opcode opcode, u32 insn); + static std::string DisassemblePKH(u32 insn); + static std::string DisassemblePLD(u32 insn); + static std::string DisassembleREV(Opcode opcode, u32 insn); + static std::string DisassembleREX(Opcode opcode, u32 insn); + static std::string DisassembleSAT(Opcode opcode, u32 insn); + static std::string DisassembleSEL(u32 insn); + static std::string DisassembleSWI(u32 insn); + static std::string DisassembleSWP(Opcode opcode, u32 insn); + static std::string DisassembleXT(Opcode opcode, u32 insn); }; diff --git a/src/core/arm/disassembler/load_symbol_map.cpp b/src/core/arm/disassembler/load_symbol_map.cpp index eb20bf6f7..58e8e6fa1 100644 --- a/src/core/arm/disassembler/load_symbol_map.cpp +++ b/src/core/arm/disassembler/load_symbol_map.cpp @@ -6,8 +6,8 @@ #include <string> #include <vector> -#include "common/symbols.h" #include "common/file_util.h" +#include "common/symbols.h" #include "core/arm/disassembler/load_symbol_map.h" |