From 672ffb93d06be04961a27e5086c8af2ce1e1d30b Mon Sep 17 00:00:00 2001 From: MerryMage Date: Thu, 14 Jul 2016 13:28:20 +0100 Subject: [PATCH] frontend/translator: Skeleton for Arm translator --- src/frontend/decoder/arm.h | 446 ++++++++++++++-------------- src/frontend/translate_arm.cpp | 51 +++- src/frontend/translate_thumb.cpp | 44 ++- tests/arm/test_arm_disassembler.cpp | 4 +- 4 files changed, 308 insertions(+), 237 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index 79088bdb..6f5d8256 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -59,284 +59,284 @@ private: }; template -static const std::array, 221> g_arm_instruction_table = {{ +static const std::array, 1> g_arm_instruction_table = { #define INST(fn, name, bitstring) detail::detail::GetMatcher(name, bitstring) // Branch instructions - { INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv") }, // v5 - { INST(&V::arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm") }, // v5 - { INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv") }, // all - { INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv") }, // all - { INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm") }, // v4T - { INST(&V::arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm") }, // v5J + //INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv"), // v5 + //INST(&V::arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm"), // v5 + //INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv"), // all + //INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv"), // all + //INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm"), // v4T + //INST(&V::arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm"), // v5J // Coprocessor instructions - { INST(&V::arm_CDP, "CDP2", "11111110-------------------1----") }, // v5 - { INST(&V::arm_CDP, "CDP", "----1110-------------------0----") }, // v2 - { INST(&V::arm_LDC, "LDC2", "1111110----1--------------------") }, // v5 - { INST(&V::arm_LDC, "LDC", "----110----1--------------------") }, // v2 - { INST(&V::arm_MCR, "MCR2", "----1110---0---------------1----") }, // v5 - { INST(&V::arm_MCR, "MCR", "----1110---0---------------1----") }, // v2 - { INST(&V::arm_MCRR, "MCRR2", "111111000100--------------------") }, // v6 - { INST(&V::arm_MCRR, "MCRR", "----11000100--------------------") }, // v5E - { INST(&V::arm_MRC, "MRC2", "11111110---1---------------1----") }, // v5 - { INST(&V::arm_MRC, "MRC", "----1110---1---------------1----") }, // v2 - { INST(&V::arm_MRRC, "MRRC2", "111111000101--------------------") }, // v6 - { INST(&V::arm_MRRC, "MRRC", "----11000101--------------------") }, // v5E - { INST(&V::arm_STC, "STC2", "1111110----0--------------------") }, // v5 - { INST(&V::arm_STC, "STC", "----110----0--------------------") }, // v2 + //INST(&V::arm_CDP, "CDP2", "11111110-------------------1----"), // v5 + //INST(&V::arm_CDP, "CDP", "----1110-------------------0----"), // v2 + //INST(&V::arm_LDC, "LDC2", "1111110----1--------------------"), // v5 + //INST(&V::arm_LDC, "LDC", "----110----1--------------------"), // v2 + //INST(&V::arm_MCR, "MCR2", "----1110---0---------------1----"), // v5 + //INST(&V::arm_MCR, "MCR", "----1110---0---------------1----"), // v2 + //INST(&V::arm_MCRR, "MCRR2", "111111000100--------------------"), // v6 + //INST(&V::arm_MCRR, "MCRR", "----11000100--------------------"), // v5E + //INST(&V::arm_MRC, "MRC2", "11111110---1---------------1----"), // v5 + //INST(&V::arm_MRC, "MRC", "----1110---1---------------1----"), // v2 + //INST(&V::arm_MRRC, "MRRC2", "111111000101--------------------"), // v6 + //INST(&V::arm_MRRC, "MRRC", "----11000101--------------------"), // v5E + //INST(&V::arm_STC, "STC2", "1111110----0--------------------"), // v5 + //INST(&V::arm_STC, "STC", "----110----0--------------------"), // v2 // Data Processing instructions - { INST(&V::arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_ADC_reg, "ADC (reg)", "cccc0000101Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_ADC_rsr, "ADC (rsr)", "cccc0000101Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_ADD_imm, "ADD (imm)", "cccc0010100Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_ADD_reg, "ADD (reg)", "cccc0000100Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_ADD_rsr, "ADD (rsr)", "cccc0000100Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_AND_imm, "AND (imm)", "cccc0010000Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_AND_reg, "AND (reg)", "cccc0000000Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_AND_rsr, "AND (rsr)", "cccc0000000Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_BIC_imm, "BIC (imm)", "cccc0011110Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_BIC_reg, "BIC (reg)", "cccc0001110Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_BIC_rsr, "BIC (rsr)", "cccc0001110Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_CMN_imm, "CMN (imm)", "cccc00110111nnnn0000rrrrvvvvvvvv") }, // all - { INST(&V::arm_CMN_reg, "CMN (reg)", "cccc00010111nnnn0000vvvvvrr0mmmm") }, // all - { INST(&V::arm_CMN_rsr, "CMN (rsr)", "cccc00010111nnnn0000ssss0rr1mmmm") }, // all - { INST(&V::arm_CMP_imm, "CMP (imm)", "cccc00110101nnnn0000rrrrvvvvvvvv") }, // all - { INST(&V::arm_CMP_reg, "CMP (reg)", "cccc00010101nnnn0000vvvvvrr0mmmm") }, // all - { INST(&V::arm_CMP_rsr, "CMP (rsr)", "cccc00010101nnnn0000ssss0rr1mmmm") }, // all - { INST(&V::arm_EOR_imm, "EOR (imm)", "cccc0010001Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_EOR_reg, "EOR (reg)", "cccc0000001Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_EOR_rsr, "EOR (rsr)", "cccc0000001Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_MOV_imm, "MOV (imm)", "cccc0011101S0000ddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_MOV_reg, "MOV (reg)", "cccc0001101S0000ddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_MOV_rsr, "MOV (rsr)", "cccc0001101S0000ddddssss0rr1mmmm") }, // all - { INST(&V::arm_MVN_imm, "MVN (imm)", "cccc0011111S0000ddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_MVN_reg, "MVN (reg)", "cccc0001111S0000ddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_MVN_rsr, "MVN (rsr)", "cccc0001111S0000ddddssss0rr1mmmm") }, // all - { INST(&V::arm_ORR_imm, "ORR (imm)", "cccc0011100Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_ORR_reg, "ORR (reg)", "cccc0001100Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_ORR_rsr, "ORR (rsr)", "cccc0001100Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_RSB_imm, "RSB (imm)", "cccc0010011Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_RSB_reg, "RSB (reg)", "cccc0000011Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_RSB_rsr, "RSB (rsr)", "cccc0000011Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_RSC_imm, "RSC (imm)", "cccc0010111Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_RSC_reg, "RSC (reg)", "cccc0000111Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_RSC_rsr, "RSC (rsr)", "cccc0000111Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_SBC_imm, "SBC (imm)", "cccc0010110Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_SBC_reg, "SBC (reg)", "cccc0000110Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_SBC_rsr, "SBC (rsr)", "cccc0000110Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_SUB_imm, "SUB (imm)", "cccc0010010Snnnnddddrrrrvvvvvvvv") }, // all - { INST(&V::arm_SUB_reg, "SUB (reg)", "cccc0000010Snnnnddddvvvvvrr0mmmm") }, // all - { INST(&V::arm_SUB_rsr, "SUB (rsr)", "cccc0000010Snnnnddddssss0rr1mmmm") }, // all - { INST(&V::arm_TEQ_imm, "TEQ (imm)", "cccc00110011nnnn0000rrrrvvvvvvvv") }, // all - { INST(&V::arm_TEQ_reg, "TEQ (reg)", "cccc00010011nnnn0000vvvvvrr0mmmm") }, // all - { INST(&V::arm_TEQ_rsr, "TEQ (rsr)", "cccc00010011nnnn0000ssss0rr1mmmm") }, // all - { INST(&V::arm_TST_imm, "TST (imm)", "cccc00110001nnnn0000rrrrvvvvvvvv") }, // all - { INST(&V::arm_TST_reg, "TST (reg)", "cccc00010001nnnn0000vvvvvrr0mmmm") }, // all - { INST(&V::arm_TST_rsr, "TST (rsr)", "cccc00010001nnnn0000ssss0rr1mmmm") }, // all + //INST(&V::arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_ADC_reg, "ADC (reg)", "cccc0000101Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_ADC_rsr, "ADC (rsr)", "cccc0000101Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_ADD_imm, "ADD (imm)", "cccc0010100Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_ADD_reg, "ADD (reg)", "cccc0000100Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_ADD_rsr, "ADD (rsr)", "cccc0000100Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_AND_imm, "AND (imm)", "cccc0010000Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_AND_reg, "AND (reg)", "cccc0000000Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_AND_rsr, "AND (rsr)", "cccc0000000Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_BIC_imm, "BIC (imm)", "cccc0011110Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_BIC_reg, "BIC (reg)", "cccc0001110Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_BIC_rsr, "BIC (rsr)", "cccc0001110Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_CMN_imm, "CMN (imm)", "cccc00110111nnnn0000rrrrvvvvvvvv"), // all + //INST(&V::arm_CMN_reg, "CMN (reg)", "cccc00010111nnnn0000vvvvvrr0mmmm"), // all + //INST(&V::arm_CMN_rsr, "CMN (rsr)", "cccc00010111nnnn0000ssss0rr1mmmm"), // all + //INST(&V::arm_CMP_imm, "CMP (imm)", "cccc00110101nnnn0000rrrrvvvvvvvv"), // all + //INST(&V::arm_CMP_reg, "CMP (reg)", "cccc00010101nnnn0000vvvvvrr0mmmm"), // all + //INST(&V::arm_CMP_rsr, "CMP (rsr)", "cccc00010101nnnn0000ssss0rr1mmmm"), // all + //INST(&V::arm_EOR_imm, "EOR (imm)", "cccc0010001Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_EOR_reg, "EOR (reg)", "cccc0000001Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_EOR_rsr, "EOR (rsr)", "cccc0000001Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_MOV_imm, "MOV (imm)", "cccc0011101S0000ddddrrrrvvvvvvvv"), // all + //INST(&V::arm_MOV_reg, "MOV (reg)", "cccc0001101S0000ddddvvvvvrr0mmmm"), // all + //INST(&V::arm_MOV_rsr, "MOV (rsr)", "cccc0001101S0000ddddssss0rr1mmmm"), // all + //INST(&V::arm_MVN_imm, "MVN (imm)", "cccc0011111S0000ddddrrrrvvvvvvvv"), // all + //INST(&V::arm_MVN_reg, "MVN (reg)", "cccc0001111S0000ddddvvvvvrr0mmmm"), // all + //INST(&V::arm_MVN_rsr, "MVN (rsr)", "cccc0001111S0000ddddssss0rr1mmmm"), // all + //INST(&V::arm_ORR_imm, "ORR (imm)", "cccc0011100Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_ORR_reg, "ORR (reg)", "cccc0001100Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_ORR_rsr, "ORR (rsr)", "cccc0001100Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_RSB_imm, "RSB (imm)", "cccc0010011Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_RSB_reg, "RSB (reg)", "cccc0000011Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_RSB_rsr, "RSB (rsr)", "cccc0000011Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_RSC_imm, "RSC (imm)", "cccc0010111Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_RSC_reg, "RSC (reg)", "cccc0000111Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_RSC_rsr, "RSC (rsr)", "cccc0000111Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_SBC_imm, "SBC (imm)", "cccc0010110Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_SBC_reg, "SBC (reg)", "cccc0000110Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_SBC_rsr, "SBC (rsr)", "cccc0000110Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_SUB_imm, "SUB (imm)", "cccc0010010Snnnnddddrrrrvvvvvvvv"), // all + //INST(&V::arm_SUB_reg, "SUB (reg)", "cccc0000010Snnnnddddvvvvvrr0mmmm"), // all + //INST(&V::arm_SUB_rsr, "SUB (rsr)", "cccc0000010Snnnnddddssss0rr1mmmm"), // all + //INST(&V::arm_TEQ_imm, "TEQ (imm)", "cccc00110011nnnn0000rrrrvvvvvvvv"), // all + //INST(&V::arm_TEQ_reg, "TEQ (reg)", "cccc00010011nnnn0000vvvvvrr0mmmm"), // all + //INST(&V::arm_TEQ_rsr, "TEQ (rsr)", "cccc00010011nnnn0000ssss0rr1mmmm"), // all + //INST(&V::arm_TST_imm, "TST (imm)", "cccc00110001nnnn0000rrrrvvvvvvvv"), // all + //INST(&V::arm_TST_reg, "TST (reg)", "cccc00010001nnnn0000vvvvvrr0mmmm"), // all + //INST(&V::arm_TST_rsr, "TST (rsr)", "cccc00010001nnnn0000ssss0rr1mmmm"), // all // Exception Generating instructions - { INST(&V::arm_BKPT, "BKPT", "cccc00010010vvvvvvvvvvvv0111vvvv") }, // v5 - { INST(&V::arm_SVC, "SVC", "cccc1111vvvvvvvvvvvvvvvvvvvvvvvv") }, // all - { INST(&V::arm_UDF, "UDF", "111001111111------------1111----") }, // all + //INST(&V::arm_BKPT, "BKPT", "cccc00010010vvvvvvvvvvvv0111vvvv"), // v5 + //INST(&V::arm_SVC, "SVC", "cccc1111vvvvvvvvvvvvvvvvvvvvvvvv"), // all + INST(&V::arm_UDF, "UDF", "111001111111------------1111----"), // all // Extension instructions - { INST(&V::arm_SXTB, "SXTB", "cccc011010101111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_SXTB16, "SXTB16", "cccc011010001111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_SXTH, "SXTH", "cccc011010111111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_SXTAB, "SXTAB", "cccc01101010nnnnddddrr000111mmmm") }, // v6 - { INST(&V::arm_SXTAB16, "SXTAB16", "cccc01101000nnnnddddrr000111mmmm") }, // v6 - { INST(&V::arm_SXTAH, "SXTAH", "cccc01101011nnnnddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTB, "UXTB", "cccc011011101111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTB16, "UXTB16", "cccc011011001111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTH, "UXTH", "cccc011011111111ddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTAB, "UXTAB", "cccc01101110nnnnddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTAB16, "UXTAB16", "cccc01101100nnnnddddrr000111mmmm") }, // v6 - { INST(&V::arm_UXTAH, "UXTAH", "cccc01101111nnnnddddrr000111mmmm") }, // v6 + //INST(&V::arm_SXTB, "SXTB", "cccc011010101111ddddrr000111mmmm"), // v6 + //INST(&V::arm_SXTB16, "SXTB16", "cccc011010001111ddddrr000111mmmm"), // v6 + //INST(&V::arm_SXTH, "SXTH", "cccc011010111111ddddrr000111mmmm"), // v6 + //INST(&V::arm_SXTAB, "SXTAB", "cccc01101010nnnnddddrr000111mmmm"), // v6 + //INST(&V::arm_SXTAB16, "SXTAB16", "cccc01101000nnnnddddrr000111mmmm"), // v6 + //INST(&V::arm_SXTAH, "SXTAH", "cccc01101011nnnnddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTB, "UXTB", "cccc011011101111ddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTB16, "UXTB16", "cccc011011001111ddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTH, "UXTH", "cccc011011111111ddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTAB, "UXTAB", "cccc01101110nnnnddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTAB16, "UXTAB16", "cccc01101100nnnnddddrr000111mmmm"), // v6 + //INST(&V::arm_UXTAH, "UXTAH", "cccc01101111nnnnddddrr000111mmmm"), // v6 // Hint instructions - { INST(&V::arm_PLD, "PLD", "111101---101----1111------------") }, // v5E - { INST(&V::arm_SEV, "SEV", "----0011001000001111000000000100") }, // v6K - { INST(&V::arm_WFE, "WFE", "----0011001000001111000000000010") }, // v6K - { INST(&V::arm_WFI, "WFI", "----0011001000001111000000000011") }, // v6K - { INST(&V::arm_YIELD, "YIELD", "----0011001000001111000000000001") }, // v6K + //INST(&V::arm_PLD, "PLD", "111101---101----1111------------"), // v5E + //INST(&V::arm_SEV, "SEV", "----0011001000001111000000000100"), // v6K + //INST(&V::arm_WFE, "WFE", "----0011001000001111000000000010"), // v6K + //INST(&V::arm_WFI, "WFI", "----0011001000001111000000000011"), // v6K + //INST(&V::arm_YIELD, "YIELD", "----0011001000001111000000000001"), // v6K // Synchronization Primitive instructions - { INST(&V::arm_CLREX, "CLREX", "11110101011111111111000000011111") }, // v6K - { INST(&V::arm_LDREX, "LDREX", "cccc00011001nnnndddd111110011111") }, // v6 - { INST(&V::arm_LDREXB, "LDREXB", "cccc00011101nnnndddd111110011111") }, // v6K - { INST(&V::arm_LDREXD, "LDREXD", "cccc00011011nnnndddd111110011111") }, // v6K - { INST(&V::arm_LDREXH, "LDREXH", "cccc00011111nnnndddd111110011111") }, // v6K - { INST(&V::arm_STREX, "STREX", "cccc00011000nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_STREXB, "STREXB", "cccc00011100nnnndddd11111001mmmm") }, // v6K - { INST(&V::arm_STREXD, "STREXD", "cccc00011010nnnndddd11111001mmmm") }, // v6K - { INST(&V::arm_STREXH, "STREXH", "cccc00011110nnnndddd11111001mmmm") }, // v6K - { INST(&V::arm_SWP, "SWP", "cccc00010000nnnndddd00001001mmmm") }, // v2S (v6: Deprecated) - { INST(&V::arm_SWPB, "SWPB", "cccc00010100nnnndddd00001001mmmm") }, // v2S (v6: Deprecated) + //INST(&V::arm_CLREX, "CLREX", "11110101011111111111000000011111"), // v6K + //INST(&V::arm_LDREX, "LDREX", "cccc00011001nnnndddd111110011111"), // v6 + //INST(&V::arm_LDREXB, "LDREXB", "cccc00011101nnnndddd111110011111"), // v6K + //INST(&V::arm_LDREXD, "LDREXD", "cccc00011011nnnndddd111110011111"), // v6K + //INST(&V::arm_LDREXH, "LDREXH", "cccc00011111nnnndddd111110011111"), // v6K + //INST(&V::arm_STREX, "STREX", "cccc00011000nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_STREXB, "STREXB", "cccc00011100nnnndddd11111001mmmm"), // v6K + //INST(&V::arm_STREXD, "STREXD", "cccc00011010nnnndddd11111001mmmm"), // v6K + //INST(&V::arm_STREXH, "STREXH", "cccc00011110nnnndddd11111001mmmm"), // v6K + //INST(&V::arm_SWP, "SWP", "cccc00010000nnnndddd00001001mmmm"), // v2S (v6: Deprecated) + //INST(&V::arm_SWPB, "SWPB", "cccc00010100nnnndddd00001001mmmm"), // v2S (v6: Deprecated) // Load/Store instructions - { INST(&V::arm_LDR_imm, "LDR (imm)", "cccc010pu0w1nnnnddddvvvvvvvvvvvv") }, - { INST(&V::arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnddddvvvvvrr0mmmm") }, - { INST(&V::arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnddddvvvvvvvvvvvv") }, - { INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm") }, - { INST(&V::arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------") }, - { INST(&V::arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----") }, - { INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv") }, // v5E - { INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm") }, // v5E - { INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv") }, - { INST(&V::arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnndddd00001011mmmm") }, - { INST(&V::arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----") }, - { INST(&V::arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----") }, - { INST(&V::arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnddddvvvv1101vvvv") }, - { INST(&V::arm_LDRSB_reg, "LDRSB (reg)", "cccc000pu0w1nnnndddd00001101mmmm") }, - { INST(&V::arm_LDRSBT, "LDRSBT (A1)", "----0000-111------------1101----") }, - { INST(&V::arm_LDRSBT, "LDRSBT (A2)", "----0000-011--------00001101----") }, - { INST(&V::arm_LDRSH_imm, "LDRSH (imm)", "cccc000pu1w1nnnnddddvvvv1111vvvv") }, - { INST(&V::arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnndddd00001111mmmm") }, - { INST(&V::arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----") }, - { INST(&V::arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----") }, - { INST(&V::arm_LDRT, "LDRT (A1)", "----0100-011--------------------") }, - { INST(&V::arm_LDRT, "LDRT (A2)", "----0110-011---------------0----") }, - { INST(&V::arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnddddvvvvvvvvvvvv") }, - { INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm") }, - { INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv") }, - { INST(&V::arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnddddvvvvvrr0mmmm") }, - { INST(&V::arm_STRBT, "STRBT (A1)", "----0100-110--------------------") }, - { INST(&V::arm_STRBT, "STRBT (A2)", "----0110-110---------------0----") }, - { INST(&V::arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnddddvvvv1111vvvv") }, // v5E - { INST(&V::arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnndddd00001111mmmm") }, // v5E - { INST(&V::arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnddddvvvv1011vvvv") }, - { INST(&V::arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnndddd00001011mmmm") }, - { INST(&V::arm_STRHT, "STRHT (A1)", "----0000-110------------1011----") }, - { INST(&V::arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----") }, - { INST(&V::arm_STRT, "STRT (A1)", "----0100-010--------------------") }, - { INST(&V::arm_STRT, "STRT (A2)", "----0110-010---------------0----") }, + //INST(&V::arm_LDR_imm, "LDR (imm)", "cccc010pu0w1nnnnddddvvvvvvvvvvvv"), + //INST(&V::arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnddddvvvvvrr0mmmm"), + //INST(&V::arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnddddvvvvvvvvvvvv"), + //INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm"), + //INST(&V::arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------"), + //INST(&V::arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----"), + //INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E + //INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E + //INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"), + //INST(&V::arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnndddd00001011mmmm"), + //INST(&V::arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----"), + //INST(&V::arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----"), + //INST(&V::arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnddddvvvv1101vvvv"), + //INST(&V::arm_LDRSB_reg, "LDRSB (reg)", "cccc000pu0w1nnnndddd00001101mmmm"), + //INST(&V::arm_LDRSBT, "LDRSBT (A1)", "----0000-111------------1101----"), + //INST(&V::arm_LDRSBT, "LDRSBT (A2)", "----0000-011--------00001101----"), + //INST(&V::arm_LDRSH_imm, "LDRSH (imm)", "cccc000pu1w1nnnnddddvvvv1111vvvv"), + //INST(&V::arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnndddd00001111mmmm"), + //INST(&V::arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----"), + //INST(&V::arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----"), + //INST(&V::arm_LDRT, "LDRT (A1)", "----0100-011--------------------"), + //INST(&V::arm_LDRT, "LDRT (A2)", "----0110-011---------------0----"), + //INST(&V::arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnddddvvvvvvvvvvvv"), + //INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm"), + //INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv"), + //INST(&V::arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnddddvvvvvrr0mmmm"), + //INST(&V::arm_STRBT, "STRBT (A1)", "----0100-110--------------------"), + //INST(&V::arm_STRBT, "STRBT (A2)", "----0110-110---------------0----"), + //INST(&V::arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnddddvvvv1111vvvv"), // v5E + //INST(&V::arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnndddd00001111mmmm"), // v5E + //INST(&V::arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnddddvvvv1011vvvv"), + //INST(&V::arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnndddd00001011mmmm"), + //INST(&V::arm_STRHT, "STRHT (A1)", "----0000-110------------1011----"), + //INST(&V::arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----"), + //INST(&V::arm_STRT, "STRT (A1)", "----0100-010--------------------"), + //INST(&V::arm_STRT, "STRT (A2)", "----0110-010---------------0----"), // Load/Store Multiple instructions - { INST(&V::arm_LDM, "LDM", "cccc100pu0w1nnnnxxxxxxxxxxxxxxxx") }, // all - { INST(&V::arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------") }, // all - { INST(&V::arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------") }, // all - { INST(&V::arm_STM, "STM", "cccc100pu0w0nnnnxxxxxxxxxxxxxxxx") }, // all - { INST(&V::arm_STM_usr, "STM (usr reg)", "----100--100--------------------") }, // all + //INST(&V::arm_LDM, "LDM", "cccc100pu0w1nnnnxxxxxxxxxxxxxxxx"), // all + //INST(&V::arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------"), // all + //INST(&V::arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------"), // all + //INST(&V::arm_STM, "STM", "cccc100pu0w0nnnnxxxxxxxxxxxxxxxx"), // all + //INST(&V::arm_STM_usr, "STM (usr reg)", "----100--100--------------------"), // all // Miscellaneous instructions - { INST(&V::arm_CLZ, "CLZ", "cccc000101101111dddd11110001mmmm") }, // v5 - { INST(&V::arm_NOP, "NOP", "----001100100000111100000000----") }, // v6K - { INST(&V::arm_SEL, "SEL", "cccc01101000nnnndddd11111011mmmm") }, // v6 + //INST(&V::arm_CLZ, "CLZ", "cccc000101101111dddd11110001mmmm"), // v5 + //INST(&V::arm_NOP, "NOP", "----001100100000111100000000----"), // v6K + //INST(&V::arm_SEL, "SEL", "cccc01101000nnnndddd11111011mmmm"), // v6 // Unsigned Sum of Absolute Differences instructions - { INST(&V::arm_USAD8, "USAD8", "cccc01111000dddd1111mmmm0001nnnn") }, // v6 - { INST(&V::arm_USADA8, "USADA8", "cccc01111000ddddaaaammmm0001nnnn") }, // v6 + //INST(&V::arm_USAD8, "USAD8", "cccc01111000dddd1111mmmm0001nnnn"), // v6 + //INST(&V::arm_USADA8, "USADA8", "cccc01111000ddddaaaammmm0001nnnn"), // v6 // Packing instructions - { INST(&V::arm_PKHBT, "PKHBT", "cccc01101000nnnnddddvvvvv001mmmm") }, // v6K - { INST(&V::arm_PKHTB, "PKHTB", "cccc01101000nnnnddddvvvvv101mmmm") }, // v6K + //INST(&V::arm_PKHBT, "PKHBT", "cccc01101000nnnnddddvvvvv001mmmm"), // v6K + //INST(&V::arm_PKHTB, "PKHTB", "cccc01101000nnnnddddvvvvv101mmmm"), // v6K // Reversal instructions - { INST(&V::arm_REV, "REV", "cccc011010111111dddd11110011mmmm") }, // v6 - { INST(&V::arm_REV16, "REV16", "cccc011010111111dddd11111011mmmm") }, // v6 - { INST(&V::arm_REVSH, "REVSH", "cccc011011111111dddd11111011mmmm") }, // v6 + //INST(&V::arm_REV, "REV", "cccc011010111111dddd11110011mmmm"), // v6 + //INST(&V::arm_REV16, "REV16", "cccc011010111111dddd11111011mmmm"), // v6 + //INST(&V::arm_REVSH, "REVSH", "cccc011011111111dddd11111011mmmm"), // v6 // Saturation instructions - { INST(&V::arm_SSAT, "SSAT", "cccc0110101vvvvvddddvvvvvr01nnnn") }, // v6 - { INST(&V::arm_SSAT16, "SSAT16", "cccc01101010vvvvdddd11110011nnnn") }, // v6 - { INST(&V::arm_USAT, "USAT", "cccc0110111vvvvvddddvvvvvr01nnnn") }, // v6 - { INST(&V::arm_USAT16, "USAT16", "cccc01101110vvvvdddd11110011nnnn") }, // v6 + //INST(&V::arm_SSAT, "SSAT", "cccc0110101vvvvvddddvvvvvr01nnnn"), // v6 + //INST(&V::arm_SSAT16, "SSAT16", "cccc01101010vvvvdddd11110011nnnn"), // v6 + //INST(&V::arm_USAT, "USAT", "cccc0110111vvvvvddddvvvvvr01nnnn"), // v6 + //INST(&V::arm_USAT16, "USAT16", "cccc01101110vvvvdddd11110011nnnn"), // v6 // Multiply (Normal) instructions - { INST(&V::arm_MLA, "MLA", "cccc0000001Sddddaaaammmm1001nnnn") }, // v2 - { INST(&V::arm_MUL, "MUL", "cccc0000000Sdddd0000mmmm1001nnnn") }, // v2 + //INST(&V::arm_MLA, "MLA", "cccc0000001Sddddaaaammmm1001nnnn"), // v2 + //INST(&V::arm_MUL, "MUL", "cccc0000000Sdddd0000mmmm1001nnnn"), // v2 // Multiply (Long) instructions - { INST(&V::arm_SMLAL, "SMLAL", "cccc0000111Sddddaaaammmm1001nnnn") }, // v3M - { INST(&V::arm_SMULL, "SMULL", "cccc0000110Sddddaaaammmm1001nnnn") }, // v3M - { INST(&V::arm_UMAAL, "UMAAL", "cccc00000100ddddaaaammmm1001nnnn") }, // v6 - { INST(&V::arm_UMLAL, "UMLAL", "cccc0000101Sddddaaaammmm1001nnnn") }, // v3M - { INST(&V::arm_UMULL, "UMULL", "cccc0000100Sddddaaaammmm1001nnnn") }, // v3M + //INST(&V::arm_SMLAL, "SMLAL", "cccc0000111Sddddaaaammmm1001nnnn"), // v3M + //INST(&V::arm_SMULL, "SMULL", "cccc0000110Sddddaaaammmm1001nnnn"), // v3M + //INST(&V::arm_UMAAL, "UMAAL", "cccc00000100ddddaaaammmm1001nnnn"), // v6 + //INST(&V::arm_UMLAL, "UMLAL", "cccc0000101Sddddaaaammmm1001nnnn"), // v3M + //INST(&V::arm_UMULL, "UMULL", "cccc0000100Sddddaaaammmm1001nnnn"), // v3M // Multiply (Halfword) instructions - { INST(&V::arm_SMLALxy, "SMLALXY", "cccc00010100ddddaaaammmm1xy0nnnn") }, // v5xP - { INST(&V::arm_SMLAxy, "SMLAXY", "cccc00010000ddddaaaammmm1xy0nnnn") }, // v5xP - { INST(&V::arm_SMULxy, "SMULXY", "cccc00010110dddd0000mmmm1xy0nnnn") }, // v5xP + //INST(&V::arm_SMLALxy, "SMLALXY", "cccc00010100ddddaaaammmm1xy0nnnn"), // v5xP + //INST(&V::arm_SMLAxy, "SMLAXY", "cccc00010000ddddaaaammmm1xy0nnnn"), // v5xP + //INST(&V::arm_SMULxy, "SMULXY", "cccc00010110dddd0000mmmm1xy0nnnn"), // v5xP // Multiply (Word by Halfword) instructions - { INST(&V::arm_SMLAWy, "SMLAWY", "cccc00010010ddddaaaammmm1y00nnnn") }, // v5xP - { INST(&V::arm_SMULWy, "SMULWY", "cccc00010010dddd0000mmmm1y10nnnn") }, // v5xP + //INST(&V::arm_SMLAWy, "SMLAWY", "cccc00010010ddddaaaammmm1y00nnnn"), // v5xP + //INST(&V::arm_SMULWy, "SMULWY", "cccc00010010dddd0000mmmm1y10nnnn"), // v5xP // Multiply (Most Significant Word) instructions - { INST(&V::arm_SMMUL, "SMMUL", "cccc01110101dddd1111mmmm00R1nnnn") }, // v6 - { INST(&V::arm_SMMLA, "SMMLA", "cccc01110101ddddaaaammmm00R1nnnn") }, // v6 - { INST(&V::arm_SMMLS, "SMMLS", "cccc01110101ddddaaaammmm11R1nnnn") }, // v6 + //INST(&V::arm_SMMUL, "SMMUL", "cccc01110101dddd1111mmmm00R1nnnn"), // v6 + //INST(&V::arm_SMMLA, "SMMLA", "cccc01110101ddddaaaammmm00R1nnnn"), // v6 + //INST(&V::arm_SMMLS, "SMMLS", "cccc01110101ddddaaaammmm11R1nnnn"), // v6 // Multiply (Dual) instructions - { INST(&V::arm_SMLAD, "SMLAD", "cccc01110000ddddaaaammmm00M1nnnn") }, // v6 - { INST(&V::arm_SMLALD, "SMLALD", "cccc01110100ddddaaaammmm00M1nnnn") }, // v6 - { INST(&V::arm_SMLSD, "SMLSD", "cccc01110000ddddaaaammmm01M1nnnn") }, // v6 - { INST(&V::arm_SMLSLD, "SMLSLD", "cccc01110100ddddaaaammmm01M1nnnn") }, // v6 - { INST(&V::arm_SMUAD, "SMUAD", "cccc01110000dddd1111mmmm00M1nnnn") }, // v6 - { INST(&V::arm_SMUSD, "SMUSD", "cccc01110000dddd1111mmmm01M1nnnn") }, // v6 + //INST(&V::arm_SMLAD, "SMLAD", "cccc01110000ddddaaaammmm00M1nnnn"), // v6 + //INST(&V::arm_SMLALD, "SMLALD", "cccc01110100ddddaaaammmm00M1nnnn"), // v6 + //INST(&V::arm_SMLSD, "SMLSD", "cccc01110000ddddaaaammmm01M1nnnn"), // v6 + //INST(&V::arm_SMLSLD, "SMLSLD", "cccc01110100ddddaaaammmm01M1nnnn"), // v6 + //INST(&V::arm_SMUAD, "SMUAD", "cccc01110000dddd1111mmmm00M1nnnn"), // v6 + //INST(&V::arm_SMUSD, "SMUSD", "cccc01110000dddd1111mmmm01M1nnnn"), // v6 // Parallel Add/Subtract (Modulo) instructions - { INST(&V::arm_SADD8, "SADD8", "cccc01100001nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_SADD16, "SADD16", "cccc01100001nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_SASX, "SASX", "cccc01100001nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_SSAX, "SSAX", "cccc01100001nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_SSUB8, "SSUB8", "cccc01100001nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_SSUB16, "SSUB16", "cccc01100001nnnndddd11110111mmmm") }, // v6 - { INST(&V::arm_UADD8, "UADD8", "cccc01100101nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_UADD16, "UADD16", "cccc01100101nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_UASX, "UASX", "cccc01100101nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_USAX, "USAX", "cccc01100101nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_USUB8, "USUB8", "cccc01100101nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_USUB16, "USUB16", "cccc01100101nnnndddd11110111mmmm") }, // v6 + //INST(&V::arm_SADD8, "SADD8", "cccc01100001nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_SADD16, "SADD16", "cccc01100001nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_SASX, "SASX", "cccc01100001nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_SSAX, "SSAX", "cccc01100001nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_SSUB8, "SSUB8", "cccc01100001nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_SSUB16, "SSUB16", "cccc01100001nnnndddd11110111mmmm"), // v6 + //INST(&V::arm_UADD8, "UADD8", "cccc01100101nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_UADD16, "UADD16", "cccc01100101nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_UASX, "UASX", "cccc01100101nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_USAX, "USAX", "cccc01100101nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_USUB8, "USUB8", "cccc01100101nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_USUB16, "USUB16", "cccc01100101nnnndddd11110111mmmm"), // v6 // Parallel Add/Subtract (Saturating) instructions - { INST(&V::arm_QADD8, "QADD8", "cccc01100010nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_QADD16, "QADD16", "cccc01100010nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_QASX, "QASX", "cccc01100010nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_QSAX, "QSAX", "cccc01100010nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_QSUB8, "QSUB8", "cccc01100010nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_QSUB16, "QSUB16", "cccc01100010nnnndddd11110111mmmm") }, // v6 - { INST(&V::arm_UQADD8, "UQADD8", "cccc01100110nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_UQADD16, "UQADD16", "cccc01100110nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_UQASX, "UQASX", "cccc01100110nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_UQSAX, "UQSAX", "cccc01100110nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_UQSUB8, "UQSUB8", "cccc01100110nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_UQSUB16, "UQSUB16", "cccc01100110nnnndddd11110111mmmm") }, // v6 + //INST(&V::arm_QADD8, "QADD8", "cccc01100010nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_QADD16, "QADD16", "cccc01100010nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_QASX, "QASX", "cccc01100010nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_QSAX, "QSAX", "cccc01100010nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_QSUB8, "QSUB8", "cccc01100010nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_QSUB16, "QSUB16", "cccc01100010nnnndddd11110111mmmm"), // v6 + //INST(&V::arm_UQADD8, "UQADD8", "cccc01100110nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_UQADD16, "UQADD16", "cccc01100110nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_UQASX, "UQASX", "cccc01100110nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_UQSAX, "UQSAX", "cccc01100110nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_UQSUB8, "UQSUB8", "cccc01100110nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_UQSUB16, "UQSUB16", "cccc01100110nnnndddd11110111mmmm"), // v6 // Parallel Add/Subtract (Halving) instructions - { INST(&V::arm_SHADD8, "SHADD8", "cccc01100011nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_SHADD16, "SHADD16", "cccc01100011nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_SHASX, "SHASX", "cccc01100011nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_SHSAX, "SHSAX", "cccc01100011nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_SHSUB8, "SHSUB8", "cccc01100011nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_SHSUB16, "SHSUB16", "cccc01100011nnnndddd11110111mmmm") }, // v6 - { INST(&V::arm_UHADD8, "UHADD8", "cccc01100111nnnndddd11111001mmmm") }, // v6 - { INST(&V::arm_UHADD16, "UHADD16", "cccc01100111nnnndddd11110001mmmm") }, // v6 - { INST(&V::arm_UHASX, "UHASX", "cccc01100111nnnndddd11110011mmmm") }, // v6 - { INST(&V::arm_UHSAX, "UHSAX", "cccc01100111nnnndddd11110101mmmm") }, // v6 - { INST(&V::arm_UHSUB8, "UHSUB8", "cccc01100111nnnndddd11111111mmmm") }, // v6 - { INST(&V::arm_UHSUB16, "UHSUB16", "cccc01100111nnnndddd11110111mmmm") }, // v6 + //INST(&V::arm_SHADD8, "SHADD8", "cccc01100011nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_SHADD16, "SHADD16", "cccc01100011nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_SHASX, "SHASX", "cccc01100011nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_SHSAX, "SHSAX", "cccc01100011nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_SHSUB8, "SHSUB8", "cccc01100011nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_SHSUB16, "SHSUB16", "cccc01100011nnnndddd11110111mmmm"), // v6 + //INST(&V::arm_UHADD8, "UHADD8", "cccc01100111nnnndddd11111001mmmm"), // v6 + //INST(&V::arm_UHADD16, "UHADD16", "cccc01100111nnnndddd11110001mmmm"), // v6 + //INST(&V::arm_UHASX, "UHASX", "cccc01100111nnnndddd11110011mmmm"), // v6 + //INST(&V::arm_UHSAX, "UHSAX", "cccc01100111nnnndddd11110101mmmm"), // v6 + //INST(&V::arm_UHSUB8, "UHSUB8", "cccc01100111nnnndddd11111111mmmm"), // v6 + //INST(&V::arm_UHSUB16, "UHSUB16", "cccc01100111nnnndddd11110111mmmm"), // v6 // Saturated Add/Subtract instructions - { INST(&V::arm_QADD, "QADD", "cccc00010000nnnndddd00000101mmmm") }, // v5xP - { INST(&V::arm_QSUB, "QSUB", "cccc00010010nnnndddd00000101mmmm") }, // v5xP - { INST(&V::arm_QDADD, "QDADD", "cccc00010100nnnndddd00000101mmmm") }, // v5xP - { INST(&V::arm_QDSUB, "QDSUB", "cccc00010110nnnndddd00000101mmmm") }, // v5xP + //INST(&V::arm_QADD, "QADD", "cccc00010000nnnndddd00000101mmmm"), // v5xP + //INST(&V::arm_QSUB, "QSUB", "cccc00010010nnnndddd00000101mmmm"), // v5xP + //INST(&V::arm_QDADD, "QDADD", "cccc00010100nnnndddd00000101mmmm"), // v5xP + //INST(&V::arm_QDSUB, "QDSUB", "cccc00010110nnnndddd00000101mmmm"), // v5xP // Status Register Access instructions - { INST(&V::arm_CPS, "CPS", "111100010000---00000000---0-----") }, // v6 - { INST(&V::arm_SETEND, "SETEND", "1111000100000001000000e000000000") }, // v6 - { INST(&V::arm_MRS, "MRS", "----00010-00--------00--00000000") }, // v3 - { INST(&V::arm_MSR, "MSR", "----00-10-10----1111------------") }, // v3 - { INST(&V::arm_RFE, "RFE", "----0001101-0000---------110----") }, // v6 - { INST(&V::arm_SRS, "SRS", "0000011--0-00000000000000001----") }, // v6 + //INST(&V::arm_CPS, "CPS", "111100010000---00000000---0-----"), // v6 + //INST(&V::arm_SETEND, "SETEND", "1111000100000001000000e000000000"), // v6 + //INST(&V::arm_MRS, "MRS", "----00010-00--------00--00000000"), // v3 + //INST(&V::arm_MSR, "MSR", "----00-10-10----1111------------"), // v3 + //INST(&V::arm_RFE, "RFE", "----0001101-0000---------110----"), // v6 + //INST(&V::arm_SRS, "SRS", "0000011--0-00000000000000001----"), // v6 #undef INST -}}; +}; template boost::optional&> DecodeArm(u32 instruction) { diff --git a/src/frontend/translate_arm.cpp b/src/frontend/translate_arm.cpp index fe1ca7bc..691e61c8 100644 --- a/src/frontend/translate_arm.cpp +++ b/src/frontend/translate_arm.cpp @@ -6,6 +6,7 @@ #include "common/assert.h" #include "frontend/arm_types.h" +#include "frontend/decoder/arm.h" #include "frontend/ir/ir.h" #include "frontend/ir_emitter.h" #include "frontend/translate.h" @@ -13,12 +14,52 @@ namespace Dynarmic { namespace Arm { +namespace { + +struct ArmTranslatorVisitor final { + explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) { + ASSERT_MSG(!descriptor.TFlag, "The processor must be in Arm mode"); + } + + IREmitter ir; + + bool TranslateThisInstruction() { + ir.SetTerm(IR::Term::Interpret(ir.current_location)); + return false; + } + + bool UnpredictableInstruction() { + ASSERT_MSG(false, "UNPREDICTABLE"); + return false; + } + + bool arm_UDF() { + return TranslateThisInstruction(); + } +}; + +} // local namespace + IR::Block TranslateArm(LocationDescriptor descriptor, MemoryRead32FuncType memory_read_32) { - // Just interpret everything. - IREmitter ir{descriptor}; - ir.SetTerm(IR::Term::Interpret{ir.current_location}); - ir.block.cycle_count++; - return ir.block; + ArmTranslatorVisitor visitor{descriptor}; + + bool should_continue = true; + while (should_continue) { + const u32 arm_pc = visitor.ir.current_location.arm_pc; + const u32 arm_instruction = (*memory_read_32)(arm_pc); + + const auto decoder = DecodeArm(arm_instruction); + if (decoder) { + should_continue = decoder->call(visitor, arm_instruction); + } else { + should_continue = visitor.arm_UDF(); + } + + visitor.ir.current_location.arm_pc += 4; + visitor.ir.block.cycle_count++; + } + + return visitor.ir.block; } } // namespace Arm diff --git a/src/frontend/translate_thumb.cpp b/src/frontend/translate_thumb.cpp index aba56fc9..a74aedb6 100644 --- a/src/frontend/translate_thumb.cpp +++ b/src/frontend/translate_thumb.cpp @@ -15,8 +15,10 @@ namespace Dynarmic { namespace Arm { -struct TranslatorVisitor final { - explicit TranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) { +namespace { + +struct ThumbTranslatorVisitor final { + explicit ThumbTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) { ASSERT_MSG(descriptor.TFlag, "The processor must be in Thumb mode"); } @@ -26,6 +28,7 @@ struct TranslatorVisitor final { ir.SetTerm(IR::Term::Interpret(ir.current_location)); return false; } + bool UnpredictableInstruction() { ASSERT_MSG(false, "UNPREDICTABLE"); return false; @@ -42,6 +45,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_LSR_imm(Imm5 imm5, Reg m, Reg d) { u8 shift_n = imm5 != 0 ? imm5 : 32; // LSRS , , # @@ -53,6 +57,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_ASR_imm(Imm5 imm5, Reg m, Reg d) { u8 shift_n = imm5 != 0 ? imm5 : 32; // ASRS , , # @@ -64,6 +69,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) { // ADDS , , // Note that it is not possible to encode Rd == R15. @@ -75,6 +81,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_SUB_reg(Reg m, Reg n, Reg d) { // SUBS , , // Note that it is not possible to encode Rd == R15. @@ -86,6 +93,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_ADD_imm_t1(Imm3 imm3, Reg n, Reg d) { u32 imm32 = imm3 & 0x7; // ADDS , , # @@ -98,6 +106,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_SUB_imm_t1(Imm3 imm3, Reg n, Reg d) { u32 imm32 = imm3 & 0x7; // SUBS , , # @@ -110,6 +119,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_MOV_imm(Reg d, Imm8 imm8) { u32 imm32 = imm8 & 0xFF; // MOVS , # @@ -120,6 +130,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_CMP_imm(Reg n, Imm8 imm8) { u32 imm32 = imm8 & 0xFF; // CMP , # @@ -130,6 +141,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_ADD_imm_t2(Reg d_n, Imm8 imm8) { u32 imm32 = imm8 & 0xFF; Reg d = d_n, n = d_n; @@ -143,6 +155,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_SUB_imm_t2(Reg d_n, Imm8 imm8) { u32 imm32 = imm8 & 0xFF; Reg d = d_n, n = d_n; @@ -167,6 +180,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_EOR_reg(Reg m, Reg d_n) { const Reg d = d_n, n = d_n; // EORS , @@ -177,6 +191,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_LSL_reg(Reg m, Reg d_n) { const Reg d = d_n, n = d_n; // LSLS , @@ -189,6 +204,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result_carry.carry); return true; } + bool thumb16_LSR_reg(Reg m, Reg d_n) { const Reg d = d_n, n = d_n; // LSRS , @@ -201,6 +217,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_ASR_reg(Reg m, Reg d_n) { const Reg d = d_n, n = d_n; // ASRS , @@ -213,6 +230,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_ADC_reg(Reg m, Reg d_n) { Reg d = d_n, n = d_n; // ADCS , @@ -226,6 +244,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_SBC_reg(Reg m, Reg d_n) { Reg d = d_n, n = d_n; // SBCS , @@ -239,6 +258,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_ROR_reg(Reg m, Reg d_n) { Reg d = d_n, n = d_n; // RORS , @@ -251,6 +271,7 @@ struct TranslatorVisitor final { ir.SetCFlag(result.carry); return true; } + bool thumb16_TST_reg(Reg m, Reg n) { // TST , auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); @@ -258,6 +279,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_RSB_imm(Reg n, Reg d) { // RSBS , , #0 // Rd can never encode R15. @@ -269,6 +291,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_CMP_reg_t1(Reg m, Reg n) { // CMP , auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); @@ -278,6 +301,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_CMN_reg(Reg m, Reg n) { // CMN , auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); @@ -287,6 +311,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_ORR_reg(Reg m, Reg d_n) { Reg d = d_n, n = d_n; // ORRS , @@ -297,6 +322,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_BIC_reg(Reg m, Reg d_n) { Reg d = d_n, n = d_n; // BICS , @@ -307,6 +333,7 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb16_MVN_reg(Reg m, Reg d) { // MVNS , // Rd cannot encode R15. @@ -351,6 +378,7 @@ struct TranslatorVisitor final { ir.SetVFlag(result.overflow); return true; } + bool thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) { Reg d = d_hi ? (d_lo + 8) : d_lo; // MOV , @@ -435,16 +463,18 @@ static std::tuple ReadThumbInstruction(u32 arm_pc, MemoryRea // 32-bit thumb instruction // These always start with 0b11101, 0b11110 or 0b11111. - u32 second_part = (*memory_read_32)((arm_pc+2) & 0xFFFFFFFC); - if (((arm_pc+2) & 0x2) != 0) + u32 second_part = (*memory_read_32)((arm_pc + 2) & 0xFFFFFFFC); + if (((arm_pc + 2) & 0x2) != 0) second_part >>= 16; second_part &= 0xFFFF; return std::make_tuple(static_cast((first_part << 16) | second_part), ThumbInstSize::Thumb32); } +} // local namespace + IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryRead32FuncType memory_read_32) { - TranslatorVisitor visitor{descriptor}; + ThumbTranslatorVisitor visitor{descriptor}; bool should_continue = true; while (should_continue) { @@ -455,14 +485,14 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryRead32FuncType mem std::tie(thumb_instruction, inst_size) = ReadThumbInstruction(arm_pc, memory_read_32); if (inst_size == ThumbInstSize::Thumb16) { - auto decoder = DecodeThumb16(static_cast(thumb_instruction)); + auto decoder = DecodeThumb16(static_cast(thumb_instruction)); if (decoder) { should_continue = decoder->call(visitor, static_cast(thumb_instruction)); } else { should_continue = visitor.thumb16_UDF(); } } else { - /*auto decoder = DecodeThumb32(thumb_instruction); + /*auto decoder = DecodeThumb32(thumb_instruction); if (decoder) { should_continue = decoder->call(visitor, thumb_instruction); } else { diff --git a/tests/arm/test_arm_disassembler.cpp b/tests/arm/test_arm_disassembler.cpp index 7444eb2a..e2a691b8 100644 --- a/tests/arm/test_arm_disassembler.cpp +++ b/tests/arm/test_arm_disassembler.cpp @@ -8,7 +8,7 @@ #include "frontend/disassembler.h" -TEST_CASE( "Disassemble branch instructions", "[arm][disassembler]" ) { +TEST_CASE( "Disassemble branch instructions", "[arm][disassembler][!hide]" ) { REQUIRE(Dynarmic::Arm::DisassembleArm(0xEAFFFFFE) == "b +#0"); REQUIRE(Dynarmic::Arm::DisassembleArm(0xEB000008) == "bl +#40"); REQUIRE(Dynarmic::Arm::DisassembleArm(0xFBFFFFFE) == "blx +#2"); @@ -19,6 +19,6 @@ TEST_CASE( "Disassemble branch instructions", "[arm][disassembler]" ) { REQUIRE(Dynarmic::Arm::DisassembleArm(0x012FFF29) == "bxjeq r9"); } -TEST_CASE( "Disassemble data processing instructions", "[arm][disassembler]" ) { +TEST_CASE( "Disassemble data processing instructions", "[arm][disassembler][!hide]" ) { REQUIRE(Dynarmic::Arm::DisassembleArm(0xE2853004) == "add r3, r5, #4"); }