diff options
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 1344 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.h | 238 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 7 | 
4 files changed, 2 insertions, 1589 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 190dc985a..e404063f0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,5 +1,4 @@  set(SRCS -            arm/disassembler/arm_disasm.cpp              arm/dynarmic/arm_dynarmic.cpp              arm/dynarmic/arm_dynarmic_cp15.cpp              arm/dyncom/arm_dyncom.cpp @@ -178,7 +177,6 @@ set(SRCS  set(HEADERS              arm/arm_interface.h -            arm/disassembler/arm_disasm.h              arm/dynarmic/arm_dynarmic.h              arm/dynarmic/arm_dynarmic_cp15.h              arm/dyncom/arm_dyncom.h diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp deleted file mode 100644 index 05d6ed1fb..000000000 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ /dev/null @@ -1,1344 +0,0 @@ -// Copyright 2006 The Android Open Source Project - -#include <string> -#include <unordered_set> -#include "common/common_types.h" -#include "common/string_util.h" -#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", -    "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}; - -// Indexed by the shift type (bits 6-5) -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) { -    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"; -    } -    return nullptr; -} - -std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) { -    static const u8 kNoOperand1 = 1; -    static const u8 kNoDest = 2; -    static const u8 kNoSbit = 4; - -    std::string rn_str; -    std::string rd_str; - -    u8 flags = 0; -    u8 cond = (insn >> 28) & 0xf; -    u8 is_immed = (insn >> 25) & 0x1; -    u8 bit_s = (insn >> 20) & 1; -    u8 rn = (insn >> 16) & 0xf; -    u8 rd = (insn >> 12) & 0xf; -    u8 immed = insn & 0xff; - -    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; -    } - -    // The "mov" instruction ignores the first operand (rn). -    rn_str[0] = 0; -    if ((flags & kNoOperand1) == 0) { -        rn_str = Common::StringFromFormat("r%d, ", rn); -    } - -    // The following instructions do not write the result register (rd): -    // tst, teq, cmp, cmn. -    rd_str[0] = 0; -    if ((flags & kNoDest) == 0) { -        rd_str = Common::StringFromFormat("r%d, ", rd); -    } - -    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); -    } - -    u8 shift_is_reg = (insn >> 4) & 1; -    u8 rotate = (insn >> 8) & 0xf; -    u8 rm = insn & 0xf; -    u8 shift_type = (insn >> 5) & 0x3; -    u8 rs = (insn >> 8) & 0xf; -    u8 shift_amount = (insn >> 7) & 0x1f; -    u32 rotated_val = immed; -    u8 rotate2 = rotate << 1; -    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); -    } - -    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); -    } -    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); -        } -        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); -} - -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 -    if ((offset >> 23) & 1) -        offset |= 0xff000000; - -    // Pre-compute the left-shift and the prefetch offset -    offset <<= 2; -    offset += 8; -    addr += offset; -    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) { -    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) { -    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) { -    u8 cond = (insn >> 28) & 0xf; -    u8 rd = (insn >> 12) & 0xf; -    u8 rm = insn & 0xf; -    return Common::StringFromFormat("clz%s\tr%d, r%d", cond_to_str(cond), rd, rm); -} - -std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, u32 insn) { -    u32 cond = BITS(insn, 28, 31); -    u32 rd = BITS(insn, 16, 19); -    u32 ra = BITS(insn, 12, 15); -    u32 rm = BITS(insn, 8, 11); -    u32 m = BIT(insn, 5); -    u32 rn = BITS(insn, 0, 3); - -    std::string cross = ""; -    if (m) { -        if (opcode == OP_SMMLA || opcode == OP_SMMUL || opcode == OP_SMMLS) -            cross = "r"; -        else -            cross = "x"; -    } - -    std::string ext_reg = ""; -    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); - -    std::string rd_low = ""; -    if (opcode == OP_SMLALD || opcode == OP_SMLSLD) -        rd_low = Common::StringFromFormat("r%u, ", ra); - -    return Common::StringFromFormat("%s%s%s\t%sr%u, r%u, r%u%s", opcode_names[opcode], -                                    cross.c_str(), cond_to_str(cond), rd_low.c_str(), rd, rn, rm, -                                    ext_reg.c_str()); -} - -std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) { -    std::string tmp_list; - -    u8 cond = (insn >> 28) & 0xf; -    u8 write_back = (insn >> 21) & 0x1; -    u8 bit_s = (insn >> 22) & 0x1; -    u8 is_up = (insn >> 23) & 0x1; -    u8 is_pre = (insn >> 24) & 0x1; -    u8 rn = (insn >> 16) & 0xf; -    u16 reg_list = insn & 0xffff; - -    const char* opname = opcode_names[opcode]; - -    const char* bang = ""; -    if (write_back) -        bang = "!"; - -    const char* carret = ""; -    if (bit_s) -        carret = "^"; - -    const char* comma = ""; -    tmp_list[0] = 0; -    for (int ii = 0; ii < 16; ++ii) { -        if (reg_list & (1 << ii)) { -            tmp_list += Common::StringFromFormat("%sr%d", comma, ii); -            comma = ","; -        } -    } - -    const char* addr_mode = ""; -    if (is_pre) { -        if (is_up) { -            addr_mode = "ib"; -        } else { -            addr_mode = "db"; -        } -    } else { -        if (is_up) { -            addr_mode = "ia"; -        } else { -            addr_mode = "da"; -        } -    } - -    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) { -    u8 cond = (insn >> 28) & 0xf; -    u8 is_reg = (insn >> 25) & 0x1; -    u8 is_load = (insn >> 20) & 0x1; -    u8 write_back = (insn >> 21) & 0x1; -    u8 is_byte = (insn >> 22) & 0x1; -    u8 is_up = (insn >> 23) & 0x1; -    u8 is_pre = (insn >> 24) & 0x1; -    u8 rn = (insn >> 16) & 0xf; -    u8 rd = (insn >> 12) & 0xf; -    u16 offset = insn & 0xfff; - -    const char* opname = "ldr"; -    if (!is_load) -        opname = "str"; - -    const char* bang = ""; -    if (write_back) -        bang = "!"; - -    const char* minus = ""; -    if (is_up == 0) -        minus = "-"; - -    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); -            } 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); -            } -        } else { -            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); -        } -    } - -    u8 rm = insn & 0xf; -    u8 shift_type = (insn >> 5) & 0x3; -    u8 shift_amount = (insn >> 7) & 0x1f; - -    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); -            } -            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); -            } -            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); -    } - -    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); -        } -        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); -        } -        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); -} - -std::string ARM_Disasm::DisassembleMemHalf(u32 insn) { -    u8 cond = (insn >> 28) & 0xf; -    u8 is_load = (insn >> 20) & 0x1; -    u8 write_back = (insn >> 21) & 0x1; -    u8 is_immed = (insn >> 22) & 0x1; -    u8 is_up = (insn >> 23) & 0x1; -    u8 is_pre = (insn >> 24) & 0x1; -    u8 rn = (insn >> 16) & 0xf; -    u8 rd = (insn >> 12) & 0xf; -    u8 bits_65 = (insn >> 5) & 0x3; -    u8 rm = insn & 0xf; -    u8 offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf); - -    const char* opname = "ldr"; -    if (is_load == 0) -        opname = "str"; - -    const char* width = ""; -    if (bits_65 == 1) -        width = "h"; -    else if (bits_65 == 2) -        width = "sb"; -    else -        width = "sh"; - -    const char* bang = ""; -    if (write_back) -        bang = "!"; -    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); -            } 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); -            } -        } else { -            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); -    } else { -        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) { -    u8 cond = (insn >> 28) & 0xf; -    u8 crn = (insn >> 16) & 0xf; -    u8 crd = (insn >> 12) & 0xf; -    u8 cpnum = (insn >> 8) & 0xf; -    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); -} - -std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) { -    u8 cond = (insn >> 28) & 0xf; -    u8 rd = (insn >> 16) & 0xf; -    u8 rn = (insn >> 12) & 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, r%d", opname, cond_to_str(cond), -                                    bit_s ? "s" : "", rd, rm, rs, rn); -} - -std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) { -    u8 cond = (insn >> 28) & 0xf; -    u8 rdhi = (insn >> 16) & 0xf; -    u8 rdlo = (insn >> 12) & 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, r%d", opname, cond_to_str(cond), -                                    bit_s ? "s" : "", rdlo, rdhi, rm, rs); -} - -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); -} - -std::string ARM_Disasm::DisassembleMRS(u32 insn) { -    u8 cond = (insn >> 28) & 0xf; -    u8 rd = (insn >> 12) & 0xf; -    u8 ps = (insn >> 22) & 1; - -    return Common::StringFromFormat("mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr"); -} - -std::string ARM_Disasm::DisassembleMSR(u32 insn) { -    char flags[8]; -    int flag_index = 0; -    u8 cond = (insn >> 28) & 0xf; -    u8 is_immed = (insn >> 25) & 0x1; -    u8 pd = (insn >> 22) & 1; -    u8 mask = (insn >> 16) & 0xf; - -    if (mask & 1) -        flags[flag_index++] = 'c'; -    if (mask & 2) -        flags[flag_index++] = 'x'; -    if (mask & 4) -        flags[flag_index++] = 's'; -    if (mask & 8) -        flags[flag_index++] = 'f'; -    flags[flag_index] = 0; - -    if (is_immed) { -        u32 immed = insn & 0xff; -        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); -    } - -    u8 rm = insn & 0xf; - -    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) { -    u32 cond = BITS(insn, 28, 31); -    return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); -} - -std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, u32 insn) { -    u32 cond = BITS(insn, 28, 31); -    u32 rn = BITS(insn, 16, 19); -    u32 rd = BITS(insn, 12, 15); -    u32 rm = BITS(insn, 0, 3); - -    return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[opcode], cond_to_str(cond), -                                    rd, rn, rm); -} - -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); -    u32 imm5 = BITS(insn, 7, 11); -    u32 tb = BIT(insn, 6); -    u32 rm = BITS(insn, 0, 3); - -    std::string suffix = tb ? "tb" : "bt"; -    std::string shift = ""; - -    if (tb && imm5 == 0) -        imm5 = 32; - -    if (imm5 > 0) { -        shift = tb ? ", ASR" : ", LSL"; -        shift += " #" + std::to_string(imm5); -    } - -    return Common::StringFromFormat("pkh%s%s\tr%u, r%u, r%u%s", suffix.c_str(), cond_to_str(cond), -                                    rd, rn, rm, shift.c_str()); -} - -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 = ""; -    if (is_up == 0) -        minus = "-"; - -    if (is_reg) { -        u8 rm = insn & 0xf; -        return Common::StringFromFormat("pld\t[r%d, %sr%d]", rn, minus, rm); -    } - -    u16 offset = insn & 0xfff; -    if (offset == 0) { -        return Common::StringFromFormat("pld\t[r%d]", rn); -    } else { -        return Common::StringFromFormat("pld\t[r%d, #%s%u]", rn, minus, offset); -    } -} - -std::string ARM_Disasm::DisassembleREV(Opcode opcode, u32 insn) { -    u32 cond = BITS(insn, 28, 31); -    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); -} - -std::string ARM_Disasm::DisassembleREX(Opcode opcode, u32 insn) { -    u32 rn = BITS(insn, 16, 19); -    u32 rd = BITS(insn, 12, 15); -    u32 rt = BITS(insn, 0, 3); -    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]; -    } -} - -std::string ARM_Disasm::DisassembleSAT(Opcode opcode, u32 insn) { -    u32 cond = BITS(insn, 28, 31); -    u32 sat_imm = BITS(insn, 16, 20); -    u32 rd = BITS(insn, 12, 15); -    u32 imm5 = BITS(insn, 7, 11); -    u32 sh = BIT(insn, 6); -    u32 rn = BITS(insn, 0, 3); - -    std::string shift_part = ""; -    bool opcode_has_shift = (opcode == OP_SSAT) || (opcode == OP_USAT); -    if (opcode_has_shift && !(sh == 0 && imm5 == 0)) { -        if (sh == 0) -            shift_part += ", LSL #"; -        else -            shift_part += ", ASR #"; - -        if (imm5 == 0) -            imm5 = 32; -        shift_part += std::to_string(imm5); -    } - -    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()); -} - -std::string ARM_Disasm::DisassembleSEL(u32 insn) { -    u32 cond = BITS(insn, 28, 31); -    u32 rn = BITS(insn, 16, 19); -    u32 rd = BITS(insn, 12, 15); -    u32 rm = BITS(insn, 0, 3); - -    return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[OP_SEL], cond_to_str(cond), -                                    rd, rn, rm); -} - -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) { -    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]; -    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) { -    u32 cond = BITS(insn, 28, 31); -    u32 rn = BITS(insn, 16, 19); -    u32 rd = BITS(insn, 12, 15); -    u32 rotate = BITS(insn, 10, 11); -    u32 rm = BITS(insn, 0, 3); - -    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}; -    if (extend_with_add.find(opcode) != extend_with_add.end()) -        rn_part = ", r" + std::to_string(rn); - -    std::string rotate_part = ""; -    if (rotate != 0) -        rotate_part = ", ROR #" + std::to_string(rotate << 3); - -    return Common::StringFromFormat("%s%s\tr%u%s, r%u%s", opcode_names[opcode], cond_to_str(cond), -                                    rd, rn_part.c_str(), rm, rotate_part.c_str()); -} - -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); -    } -    return OP_INVALID; -} - -Opcode ARM_Disasm::Decode00(u32 insn) { -    u8 bit25 = (insn >> 25) & 0x1; -    u8 bit4 = (insn >> 4) & 0x1; -    if (bit25 == 0 && bit4 == 1) { -        if ((insn & 0x0ffffff0) == 0x012fff10) { -            // Bx instruction -            return OP_BX; -        } -        if ((insn & 0x0ff000f0) == 0x01600010) { -            // Clz instruction -            return OP_CLZ; -        } -        if ((insn & 0xfff000f0) == 0xe1200070) { -            // Bkpt instruction -            return OP_BKPT; -        } -        u32 bits7_4 = (insn >> 4) & 0xf; -        if (bits7_4 == 0x9) { -            u32 bit24 = BIT(insn, 24); -            if (bit24) { -                return DecodeSyncPrimitive(insn); -            } -            // One of the multiply instructions -            return DecodeMUL(insn); -        } - -        u8 bit7 = (insn >> 7) & 0x1; -        if (bit7 == 1) { -            // One of the load/store halfword/byte instructions -            return DecodeLDRH(insn); -        } -    } - -    u32 op1 = BITS(insn, 20, 24); -    if (bit25 && (op1 == 0x12 || op1 == 0x16)) { -        // One of the MSR (immediate) and hints instructions -        return DecodeMSRImmAndHints(insn); -    } - -    // One of the data processing instructions -    return DecodeALU(insn); -} - -Opcode ARM_Disasm::Decode01(u32 insn) { -    u8 is_reg = (insn >> 25) & 0x1; -    u8 bit4 = (insn >> 4) & 0x1; -    if (is_reg == 1 && bit4 == 1) -        return DecodeMedia(insn); -    u8 is_load = (insn >> 20) & 0x1; -    u8 is_byte = (insn >> 22) & 0x1; -    if ((insn & 0xfd70f000) == 0xf550f000) { -        // Pre-load -        return OP_PLD; -    } -    if (insn == 0xf57ff01f) { -        // Clear-Exclusive -        return OP_CLREX; -    } -    if (is_load) { -        if (is_byte) { -            // Load byte -            return OP_LDRB; -        } -        // Load word -        return OP_LDR; -    } -    if (is_byte) { -        // Store byte -        return OP_STRB; -    } -    // Store word -    return OP_STR; -} - -Opcode ARM_Disasm::Decode10(u32 insn) { -    u8 bit25 = (insn >> 25) & 0x1; -    if (bit25 == 0) { -        // LDM/STM -        u8 is_load = (insn >> 20) & 0x1; -        if (is_load) -            return OP_LDM; -        return OP_STM; -    } - -    // Branch with link -    if ((insn >> 24) & 1) -        return OP_BL; - -    return OP_B; -} - -Opcode ARM_Disasm::Decode11(u32 insn) { -    u8 bit25 = (insn >> 25) & 0x1; -    if (bit25 == 0) { -        // LDC, SDC -        u8 is_load = (insn >> 20) & 0x1; -        if (is_load) { -            // LDC -            return OP_LDC; -        } -        // STC -        return OP_STC; -    } - -    u8 bit24 = (insn >> 24) & 0x1; -    if (bit24 == 0x1) { -        // SWI -        return OP_SWI; -    } - -    u8 bit4 = (insn >> 4) & 0x1; -    u8 cpnum = (insn >> 8) & 0xf; - -    if (cpnum == 15) { -        // Special case for coprocessor 15 -        u8 opcode = (insn >> 21) & 0x7; -        if (bit4 == 0 || opcode != 0) { -            // This is an unexpected bit pattern.  Create an undefined -            // instruction in case this is ever executed. -            return OP_UNDEFINED; -        } - -        // MRC, MCR -        u8 is_mrc = (insn >> 20) & 0x1; -        if (is_mrc) -            return OP_MRC; -        return OP_MCR; -    } - -    if (bit4 == 0) { -        // CDP -        return OP_CDP; -    } -    // MRC, MCR -    u8 is_mrc = (insn >> 20) & 0x1; -    if (is_mrc) -        return OP_MRC; -    return OP_MCR; -} - -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; -    } -} - -Opcode ARM_Disasm::DecodeParallelAddSub(u32 insn) { -    u32 op1 = BITS(insn, 20, 21); -    u32 op2 = BITS(insn, 5, 7); -    u32 is_unsigned = BIT(insn, 22); - -    if (op1 == 0x0 || op2 == 0x5 || op2 == 0x6) -        return OP_UNDEFINED; - -    // change op1 range from [1, 3] to range [0, 2] -    op1--; - -    // change op2 range from [0, 4] U {7} to range [0, 5] -    if (op2 == 0x7) -        op2 = 0x5; - -    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, -        // 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, -        // 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}; - -    u32 opcode_index = op1 * 12 + op2 * 2 + is_unsigned; -    return opcodes[opcode_index]; -} - -Opcode ARM_Disasm::DecodePackingSaturationReversal(u32 insn) { -    u32 op1 = BITS(insn, 20, 22); -    u32 a = BITS(insn, 16, 19); -    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; -    } - -    return OP_UNDEFINED; -} - -Opcode ARM_Disasm::DecodeMUL(u32 insn) { -    u8 bit24 = (insn >> 24) & 0x1; -    if (bit24 != 0) { -        // This is an unexpected bit pattern.  Create an undefined -        // instruction in case this is ever executed. -        return OP_UNDEFINED; -    } -    u8 bit23 = (insn >> 23) & 0x1; -    u8 bit22_U = (insn >> 22) & 0x1; -    u8 bit21_A = (insn >> 21) & 0x1; -    if (bit23 == 0) { -        // 32-bit multiply -        if (bit22_U != 0) { -            // This is an unexpected bit pattern.  Create an undefined -            // instruction in case this is ever executed. -            return OP_UNDEFINED; -        } -        if (bit21_A == 0) -            return OP_MUL; -        return OP_MLA; -    } -    // 64-bit multiply -    if (bit22_U == 0) { -        // Unsigned multiply long -        if (bit21_A == 0) -            return OP_UMULL; -        return OP_UMLAL; -    } -    // Signed multiply long -    if (bit21_A == 0) -        return OP_SMULL; -    return OP_SMLAL; -} - -Opcode ARM_Disasm::DecodeMSRImmAndHints(u32 insn) { -    u32 op = BIT(insn, 22); -    u32 op1 = BITS(insn, 16, 19); -    u32 op2 = BITS(insn, 0, 7); - -    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; -        } -    } - -    return OP_MSR; -} - -Opcode ARM_Disasm::DecodeMediaMulDiv(u32 insn) { -    u32 op1 = BITS(insn, 20, 22); -    u32 op2_h = BITS(insn, 6, 7); -    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; -    } - -    return OP_UNDEFINED; -} - -Opcode ARM_Disasm::DecodeMedia(u32 insn) { -    u32 op1 = BITS(insn, 20, 24); -    u32 rd = BITS(insn, 12, 15); -    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; -    } - -    return OP_UNDEFINED; -} - -Opcode ARM_Disasm::DecodeLDRH(u32 insn) { -    u8 is_load = (insn >> 20) & 0x1; -    u8 bits_65 = (insn >> 5) & 0x3; -    if (is_load) { -        if (bits_65 == 0x1) { -            // Load unsigned halfword -            return OP_LDRH; -        } else if (bits_65 == 0x2) { -            // Load signed byte -            return OP_LDRSB; -        } -        // Signed halfword -        if (bits_65 != 0x3) { -            // This is an unexpected bit pattern.  Create an undefined -            // instruction in case this is ever executed. -            return OP_UNDEFINED; -        } -        // Load signed halfword -        return OP_LDRSH; -    } -    // Store halfword -    if (bits_65 != 0x1) { -        // This is an unexpected bit pattern.  Create an undefined -        // instruction in case this is ever executed. -        return OP_UNDEFINED; -    } -    // Store halfword -    return OP_STRH; -} - -Opcode ARM_Disasm::DecodeALU(u32 insn) { -    u8 is_immed = (insn >> 25) & 0x1; -    u8 opcode = (insn >> 21) & 0xf; -    u8 bit_s = (insn >> 20) & 1; -    u8 shift_is_reg = (insn >> 4) & 1; -    u8 bit7 = (insn >> 7) & 1; -    if (!is_immed && shift_is_reg && (bit7 != 0)) { -        // This is an unexpected bit pattern.  Create an undefined -        // instruction in case this is ever executed. -        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; -    } -    // Unreachable -    return OP_INVALID; -} diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h deleted file mode 100644 index 300e228ed..000000000 --- a/src/core/arm/disassembler/arm_disasm.h +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2006 The Android Open Source Project - -#pragma once - -#include <string> -#include "common/common_types.h" - -// Note: this list of opcodes must match the list used to initialize -// the opflags[] array in opcode.cpp. -enum Opcode { -    OP_INVALID, -    OP_UNDEFINED, -    OP_ADC, -    OP_ADD, -    OP_AND, -    OP_B, -    OP_BL, -    OP_BIC, -    OP_BKPT, -    OP_BLX, -    OP_BX, -    OP_CDP, -    OP_CLREX, -    OP_CLZ, -    OP_CMN, -    OP_CMP, -    OP_EOR, -    OP_LDC, -    OP_LDM, -    OP_LDR, -    OP_LDRB, -    OP_LDRBT, -    OP_LDREX, -    OP_LDREXB, -    OP_LDREXD, -    OP_LDREXH, -    OP_LDRH, -    OP_LDRSB, -    OP_LDRSH, -    OP_LDRT, -    OP_MCR, -    OP_MLA, -    OP_MOV, -    OP_MRC, -    OP_MRS, -    OP_MSR, -    OP_MUL, -    OP_MVN, -    OP_NOP, -    OP_ORR, -    OP_PKH, -    OP_PLD, -    OP_QADD16, -    OP_QADD8, -    OP_QASX, -    OP_QSAX, -    OP_QSUB16, -    OP_QSUB8, -    OP_REV, -    OP_REV16, -    OP_REVSH, -    OP_RSB, -    OP_RSC, -    OP_SADD16, -    OP_SADD8, -    OP_SASX, -    OP_SBC, -    OP_SEL, -    OP_SEV, -    OP_SHADD16, -    OP_SHADD8, -    OP_SHASX, -    OP_SHSAX, -    OP_SHSUB16, -    OP_SHSUB8, -    OP_SMLAD, -    OP_SMLAL, -    OP_SMLALD, -    OP_SMLSD, -    OP_SMLSLD, -    OP_SMMLA, -    OP_SMMLS, -    OP_SMMUL, -    OP_SMUAD, -    OP_SMULL, -    OP_SMUSD, -    OP_SSAT, -    OP_SSAT16, -    OP_SSAX, -    OP_SSUB16, -    OP_SSUB8, -    OP_STC, -    OP_STM, -    OP_STR, -    OP_STRB, -    OP_STRBT, -    OP_STREX, -    OP_STREXB, -    OP_STREXD, -    OP_STREXH, -    OP_STRH, -    OP_STRT, -    OP_SUB, -    OP_SWI, -    OP_SWP, -    OP_SWPB, -    OP_SXTAB, -    OP_SXTAB16, -    OP_SXTAH, -    OP_SXTB, -    OP_SXTB16, -    OP_SXTH, -    OP_TEQ, -    OP_TST, -    OP_UADD16, -    OP_UADD8, -    OP_UASX, -    OP_UHADD16, -    OP_UHADD8, -    OP_UHASX, -    OP_UHSAX, -    OP_UHSUB16, -    OP_UHSUB8, -    OP_UMLAL, -    OP_UMULL, -    OP_UQADD16, -    OP_UQADD8, -    OP_UQASX, -    OP_UQSAX, -    OP_UQSUB16, -    OP_UQSUB8, -    OP_USAD8, -    OP_USADA8, -    OP_USAT, -    OP_USAT16, -    OP_USAX, -    OP_USUB16, -    OP_USUB8, -    OP_UXTAB, -    OP_UXTAB16, -    OP_UXTAH, -    OP_UXTB, -    OP_UXTB16, -    OP_UXTH, -    OP_WFE, -    OP_WFI, -    OP_YIELD, - -    // Define thumb opcodes -    OP_THUMB_UNDEFINED, -    OP_THUMB_ADC, -    OP_THUMB_ADD, -    OP_THUMB_AND, -    OP_THUMB_ASR, -    OP_THUMB_B, -    OP_THUMB_BIC, -    OP_THUMB_BKPT, -    OP_THUMB_BL, -    OP_THUMB_BLX, -    OP_THUMB_BX, -    OP_THUMB_CMN, -    OP_THUMB_CMP, -    OP_THUMB_EOR, -    OP_THUMB_LDMIA, -    OP_THUMB_LDR, -    OP_THUMB_LDRB, -    OP_THUMB_LDRH, -    OP_THUMB_LDRSB, -    OP_THUMB_LDRSH, -    OP_THUMB_LSL, -    OP_THUMB_LSR, -    OP_THUMB_MOV, -    OP_THUMB_MUL, -    OP_THUMB_MVN, -    OP_THUMB_NEG, -    OP_THUMB_ORR, -    OP_THUMB_POP, -    OP_THUMB_PUSH, -    OP_THUMB_ROR, -    OP_THUMB_SBC, -    OP_THUMB_STMIA, -    OP_THUMB_STR, -    OP_THUMB_STRB, -    OP_THUMB_STRH, -    OP_THUMB_SUB, -    OP_THUMB_SWI, -    OP_THUMB_TST, - -    OP_END // must be last -}; - -class ARM_Disasm { -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); - -    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/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 8073bb705..f4fbb8d04 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -10,7 +10,6 @@  #include "common/common_types.h"  #include "common/logging/log.h"  #include "common/microprofile.h" -#include "core/arm/disassembler/arm_disasm.h"  #include "core/arm/dyncom/arm_dyncom_dec.h"  #include "core/arm/dyncom/arm_dyncom_interpreter.h"  #include "core/arm/dyncom/arm_dyncom_run.h" @@ -828,10 +827,8 @@ static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, cons      int idx;      if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) { -        std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); -        LOG_ERROR(Core_ARM11, -                  "Decode failure.\tPC: [0x%08" PRIX32 "]\tInstruction: %s [%08" PRIX32 "]", -                  phys_addr, disasm.c_str(), inst); +        LOG_ERROR(Core_ARM11, "Decode failure.\tPC: [0x%08" PRIX32 "]\tInstruction: %08" PRIX32, +                  phys_addr, inst);          LOG_ERROR(Core_ARM11, "cpsr=0x%" PRIX32 ", cpu->TFlag=%d, r15=0x%08" PRIX32, cpu->Cpsr,                    cpu->TFlag, cpu->Reg[15]);          CITRA_IGNORE_EXIT(-1);  | 
