diff --git a/externals/boost b/externals/boost index d81b92699..2dcb9d979 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit d81b9269900ae183d0dc98403eea4c971590a807 +Subproject commit 2dcb9d979665b6aabb1635c617973e02914e60ec diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f9c31662c..76c9cc629 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -267,7 +267,6 @@ set(HEADERS if(ARCHITECTURE_x86_64) set(SRCS ${SRCS} arm/jit_x64/cond.cpp - arm/jit_x64/instructions/barrier.cpp arm/jit_x64/instructions/branch.cpp arm/jit_x64/instructions/coprocessor.cpp arm/jit_x64/instructions/data_processing.cpp diff --git a/src/core/arm/decoder/arm.cpp b/src/core/arm/decoder/arm.cpp index 9b48b4698..68c2527e0 100644 --- a/src/core/arm/decoder/arm.cpp +++ b/src/core/arm/decoder/arm.cpp @@ -2,10 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - #include #include +#include + +#include #include "common/assert.h" #include "common/common_types.h" @@ -16,47 +17,65 @@ namespace ArmDecoder { namespace Impl { - template - struct Call { - FORCE_INLINE static void call(Visitor* v, Function fn, const Container& list, Args&&... args) { - using ArgT = decltype(std::get(list)); - Call::call(v, fn, list, std::get(list), args...); - } + // std::integer_sequence and std::make_integer_sequence are only available in C++14 + + /// This type represents a sequence of integers + template + struct integer_sequence {}; + + /// This metafunction generates a sequence of integers from 0..N + template + struct make_integer_sequence : make_integer_sequence {}; + + // Internal implementation for make_integer_sequence + template + struct make_integer_sequence<0, seq...> { + typedef integer_sequence type; }; - template - struct Call { - FORCE_INLINE static void call(Visitor* v, Function fn, const Container& list, Args&&... args) { - (v->*fn)(args...); - } - }; + /** + * This function takes a member function of Visitor and calls it with the parameters specified in list. + * @tparam NumArgs Number of arguments that the member function fn has. + * @param v The Visitor. + * @param fn Member function to call on v. + * @param list List of arguments that will be splatted. + */ + template + void call(Visitor* v, Function fn, const Container& list) { + call_impl(typename make_integer_sequence::type(), v, fn, list); + } - template + // Internal implementation for call + template + void call_impl(integer_sequence, Visitor* v, Function fn, const Container& list) { + (v->*fn)(std::get(list)...); + } + + /// Function has NumArgs arguments + template struct MatcherImpl : Matcher { - std::array masks; - std::array shifts; - Function fn; + std::array masks = {}; + std::array shifts = {}; + Function fn = nullptr; virtual void visit(Visitor *v, u32 inst) override { - std::array values; - for (int i = 0; i < N; i++) { + std::array values; + for (size_t i = 0; i < NumArgs; i++) { values[i] = (inst & masks[i]) >> shifts[i]; } - Call::call(v, fn, values); + call(v, fn, values); } }; } -template -static std::unique_ptr MakeMatcher(const char* const format, Function fn) { - ASSERT(strlen(format) == 32); - - auto ret = Common::make_unique>(); +template +static std::unique_ptr MakeMatcher(const char format[32], Function fn) { + auto ret = Common::make_unique>(); ret->fn = fn; ret->masks.fill(0); ret->shifts.fill(0); char ch = 0; - int j = -1; + int arg = -1; for (int i = 0; i < 32; i++) { const u32 bit = 1 << (31 - i); @@ -81,324 +100,308 @@ static std::unique_ptr MakeMatcher(const char* const format, Function f ASSERT(format[i] != 'O'); if (format[i] != ch){ - j++; - ASSERT(j < N); + arg++; + ASSERT(arg < NumArgs); ch = format[i]; } - ret->masks[j] |= bit; - ret->shifts[j] = 31 - i; + ret->masks[arg] |= bit; + ret->shifts[arg] = 31 - i; } - ASSERT(j == N-1); + ASSERT(arg == NumArgs - 1); - return ret; + return std::unique_ptr(std::move(ret)); } -static const std::array arm_instruction_table = {{ - // Barrier instructions - { "DSB", MakeMatcher<0>("1111010101111111111100000100----", &Visitor::DSB) }, - { "DMB", MakeMatcher<0>("1111010101111111111100000101----", &Visitor::DMB) }, - { "ISB", MakeMatcher<0>("1111010101111111111100000110----", &Visitor::ISB) }, - +static const std::array arm_instruction_table = {{ // Branch instructions - { "BLX (immediate)", MakeMatcher<2>("1111101hvvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::BLX_imm) }, - { "BLX (register)", MakeMatcher<2>("cccc000100101111111111110011mmmm", &Visitor::BLX_reg) }, - { "B", MakeMatcher<2>("cccc1010vvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::B) }, - { "BL", MakeMatcher<2>("cccc1011vvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::BL) }, - { "BX", MakeMatcher<2>("cccc000100101111111111110001mmmm", &Visitor::BX) }, - { "BXJ", MakeMatcher<2>("cccc000100101111111111110010mmmm", &Visitor::BXJ) }, + { "BLX (immediate)", MakeMatcher<2>("1111101hvvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::BLX_imm) }, // ARMv5 + { "BLX (register)", MakeMatcher<2>("cccc000100101111111111110011mmmm", &Visitor::BLX_reg) }, // ARMv5 + { "B", MakeMatcher<2>("cccc1010vvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::B) }, // all + { "BL", MakeMatcher<2>("cccc1011vvvvvvvvvvvvvvvvvvvvvvvv", &Visitor::BL) }, // all + { "BX", MakeMatcher<2>("cccc000100101111111111110001mmmm", &Visitor::BX) }, // ARMv4T + { "BXJ", MakeMatcher<2>("cccc000100101111111111110010mmmm", &Visitor::BXJ) }, // ARMv5J // Coprocessor instructions - { "CDP2", MakeMatcher<0>("11111110-------------------1----", &Visitor::CDP) }, - { "CDP", MakeMatcher<0>("----1110-------------------0----", &Visitor::CDP) }, - { "LDC2", MakeMatcher<0>("1111110----1--------------------", &Visitor::LDC) }, - { "LDC", MakeMatcher<0>("----110----1--------------------", &Visitor::LDC) }, - { "MCR2", MakeMatcher<0>("----1110---0---------------1----", &Visitor::MCR) }, - { "MCR", MakeMatcher<0>("----1110---0---------------1----", &Visitor::MCR) }, - { "MCRR2", MakeMatcher<0>("111111000100--------------------", &Visitor::MCRR) }, - { "MCRR", MakeMatcher<0>("----11000100--------------------", &Visitor::MCRR) }, - { "MRC2", MakeMatcher<0>("11111110---1---------------1----", &Visitor::MRC) }, - { "MRC", MakeMatcher<0>("----1110---1---------------1----", &Visitor::MRC) }, - { "MRRC2", MakeMatcher<0>("111111000101--------------------", &Visitor::MRRC) }, - { "MRRC", MakeMatcher<0>("----11000101--------------------", &Visitor::MRRC) }, - { "STC2", MakeMatcher<0>("1111110----0--------------------", &Visitor::STC) }, - { "STC", MakeMatcher<0>("----110----0--------------------", &Visitor::STC) }, + { "CDP2", MakeMatcher<0>("11111110-------------------1----", &Visitor::CDP) }, // ARMv5 (Generic Coprocessor) + { "CDP", MakeMatcher<0>("----1110-------------------0----", &Visitor::CDP) }, // ARMv2 (Generic Coprocessor) + { "LDC2", MakeMatcher<0>("1111110----1--------------------", &Visitor::LDC) }, // ARMv5 (Generic Coprocessor) + { "LDC", MakeMatcher<0>("----110----1--------------------", &Visitor::LDC) }, // ARMv2 (Generic Coprocessor) + { "MCR2", MakeMatcher<0>("----1110---0---------------1----", &Visitor::MCR) }, // ARMv5 (Generic Coprocessor) + { "MCR", MakeMatcher<0>("----1110---0---------------1----", &Visitor::MCR) }, // ARMv2 (Generic Coprocessor) + { "MCRR2", MakeMatcher<0>("111111000100--------------------", &Visitor::MCRR) }, // ARMv6 (Generic Coprocessor) + { "MCRR", MakeMatcher<0>("----11000100--------------------", &Visitor::MCRR) }, // ARMv5E (Generic Coprocessor) + { "MRC2", MakeMatcher<0>("11111110---1---------------1----", &Visitor::MRC) }, // ARMv5 (Generic Coprocessor) + { "MRC", MakeMatcher<0>("----1110---1---------------1----", &Visitor::MRC) }, // ARMv2 (Generic Coprocessor) + { "MRRC2", MakeMatcher<0>("111111000101--------------------", &Visitor::MRRC) }, // ARMv6 (Generic Coprocessor) + { "MRRC", MakeMatcher<0>("----11000101--------------------", &Visitor::MRRC) }, // ARMv5E (Generic Coprocessor) + { "STC2", MakeMatcher<0>("1111110----0--------------------", &Visitor::STC) }, // ARMv5 (Generic Coprocessor) + { "STC", MakeMatcher<0>("----110----0--------------------", &Visitor::STC) }, // ARMv2 (Generic Coprocessor) // Data Processing instructions - { "ADC (imm)", MakeMatcher<6>("cccc0010101Snnnnddddrrrrvvvvvvvv", &Visitor::ADC_imm) }, - { "ADC (reg)", MakeMatcher<7>("cccc0000101Snnnnddddvvvvvrr0mmmm", &Visitor::ADC_reg) }, - { "ADC (rsr)", MakeMatcher<7>("cccc0000101Snnnnddddssss0rr1mmmm", &Visitor::ADC_rsr) }, - { "ADD (imm)", MakeMatcher<6>("cccc0010100Snnnnddddrrrrvvvvvvvv", &Visitor::ADD_imm) }, - { "ADD (reg)", MakeMatcher<7>("cccc0000100Snnnnddddvvvvvrr0mmmm", &Visitor::ADD_reg) }, - { "ADD (rsr)", MakeMatcher<7>("cccc0000100Snnnnddddssss0rr1mmmm", &Visitor::ADD_rsr) }, - { "AND (imm)", MakeMatcher<6>("cccc0010000Snnnnddddrrrrvvvvvvvv", &Visitor::AND_imm) }, - { "AND (reg)", MakeMatcher<7>("cccc0000000Snnnnddddvvvvvrr0mmmm", &Visitor::AND_reg) }, - { "AND (rsr)", MakeMatcher<7>("cccc0000000Snnnnddddssss0rr1mmmm", &Visitor::AND_rsr) }, - { "BIC (imm)", MakeMatcher<6>("cccc0011110Snnnnddddrrrrvvvvvvvv", &Visitor::BIC_imm) }, - { "BIC (reg)", MakeMatcher<7>("cccc0001110Snnnnddddvvvvvrr0mmmm", &Visitor::BIC_reg) }, - { "BIC (rsr)", MakeMatcher<7>("cccc0001110Snnnnddddssss0rr1mmmm", &Visitor::BIC_rsr) }, - { "CMN (imm)", MakeMatcher<4>("cccc00110111nnnn0000rrrrvvvvvvvv", &Visitor::CMN_imm) }, - { "CMN (reg)", MakeMatcher<5>("cccc00010111nnnn0000vvvvvrr0mmmm", &Visitor::CMN_reg) }, - { "CMN (rsr)", MakeMatcher<5>("cccc00010111nnnn0000ssss0rr1mmmm", &Visitor::CMN_rsr) }, - { "CMP (imm)", MakeMatcher<4>("cccc00110101nnnn0000rrrrvvvvvvvv", &Visitor::CMP_imm) }, - { "CMP (reg)", MakeMatcher<5>("cccc00010101nnnn0000vvvvvrr0mmmm", &Visitor::CMP_reg) }, - { "CMP (rsr)", MakeMatcher<5>("cccc00010101nnnn0000ssss0rr1mmmm", &Visitor::CMP_rsr) }, - { "EOR (imm)", MakeMatcher<6>("cccc0010001Snnnnddddrrrrvvvvvvvv", &Visitor::EOR_imm) }, - { "EOR (reg)", MakeMatcher<7>("cccc0000001Snnnnddddvvvvvrr0mmmm", &Visitor::EOR_reg) }, - { "EOR (rsr)", MakeMatcher<7>("cccc0000001Snnnnddddssss0rr1mmmm", &Visitor::EOR_rsr) }, - { "MOV (imm)", MakeMatcher<5>("cccc0011101S0000ddddrrrrvvvvvvvv", &Visitor::MOV_imm) }, - { "MOV (reg)", MakeMatcher<6>("cccc0001101S0000ddddvvvvvrr0mmmm", &Visitor::MOV_reg) }, - { "MOV (rsr)", MakeMatcher<6>("cccc0001101S0000ddddssss0rr1mmmm", &Visitor::MOV_rsr) }, - { "MVN (imm)", MakeMatcher<5>("cccc0011111S0000ddddrrrrvvvvvvvv", &Visitor::MVN_imm) }, - { "MVN (reg)", MakeMatcher<6>("cccc0001111S0000ddddvvvvvrr0mmmm", &Visitor::MVN_reg) }, - { "MVN (rsr)", MakeMatcher<6>("cccc0001111S0000ddddssss0rr1mmmm", &Visitor::MVN_rsr) }, - { "ORR (imm)", MakeMatcher<6>("cccc0011100Snnnnddddrrrrvvvvvvvv", &Visitor::ORR_imm) }, - { "ORR (reg)", MakeMatcher<7>("cccc0001100Snnnnddddvvvvvrr0mmmm", &Visitor::ORR_reg) }, - { "ORR (rsr)", MakeMatcher<7>("cccc0001100Snnnnddddssss0rr1mmmm", &Visitor::ORR_rsr) }, - { "RSB (imm)", MakeMatcher<6>("cccc0010011Snnnnddddrrrrvvvvvvvv", &Visitor::RSB_imm) }, - { "RSB (reg)", MakeMatcher<7>("cccc0000011Snnnnddddvvvvvrr0mmmm", &Visitor::RSB_reg) }, - { "RSB (rsr)", MakeMatcher<7>("cccc0000011Snnnnddddssss0rr1mmmm", &Visitor::RSB_rsr) }, - { "RSC (imm)", MakeMatcher<6>("cccc0010111Snnnnddddrrrrvvvvvvvv", &Visitor::RSC_imm) }, - { "RSC (reg)", MakeMatcher<7>("cccc0000111Snnnnddddvvvvvrr0mmmm", &Visitor::RSC_reg) }, - { "RSC (rsr)", MakeMatcher<7>("cccc0000111Snnnnddddssss0rr1mmmm", &Visitor::RSC_rsr) }, - { "SBC (imm)", MakeMatcher<6>("cccc0010110Snnnnddddrrrrvvvvvvvv", &Visitor::SBC_imm) }, - { "SBC (reg)", MakeMatcher<7>("cccc0000110Snnnnddddvvvvvrr0mmmm", &Visitor::SBC_reg) }, - { "SBC (rsr)", MakeMatcher<7>("cccc0000110Snnnnddddssss0rr1mmmm", &Visitor::SBC_rsr) }, - { "SUB (imm)", MakeMatcher<6>("cccc0010010Snnnnddddrrrrvvvvvvvv", &Visitor::SUB_imm) }, - { "SUB (reg)", MakeMatcher<7>("cccc0000010Snnnnddddvvvvvrr0mmmm", &Visitor::SUB_reg) }, - { "SUB (rsr)", MakeMatcher<7>("cccc0000010Snnnnddddssss0rr1mmmm", &Visitor::SUB_rsr) }, - { "TEQ (imm)", MakeMatcher<4>("cccc00110011nnnn0000rrrrvvvvvvvv", &Visitor::TEQ_imm) }, - { "TEQ (reg)", MakeMatcher<5>("cccc00010011nnnn0000vvvvvrr0mmmm", &Visitor::TEQ_reg) }, - { "TEQ (rsr)", MakeMatcher<5>("cccc00010011nnnn0000ssss0rr1mmmm", &Visitor::TEQ_rsr) }, - { "TST (imm)", MakeMatcher<4>("cccc00110001nnnn0000rrrrvvvvvvvv", &Visitor::TST_imm) }, - { "TST (reg)", MakeMatcher<5>("cccc00010001nnnn0000vvvvvrr0mmmm", &Visitor::TST_reg) }, - { "TST (rsr)", MakeMatcher<5>("cccc00010001nnnn0000ssss0rr1mmmm", &Visitor::TST_rsr) }, + { "ADC (imm)", MakeMatcher<6>("cccc0010101Snnnnddddrrrrvvvvvvvv", &Visitor::ADC_imm) }, // all + { "ADC (reg)", MakeMatcher<7>("cccc0000101Snnnnddddvvvvvrr0mmmm", &Visitor::ADC_reg) }, // all + { "ADC (rsr)", MakeMatcher<7>("cccc0000101Snnnnddddssss0rr1mmmm", &Visitor::ADC_rsr) }, // all + { "ADD (imm)", MakeMatcher<6>("cccc0010100Snnnnddddrrrrvvvvvvvv", &Visitor::ADD_imm) }, // all + { "ADD (reg)", MakeMatcher<7>("cccc0000100Snnnnddddvvvvvrr0mmmm", &Visitor::ADD_reg) }, // all + { "ADD (rsr)", MakeMatcher<7>("cccc0000100Snnnnddddssss0rr1mmmm", &Visitor::ADD_rsr) }, // all + { "AND (imm)", MakeMatcher<6>("cccc0010000Snnnnddddrrrrvvvvvvvv", &Visitor::AND_imm) }, // all + { "AND (reg)", MakeMatcher<7>("cccc0000000Snnnnddddvvvvvrr0mmmm", &Visitor::AND_reg) }, // all + { "AND (rsr)", MakeMatcher<7>("cccc0000000Snnnnddddssss0rr1mmmm", &Visitor::AND_rsr) }, // all + { "BIC (imm)", MakeMatcher<6>("cccc0011110Snnnnddddrrrrvvvvvvvv", &Visitor::BIC_imm) }, // all + { "BIC (reg)", MakeMatcher<7>("cccc0001110Snnnnddddvvvvvrr0mmmm", &Visitor::BIC_reg) }, // all + { "BIC (rsr)", MakeMatcher<7>("cccc0001110Snnnnddddssss0rr1mmmm", &Visitor::BIC_rsr) }, // all + { "CMN (imm)", MakeMatcher<4>("cccc00110111nnnn0000rrrrvvvvvvvv", &Visitor::CMN_imm) }, // all + { "CMN (reg)", MakeMatcher<5>("cccc00010111nnnn0000vvvvvrr0mmmm", &Visitor::CMN_reg) }, // all + { "CMN (rsr)", MakeMatcher<5>("cccc00010111nnnn0000ssss0rr1mmmm", &Visitor::CMN_rsr) }, // all + { "CMP (imm)", MakeMatcher<4>("cccc00110101nnnn0000rrrrvvvvvvvv", &Visitor::CMP_imm) }, // all + { "CMP (reg)", MakeMatcher<5>("cccc00010101nnnn0000vvvvvrr0mmmm", &Visitor::CMP_reg) }, // all + { "CMP (rsr)", MakeMatcher<5>("cccc00010101nnnn0000ssss0rr1mmmm", &Visitor::CMP_rsr) }, // all + { "EOR (imm)", MakeMatcher<6>("cccc0010001Snnnnddddrrrrvvvvvvvv", &Visitor::EOR_imm) }, // all + { "EOR (reg)", MakeMatcher<7>("cccc0000001Snnnnddddvvvvvrr0mmmm", &Visitor::EOR_reg) }, // all + { "EOR (rsr)", MakeMatcher<7>("cccc0000001Snnnnddddssss0rr1mmmm", &Visitor::EOR_rsr) }, // all + { "MOV (imm)", MakeMatcher<5>("cccc0011101S0000ddddrrrrvvvvvvvv", &Visitor::MOV_imm) }, // all + { "MOV (reg)", MakeMatcher<6>("cccc0001101S0000ddddvvvvvrr0mmmm", &Visitor::MOV_reg) }, // all + { "MOV (rsr)", MakeMatcher<6>("cccc0001101S0000ddddssss0rr1mmmm", &Visitor::MOV_rsr) }, // all + { "MVN (imm)", MakeMatcher<5>("cccc0011111S0000ddddrrrrvvvvvvvv", &Visitor::MVN_imm) }, // all + { "MVN (reg)", MakeMatcher<6>("cccc0001111S0000ddddvvvvvrr0mmmm", &Visitor::MVN_reg) }, // all + { "MVN (rsr)", MakeMatcher<6>("cccc0001111S0000ddddssss0rr1mmmm", &Visitor::MVN_rsr) }, // all + { "ORR (imm)", MakeMatcher<6>("cccc0011100Snnnnddddrrrrvvvvvvvv", &Visitor::ORR_imm) }, // all + { "ORR (reg)", MakeMatcher<7>("cccc0001100Snnnnddddvvvvvrr0mmmm", &Visitor::ORR_reg) }, // all + { "ORR (rsr)", MakeMatcher<7>("cccc0001100Snnnnddddssss0rr1mmmm", &Visitor::ORR_rsr) }, // all + { "RSB (imm)", MakeMatcher<6>("cccc0010011Snnnnddddrrrrvvvvvvvv", &Visitor::RSB_imm) }, // all + { "RSB (reg)", MakeMatcher<7>("cccc0000011Snnnnddddvvvvvrr0mmmm", &Visitor::RSB_reg) }, // all + { "RSB (rsr)", MakeMatcher<7>("cccc0000011Snnnnddddssss0rr1mmmm", &Visitor::RSB_rsr) }, // all + { "RSC (imm)", MakeMatcher<6>("cccc0010111Snnnnddddrrrrvvvvvvvv", &Visitor::RSC_imm) }, // all + { "RSC (reg)", MakeMatcher<7>("cccc0000111Snnnnddddvvvvvrr0mmmm", &Visitor::RSC_reg) }, // all + { "RSC (rsr)", MakeMatcher<7>("cccc0000111Snnnnddddssss0rr1mmmm", &Visitor::RSC_rsr) }, // all + { "SBC (imm)", MakeMatcher<6>("cccc0010110Snnnnddddrrrrvvvvvvvv", &Visitor::SBC_imm) }, // all + { "SBC (reg)", MakeMatcher<7>("cccc0000110Snnnnddddvvvvvrr0mmmm", &Visitor::SBC_reg) }, // all + { "SBC (rsr)", MakeMatcher<7>("cccc0000110Snnnnddddssss0rr1mmmm", &Visitor::SBC_rsr) }, // all + { "SUB (imm)", MakeMatcher<6>("cccc0010010Snnnnddddrrrrvvvvvvvv", &Visitor::SUB_imm) }, // all + { "SUB (reg)", MakeMatcher<7>("cccc0000010Snnnnddddvvvvvrr0mmmm", &Visitor::SUB_reg) }, // all + { "SUB (rsr)", MakeMatcher<7>("cccc0000010Snnnnddddssss0rr1mmmm", &Visitor::SUB_rsr) }, // all + { "TEQ (imm)", MakeMatcher<4>("cccc00110011nnnn0000rrrrvvvvvvvv", &Visitor::TEQ_imm) }, // all + { "TEQ (reg)", MakeMatcher<5>("cccc00010011nnnn0000vvvvvrr0mmmm", &Visitor::TEQ_reg) }, // all + { "TEQ (rsr)", MakeMatcher<5>("cccc00010011nnnn0000ssss0rr1mmmm", &Visitor::TEQ_rsr) }, // all + { "TST (imm)", MakeMatcher<4>("cccc00110001nnnn0000rrrrvvvvvvvv", &Visitor::TST_imm) }, // all + { "TST (reg)", MakeMatcher<5>("cccc00010001nnnn0000vvvvvrr0mmmm", &Visitor::TST_reg) }, // all + { "TST (rsr)", MakeMatcher<5>("cccc00010001nnnn0000ssss0rr1mmmm", &Visitor::TST_rsr) }, // all // Exception Generating instructions - { "BKPT", MakeMatcher<0>("----00010010------------0111----", &Visitor::BKPT) }, - { "HVC", MakeMatcher<0>("----00010100------------0111----", &Visitor::HVC) }, - { "SMC", MakeMatcher<0>("----000101100000000000000111----", &Visitor::SMC) }, - { "SVC", MakeMatcher<0>("----1111------------------------", &Visitor::SVC) }, - { "UDF", MakeMatcher<0>("111001111111------------1111----", &Visitor::UDF) }, + { "BKPT", MakeMatcher<0>("----00010010------------0111----", &Visitor::BKPT) }, // ARMv5 + { "SVC", MakeMatcher<0>("----1111------------------------", &Visitor::SVC) }, // all + { "UDF", MakeMatcher<0>("111001111111------------1111----", &Visitor::UDF) }, // all // Extension instructions - { "SXTB", MakeMatcher<0>("----011010101111------000111----", &Visitor::SXTB) }, - { "SXTB16", MakeMatcher<0>("----011010001111------000111----", &Visitor::SXTB16) }, - { "SXTH", MakeMatcher<0>("----011010111111------000111----", &Visitor::SXTH) }, - { "SXTAB", MakeMatcher<0>("----01101010----------000111----", &Visitor::SXTAB) }, - { "SXTAB16", MakeMatcher<0>("----01101000----------000111----", &Visitor::SXTAB16) }, - { "SXTAH", MakeMatcher<0>("----01101011----------000111----", &Visitor::SXTAH) }, - { "UXTB", MakeMatcher<0>("----011011101111------000111----", &Visitor::UXTB) }, - { "UXTB16", MakeMatcher<0>("----011011001111------000111----", &Visitor::UXTB16) }, - { "UXTH", MakeMatcher<0>("----011011111111------000111----", &Visitor::UXTH) }, - { "UXTAB", MakeMatcher<0>("----01101110----------000111----", &Visitor::UXTAB) }, - { "UXTAB16", MakeMatcher<0>("----01101100----------000111----", &Visitor::UXTAB16) }, - { "UXTAH", MakeMatcher<0>("----01101111----------000111----", &Visitor::UXTAH) }, + { "SXTB", MakeMatcher<0>("----011010101111------000111----", &Visitor::SXTB) }, // ARMv6 + { "SXTB16", MakeMatcher<0>("----011010001111------000111----", &Visitor::SXTB16) }, // ARMv6 + { "SXTH", MakeMatcher<0>("----011010111111------000111----", &Visitor::SXTH) }, // ARMv6 + { "SXTAB", MakeMatcher<0>("----01101010----------000111----", &Visitor::SXTAB) }, // ARMv6 + { "SXTAB16", MakeMatcher<0>("----01101000----------000111----", &Visitor::SXTAB16) }, // ARMv6 + { "SXTAH", MakeMatcher<0>("----01101011----------000111----", &Visitor::SXTAH) }, // ARMv6 + { "UXTB", MakeMatcher<0>("----011011101111------000111----", &Visitor::UXTB) }, // ARMv6 + { "UXTB16", MakeMatcher<0>("----011011001111------000111----", &Visitor::UXTB16) }, // ARMv6 + { "UXTH", MakeMatcher<0>("----011011111111------000111----", &Visitor::UXTH) }, // ARMv6 + { "UXTAB", MakeMatcher<0>("----01101110----------000111----", &Visitor::UXTAB) }, // ARMv6 + { "UXTAB16", MakeMatcher<0>("----01101100----------000111----", &Visitor::UXTAB16) }, // ARMv6 + { "UXTAH", MakeMatcher<0>("----01101111----------000111----", &Visitor::UXTAH) }, // ARMv6 // Hint instructions - { "DBG", MakeMatcher<0>("----001100100000111100001111----", &Visitor::DBG) }, - { "PLD (imm)", MakeMatcher<0>("11110101-101----1111------------", &Visitor::PLD) }, - { "PLD (lit)", MakeMatcher<0>("11110101010111111111------------", &Visitor::PLD) }, - { "PLD (reg)", MakeMatcher<0>("11110111-001----1111-------0----", &Visitor::PLD) }, - { "PLDW (imm)", MakeMatcher<0>("11110101-001----1111------------", &Visitor::PLD) }, - { "PLDW (reg)", MakeMatcher<0>("11110111-101----1111-------0----", &Visitor::PLD) }, - { "PLI (imm lit)", MakeMatcher<0>("11110100-101----1111------------", &Visitor::PLI) }, - { "PLI (reg)", MakeMatcher<0>("11110110-101----1111-------0----", &Visitor::PLI) }, + { "PLD", MakeMatcher<0>("111101---101----1111------------", &Visitor::PLD) }, // ARMv5E + { "SEV", MakeMatcher<0>("----0011001000001111000000000100", &Visitor::SEV) }, // ARMv6K + { "WFE", MakeMatcher<0>("----0011001000001111000000000010", &Visitor::WFE) }, // ARMv6K + { "WFI", MakeMatcher<0>("----0011001000001111000000000011", &Visitor::WFI) }, // ARMv6K + { "YIELD", MakeMatcher<0>("----0011001000001111000000000001", &Visitor::YIELD) }, // ARMv6K // Synchronization Primitive instructions - { "CLREX", MakeMatcher<0>("11110101011111111111000000011111", &Visitor::CLREX) }, - { "LDREX", MakeMatcher<0>("----00011001--------111110011111", &Visitor::LDREX) }, - { "LDREXB", MakeMatcher<0>("----00011101--------111110011111", &Visitor::LDREXB) }, - { "LDREXD", MakeMatcher<0>("----00011011--------111110011111", &Visitor::LDREXD) }, - { "LDREXH", MakeMatcher<0>("----00011111--------111110011111", &Visitor::LDREXH) }, - { "STREX", MakeMatcher<0>("----00011000--------11111001----", &Visitor::STREX) }, - { "STREXB", MakeMatcher<0>("----00011100--------11111001----", &Visitor::STREXB) }, - { "STREXD", MakeMatcher<0>("----00011010--------11111001----", &Visitor::STREXD) }, - { "STREXH", MakeMatcher<0>("----00011110--------11111001----", &Visitor::STREXH) }, - { "SWP", MakeMatcher<0>("----00010-00--------00001001----", &Visitor::SWP) }, + { "CLREX", MakeMatcher<0>("11110101011111111111000000011111", &Visitor::CLREX) }, // ARMv6K + { "LDREX", MakeMatcher<0>("----00011001--------111110011111", &Visitor::LDREX) }, // ARMv6 + { "LDREXB", MakeMatcher<0>("----00011101--------111110011111", &Visitor::LDREXB) }, // ARMv6K + { "LDREXD", MakeMatcher<0>("----00011011--------111110011111", &Visitor::LDREXD) }, // ARMv6K + { "LDREXH", MakeMatcher<0>("----00011111--------111110011111", &Visitor::LDREXH) }, // ARMv6K + { "STREX", MakeMatcher<0>("----00011000--------11111001----", &Visitor::STREX) }, // ARMv6 + { "STREXB", MakeMatcher<0>("----00011100--------11111001----", &Visitor::STREXB) }, // ARMv6K + { "STREXD", MakeMatcher<0>("----00011010--------11111001----", &Visitor::STREXD) }, // ARMv6K + { "STREXH", MakeMatcher<0>("----00011110--------11111001----", &Visitor::STREXH) }, // ARMv6K + { "SWP", MakeMatcher<0>("----00010-00--------00001001----", &Visitor::SWP) }, // ARMv2S // Load/Store instructions - { "LDR (imm)", MakeMatcher<0>("----010--0-1--------------------", &Visitor::LDR_imm) }, - { "LDR (reg)", MakeMatcher<0>("----011--0-1---------------0----", &Visitor::LDR_reg) }, - { "LDRB (imm)", MakeMatcher<0>("----010--1-1--------------------", &Visitor::LDRB_imm) }, - { "LDRB (reg)", MakeMatcher<0>("----011--1-1---------------0----", &Visitor::LDRB_reg) }, - { "LDRBT (A1)", MakeMatcher<0>("----0100-111--------------------", &Visitor::LDRBT) }, - { "LDRBT (A2)", MakeMatcher<0>("----0110-111---------------0----", &Visitor::LDRBT) }, - { "LDRD (imm)", MakeMatcher<0>("----000--1-0------------1101----", &Visitor::LDRD_imm) }, - { "LDRD (reg)", MakeMatcher<0>("----000--0-0--------00001101----", &Visitor::LDRD_reg) }, - { "LDRH (imm)", MakeMatcher<0>("----000--1-1------------1011----", &Visitor::LDRH_imm) }, - { "LDRH (reg)", MakeMatcher<0>("----000--0-1--------00001011----", &Visitor::LDRH_reg) }, - { "LDRHT (A1)", MakeMatcher<0>("----0000-111------------1011----", &Visitor::LDRHT) }, - { "LDRHT (A2)", MakeMatcher<0>("----0000-011--------00001011----", &Visitor::LDRHT) }, + { "LDR (imm)", MakeMatcher<0>("----010--0-1--------------------", &Visitor::LDR_imm) }, + { "LDR (reg)", MakeMatcher<0>("----011--0-1---------------0----", &Visitor::LDR_reg) }, + { "LDRB (imm)", MakeMatcher<0>("----010--1-1--------------------", &Visitor::LDRB_imm) }, + { "LDRB (reg)", MakeMatcher<0>("----011--1-1---------------0----", &Visitor::LDRB_reg) }, + { "LDRBT (A1)", MakeMatcher<0>("----0100-111--------------------", &Visitor::LDRBT) }, + { "LDRBT (A2)", MakeMatcher<0>("----0110-111---------------0----", &Visitor::LDRBT) }, + { "LDRD (imm)", MakeMatcher<0>("----000--1-0------------1101----", &Visitor::LDRD_imm) }, // ARMv5E + { "LDRD (reg)", MakeMatcher<0>("----000--0-0--------00001101----", &Visitor::LDRD_reg) }, // ARMv5E + { "LDRH (imm)", MakeMatcher<0>("----000--1-1------------1011----", &Visitor::LDRH_imm) }, + { "LDRH (reg)", MakeMatcher<0>("----000--0-1--------00001011----", &Visitor::LDRH_reg) }, + { "LDRHT (A1)", MakeMatcher<0>("----0000-111------------1011----", &Visitor::LDRHT) }, + { "LDRHT (A2)", MakeMatcher<0>("----0000-011--------00001011----", &Visitor::LDRHT) }, { "LDRSB (imm)", MakeMatcher<0>("----000--1-1------------1101----", &Visitor::LDRSB_imm) }, { "LDRSB (reg)", MakeMatcher<0>("----000--0-1--------00001101----", &Visitor::LDRSB_reg) }, - { "LDRSBT (A1)", MakeMatcher<0>("----0000-111------------1101----", &Visitor::LDRSBT) }, - { "LDRSBT (A2)", MakeMatcher<0>("----0000-011--------00001101----", &Visitor::LDRSBT) }, + { "LDRSBT (A1)", MakeMatcher<0>("----0000-111------------1101----", &Visitor::LDRSBT) }, + { "LDRSBT (A2)", MakeMatcher<0>("----0000-011--------00001101----", &Visitor::LDRSBT) }, { "LDRSH (imm)", MakeMatcher<0>("----000--1-1------------1111----", &Visitor::LDRSH_imm) }, { "LDRSH (reg)", MakeMatcher<0>("----000--0-1--------00001111----", &Visitor::LDRSH_reg) }, - { "LDRSHT (A1)", MakeMatcher<0>("----0000-111------------1111----", &Visitor::LDRSHT) }, - { "LDRSHT (A2)", MakeMatcher<0>("----0000-011--------00001111----", &Visitor::LDRSHT) }, - { "LDRT (A1)", MakeMatcher<0>("----0100-011--------------------", &Visitor::LDRT) }, - { "LDRT (A2)", MakeMatcher<0>("----0110-011---------------0----", &Visitor::LDRT) }, - { "STR (imm)", MakeMatcher<0>("----010--0-0--------------------", &Visitor::STR_imm) }, - { "STR (reg)", MakeMatcher<0>("----011--0-0---------------0----", &Visitor::STR_reg) }, - { "STRB (imm)", MakeMatcher<0>("----010--1-0--------------------", &Visitor::STRB_imm) }, - { "STRB (reg)", MakeMatcher<0>("----011--1-0---------------0----", &Visitor::STRB_reg) }, - { "STRBT (A1)", MakeMatcher<0>("----0100-110--------------------", &Visitor::STRBT) }, - { "STRBT (A2)", MakeMatcher<0>("----0110-110---------------0----", &Visitor::STRBT) }, - { "STRD (imm)", MakeMatcher<0>("----000--1-0------------1111----", &Visitor::STRD_imm) }, - { "STRD (reg)", MakeMatcher<0>("----000--0-0--------00001111----", &Visitor::STRD_reg) }, - { "STRH (imm)", MakeMatcher<0>("----000--1-0------------1011----", &Visitor::STRH_imm) }, - { "STRH (reg)", MakeMatcher<0>("----000--0-0--------00001011----", &Visitor::STRH_reg) }, - { "STRHT (A1)", MakeMatcher<0>("----0000-110------------1011----", &Visitor::STRHT) }, - { "STRHT (A2)", MakeMatcher<0>("----0000-010--------00001011----", &Visitor::STRHT) }, - { "STRT (A1)", MakeMatcher<0>("----0100-010--------------------", &Visitor::STRT) }, - { "STRT (A2)", MakeMatcher<0>("----0110-010---------------0----", &Visitor::STRT) }, + { "LDRSHT (A1)", MakeMatcher<0>("----0000-111------------1111----", &Visitor::LDRSHT) }, + { "LDRSHT (A2)", MakeMatcher<0>("----0000-011--------00001111----", &Visitor::LDRSHT) }, + { "LDRT (A1)", MakeMatcher<0>("----0100-011--------------------", &Visitor::LDRT) }, + { "LDRT (A2)", MakeMatcher<0>("----0110-011---------------0----", &Visitor::LDRT) }, + { "STR (imm)", MakeMatcher<0>("----010--0-0--------------------", &Visitor::STR_imm) }, + { "STR (reg)", MakeMatcher<0>("----011--0-0---------------0----", &Visitor::STR_reg) }, + { "STRB (imm)", MakeMatcher<0>("----010--1-0--------------------", &Visitor::STRB_imm) }, + { "STRB (reg)", MakeMatcher<0>("----011--1-0---------------0----", &Visitor::STRB_reg) }, + { "STRBT (A1)", MakeMatcher<0>("----0100-110--------------------", &Visitor::STRBT) }, + { "STRBT (A2)", MakeMatcher<0>("----0110-110---------------0----", &Visitor::STRBT) }, + { "STRD (imm)", MakeMatcher<0>("----000--1-0------------1111----", &Visitor::STRD_imm) }, // ARMv5E + { "STRD (reg)", MakeMatcher<0>("----000--0-0--------00001111----", &Visitor::STRD_reg) }, // ARMv5E + { "STRH (imm)", MakeMatcher<0>("----000--1-0------------1011----", &Visitor::STRH_imm) }, + { "STRH (reg)", MakeMatcher<0>("----000--0-0--------00001011----", &Visitor::STRH_reg) }, + { "STRHT (A1)", MakeMatcher<0>("----0000-110------------1011----", &Visitor::STRHT) }, + { "STRHT (A2)", MakeMatcher<0>("----0000-010--------00001011----", &Visitor::STRHT) }, + { "STRT (A1)", MakeMatcher<0>("----0100-010--------------------", &Visitor::STRT) }, + { "STRT (A2)", MakeMatcher<0>("----0110-010---------------0----", &Visitor::STRT) }, // Load/Store Multiple instructions - { "LDMIA/LDMFD", MakeMatcher<0>("----100010-1--------------------", &Visitor::LDM) }, - { "LDMDA/LDMFA", MakeMatcher<0>("----100000-1--------------------", &Visitor::LDM) }, - { "LDMDB/LDMEA", MakeMatcher<0>("----100100-1--------------------", &Visitor::LDM) }, - { "LDMIB/LDMED", MakeMatcher<0>("----100110-1--------------------", &Visitor::LDM) }, - { "LDM (exc ret)", MakeMatcher<0>("----100--1-1----1---------------", &Visitor::LDM) }, - { "LDM (usr reg)", MakeMatcher<0>("----100--1-1----0---------------", &Visitor::LDM) }, - { "POP", MakeMatcher<0>("----100010111101----------------", &Visitor::LDM) }, - { "POP", MakeMatcher<0>("----010010011101----000000000100", &Visitor::LDM) }, - { "PUSH", MakeMatcher<0>("----100100101101----------------", &Visitor::STM) }, - { "PUSH", MakeMatcher<0>("----010100101101----000000000100", &Visitor::STM) }, - { "STMIA/STMEA", MakeMatcher<0>("----100010-0--------------------", &Visitor::STM) }, - { "STMDA/STMED", MakeMatcher<0>("----100000-0--------------------", &Visitor::STM) }, - { "STMDB/STMFD", MakeMatcher<0>("----100100-0--------------------", &Visitor::STM) }, - { "STMIB/STMFA", MakeMatcher<0>("----100110-0--------------------", &Visitor::STM) }, - { "STMIB (usr reg)", MakeMatcher<0>("----100--100--------------------", &Visitor::STM) }, + { "LDMIA/LDMFD", MakeMatcher<0>("----100010-1--------------------", &Visitor::LDM) }, // all + { "LDMDA/LDMFA", MakeMatcher<0>("----100000-1--------------------", &Visitor::LDM) }, // all + { "LDMDB/LDMEA", MakeMatcher<0>("----100100-1--------------------", &Visitor::LDM) }, // all + { "LDMIB/LDMED", MakeMatcher<0>("----100110-1--------------------", &Visitor::LDM) }, // all + { "LDM (exc ret)", MakeMatcher<0>("----100--1-1----1---------------", &Visitor::LDM) }, // all + { "LDM (usr reg)", MakeMatcher<0>("----100--1-1----0---------------", &Visitor::LDM) }, // all + { "POP", MakeMatcher<0>("----100010111101----------------", &Visitor::LDM) }, // all + { "POP", MakeMatcher<0>("----010010011101----000000000100", &Visitor::LDM) }, // all + { "PUSH", MakeMatcher<0>("----100100101101----------------", &Visitor::STM) }, // all + { "PUSH", MakeMatcher<0>("----010100101101----000000000100", &Visitor::STM) }, // all + { "STMIA/STMEA", MakeMatcher<0>("----100010-0--------------------", &Visitor::STM) }, // all + { "STMDA/STMED", MakeMatcher<0>("----100000-0--------------------", &Visitor::STM) }, // all + { "STMDB/STMFD", MakeMatcher<0>("----100100-0--------------------", &Visitor::STM) }, // all + { "STMIB/STMFA", MakeMatcher<0>("----100110-0--------------------", &Visitor::STM) }, // all + { "STMIB (usr reg)", MakeMatcher<0>("----100--100--------------------", &Visitor::STM) }, // all // Miscellaneous instructions - { "CLZ", MakeMatcher<0>("----000101101111----11110001----", &Visitor::CLZ) }, - { "NOP", MakeMatcher<0>("----0011001000001111000000000000", &Visitor::NOP) }, - { "SEL", MakeMatcher<0>("----01101000--------11111011----", &Visitor::SEL) }, + { "CLZ", MakeMatcher<0>("----000101101111----11110001----", &Visitor::CLZ) }, // ARMv5 + { "NOP", MakeMatcher<0>("----001100100000111100000000----", &Visitor::NOP) }, // ARMv6K + { "SEL", MakeMatcher<0>("----01101000--------11111011----", &Visitor::SEL) }, // ARMv6 // Unsigned Sum of Absolute Differences instructions - { "USAD8", MakeMatcher<0>("----01111000----1111----0001----", &Visitor::USAD8) }, - { "USADA8", MakeMatcher<0>("----01111000------------0001----", &Visitor::USADA8) }, + { "USAD8", MakeMatcher<0>("----01111000----1111----0001----", &Visitor::USAD8) }, // ARMv6 + { "USADA8", MakeMatcher<0>("----01111000------------0001----", &Visitor::USADA8) }, // ARMv6 // Packing instructions - { "PKH", MakeMatcher<0>("----01101000--------------01----", &Visitor::PKH) }, + { "PKHBT", MakeMatcher<5>("cccc01101000nnnnddddvvvvv001mmmm", &Visitor::PKHBT) }, // ARMv6K + { "PKHTB", MakeMatcher<5>("cccc01101000nnnnddddvvvvv101mmmm", &Visitor::PKHTB) }, // ARMv6K // Reversal instructions - { "RBIT", MakeMatcher<0>("----011011111111----11110011----", &Visitor::RBIT) }, - { "REV", MakeMatcher<0>("----011010111111----11110011----", &Visitor::REV) }, - { "REV16", MakeMatcher<0>("----011010111111----11111011----", &Visitor::REV16) }, - { "REVSH", MakeMatcher<0>("----011011111111----11111011----", &Visitor::REVSH) }, + { "REV", MakeMatcher<0>("----011010111111----11110011----", &Visitor::REV) }, // ARMv6 + { "REV16", MakeMatcher<0>("----011010111111----11111011----", &Visitor::REV16) }, // ARMv6 + { "REVSH", MakeMatcher<0>("----011011111111----11111011----", &Visitor::REVSH) }, // ARMv6 // Saturation instructions - { "SSAT", MakeMatcher<0>("----0110101---------------01----", &Visitor::SSAT) }, - { "SSAT16", MakeMatcher<0>("----01101010--------11110011----", &Visitor::SSAT16) }, - { "USAT", MakeMatcher<0>("----0110111---------------01----", &Visitor::USAT) }, - { "USAT16", MakeMatcher<0>("----01101110--------11110011----", &Visitor::USAT16) }, + { "SSAT", MakeMatcher<0>("----0110101---------------01----", &Visitor::SSAT) }, // ARMv6 + { "SSAT16", MakeMatcher<0>("----01101010--------11110011----", &Visitor::SSAT16) }, // ARMv6 + { "USAT", MakeMatcher<0>("----0110111---------------01----", &Visitor::USAT) }, // ARMv6 + { "USAT16", MakeMatcher<0>("----01101110--------11110011----", &Visitor::USAT16) }, // ARMv6 // Multiply (Normal) instructions - { "MLA", MakeMatcher<0>("----0000001-------------1001----", &Visitor::MLA) }, - { "MLS", MakeMatcher<0>("----00000110------------1001----", &Visitor::MLS) }, - { "MUL", MakeMatcher<0>("----0000000-----0000----1001----", &Visitor::MUL) }, + { "MLA", MakeMatcher<0>("----0000001-------------1001----", &Visitor::MLA) }, // ARMv2 + { "MUL", MakeMatcher<0>("----0000000-----0000----1001----", &Visitor::MUL) }, // ARMv2 // Multiply (Long) instructions - { "SMLAL", MakeMatcher<0>("----0000111-------------1001----", &Visitor::SMLAL) }, - { "SMULL", MakeMatcher<0>("----0000110-------------1001----", &Visitor::SMULL) }, - { "UMAAL", MakeMatcher<0>("----00000100------------1001----", &Visitor::UMAAL) }, - { "UMLAL", MakeMatcher<0>("----0000101-------------1001----", &Visitor::UMLAL) }, - { "UMULL", MakeMatcher<0>("----0000100-------------1001----", &Visitor::UMULL) }, + { "SMLAL", MakeMatcher<0>("----0000111-------------1001----", &Visitor::SMLAL) }, // ARMv3M + { "SMULL", MakeMatcher<0>("----0000110-------------1001----", &Visitor::SMULL) }, // ARMv3M + { "UMAAL", MakeMatcher<0>("----00000100------------1001----", &Visitor::UMAAL) }, // ARMv6 + { "UMLAL", MakeMatcher<0>("----0000101-------------1001----", &Visitor::UMLAL) }, // ARMv3M + { "UMULL", MakeMatcher<0>("----0000100-------------1001----", &Visitor::UMULL) }, // ARMv3M // Multiply (Halfword) instructions - { "SMLALXY", MakeMatcher<0>("----00010100------------1--0----", &Visitor::SMLALxy) }, - { "SMLAXY", MakeMatcher<0>("----00010000------------1--0----", &Visitor::SMLAxy) }, - { "SMULXY", MakeMatcher<0>("----00010110----0000----1--0----", &Visitor::SMULxy) }, + { "SMLALXY", MakeMatcher<0>("----00010100------------1--0----", &Visitor::SMLALxy) }, // ARMv5xP + { "SMLAXY", MakeMatcher<0>("----00010000------------1--0----", &Visitor::SMLAxy) }, // ARMv5xP + { "SMULXY", MakeMatcher<0>("----00010110----0000----1--0----", &Visitor::SMULxy) }, // ARMv5xP // Multiply (Word by Halfword) instructions - { "SMLAWY", MakeMatcher<0>("----00010010------------1-00----", &Visitor::SMLAWy) }, - { "SMULWY", MakeMatcher<0>("----00010010----0000----1-10----", &Visitor::SMULWy) }, + { "SMLAWY", MakeMatcher<0>("----00010010------------1-00----", &Visitor::SMLAWy) }, // ARMv5xP + { "SMULWY", MakeMatcher<0>("----00010010----0000----1-10----", &Visitor::SMULWy) }, // ARMv5xP // Multiply (Most Significant Word) instructions - { "SMMUL", MakeMatcher<0>("----01110101----1111----00-1----", &Visitor::SMMUL) }, - { "SMMLA", MakeMatcher<0>("----01110101------------00-1----", &Visitor::SMMLA) }, - { "SMMLS", MakeMatcher<0>("----01110101------------11-1----", &Visitor::SMMLS) }, + { "SMMUL", MakeMatcher<0>("----01110101----1111----00-1----", &Visitor::SMMUL) }, // ARMv6 + { "SMMLA", MakeMatcher<0>("----01110101------------00-1----", &Visitor::SMMLA) }, // ARMv6 + { "SMMLS", MakeMatcher<0>("----01110101------------11-1----", &Visitor::SMMLS) }, // ARMv6 // Multiply (Dual) instructions - { "SMLAD", MakeMatcher<0>("----01110000------------00-1----", &Visitor::SMLAD) }, - { "SMLALD", MakeMatcher<0>("----01110100------------00-1----", &Visitor::SMLALD) }, - { "SMLSD", MakeMatcher<0>("----01110000------------01-1----", &Visitor::SMLSD) }, - { "SMLSLD", MakeMatcher<0>("----01110100------------01-1----", &Visitor::SMLSLD) }, - { "SMUAD", MakeMatcher<0>("----01110000----1111----00-1----", &Visitor::SMUAD) }, - { "SMUSD", MakeMatcher<0>("----01110000----1111----01-1----", &Visitor::SMUSD) }, + { "SMLAD", MakeMatcher<0>("----01110000------------00-1----", &Visitor::SMLAD) }, // ARMv6 + { "SMLALD", MakeMatcher<0>("----01110100------------00-1----", &Visitor::SMLALD) }, // ARMv6 + { "SMLSD", MakeMatcher<0>("----01110000------------01-1----", &Visitor::SMLSD) }, // ARMv6 + { "SMLSLD", MakeMatcher<0>("----01110100------------01-1----", &Visitor::SMLSLD) }, // ARMv6 + { "SMUAD", MakeMatcher<0>("----01110000----1111----00-1----", &Visitor::SMUAD) }, // ARMv6 + { "SMUSD", MakeMatcher<0>("----01110000----1111----01-1----", &Visitor::SMUSD) }, // ARMv6 // Parallel Add/Subtract (Modulo) instructions - { "SADD8", MakeMatcher<0>("----01100001--------11111001----", &Visitor::SADD8) }, - { "SADD16", MakeMatcher<0>("----01100001--------11110001----", &Visitor::SADD16) }, - { "SASX", MakeMatcher<0>("----01100001--------11110011----", &Visitor::SASX) }, - { "SSAX", MakeMatcher<0>("----01100001--------11110101----", &Visitor::SSAX) }, - { "SSUB8", MakeMatcher<0>("----01100001--------11111111----", &Visitor::SSUB8) }, - { "SSUB16", MakeMatcher<0>("----01100001--------11110111----", &Visitor::SSUB16) }, - { "UADD8", MakeMatcher<0>("----01100101--------11111001----", &Visitor::UADD8) }, - { "UADD16", MakeMatcher<0>("----01100101--------11110001----", &Visitor::UADD16) }, - { "UASX", MakeMatcher<0>("----01100101--------11110011----", &Visitor::UASX) }, - { "USAX", MakeMatcher<0>("----01100101--------11110101----", &Visitor::USAX) }, - { "USUB8", MakeMatcher<0>("----01100101--------11111111----", &Visitor::USUB8) }, - { "USUB16", MakeMatcher<0>("----01100101--------11110111----", &Visitor::USUB16) }, + { "SADD8", MakeMatcher<0>("----01100001--------11111001----", &Visitor::SADD8) }, // ARMv6 + { "SADD16", MakeMatcher<0>("----01100001--------11110001----", &Visitor::SADD16) }, // ARMv6 + { "SASX", MakeMatcher<0>("----01100001--------11110011----", &Visitor::SASX) }, // ARMv6 + { "SSAX", MakeMatcher<0>("----01100001--------11110101----", &Visitor::SSAX) }, // ARMv6 + { "SSUB8", MakeMatcher<0>("----01100001--------11111111----", &Visitor::SSUB8) }, // ARMv6 + { "SSUB16", MakeMatcher<0>("----01100001--------11110111----", &Visitor::SSUB16) }, // ARMv6 + { "UADD8", MakeMatcher<0>("----01100101--------11111001----", &Visitor::UADD8) }, // ARMv6 + { "UADD16", MakeMatcher<0>("----01100101--------11110001----", &Visitor::UADD16) }, // ARMv6 + { "UASX", MakeMatcher<0>("----01100101--------11110011----", &Visitor::UASX) }, // ARMv6 + { "USAX", MakeMatcher<0>("----01100101--------11110101----", &Visitor::USAX) }, // ARMv6 + { "USUB8", MakeMatcher<0>("----01100101--------11111111----", &Visitor::USUB8) }, // ARMv6 + { "USUB16", MakeMatcher<0>("----01100101--------11110111----", &Visitor::USUB16) }, // ARMv6 // Parallel Add/Subtract (Saturating) instructions - { "QADD8", MakeMatcher<0>("----01100010--------11111001----", &Visitor::QADD8) }, - { "QADD16", MakeMatcher<0>("----01100010--------11110001----", &Visitor::QADD16) }, - { "QASX", MakeMatcher<0>("----01100010--------11110011----", &Visitor::QASX) }, - { "QSAX", MakeMatcher<0>("----01100010--------11110101----", &Visitor::QSAX) }, - { "QSUB8", MakeMatcher<0>("----01100010--------11111111----", &Visitor::QSUB8) }, - { "QSUB16", MakeMatcher<0>("----01100010--------11110111----", &Visitor::QSUB16) }, - { "UQADD8", MakeMatcher<0>("----01100110--------11111001----", &Visitor::UQADD8) }, - { "UQADD16", MakeMatcher<0>("----01100110--------11110001----", &Visitor::UQADD16) }, - { "UQASX", MakeMatcher<0>("----01100110--------11110011----", &Visitor::UQASX) }, - { "UQSAX", MakeMatcher<0>("----01100110--------11110101----", &Visitor::UQSAX) }, - { "UQSUB8", MakeMatcher<0>("----01100110--------11111111----", &Visitor::UQSUB8) }, - { "UQSUB16", MakeMatcher<0>("----01100110--------11110111----", &Visitor::UQSUB16) }, + { "QADD8", MakeMatcher<0>("----01100010--------11111001----", &Visitor::QADD8) }, // ARMv6 + { "QADD16", MakeMatcher<0>("----01100010--------11110001----", &Visitor::QADD16) }, // ARMv6 + { "QASX", MakeMatcher<0>("----01100010--------11110011----", &Visitor::QASX) }, // ARMv6 + { "QSAX", MakeMatcher<0>("----01100010--------11110101----", &Visitor::QSAX) }, // ARMv6 + { "QSUB8", MakeMatcher<0>("----01100010--------11111111----", &Visitor::QSUB8) }, // ARMv6 + { "QSUB16", MakeMatcher<0>("----01100010--------11110111----", &Visitor::QSUB16) }, // ARMv6 + { "UQADD8", MakeMatcher<0>("----01100110--------11111001----", &Visitor::UQADD8) }, // ARMv6 + { "UQADD16", MakeMatcher<0>("----01100110--------11110001----", &Visitor::UQADD16) }, // ARMv6 + { "UQASX", MakeMatcher<0>("----01100110--------11110011----", &Visitor::UQASX) }, // ARMv6 + { "UQSAX", MakeMatcher<0>("----01100110--------11110101----", &Visitor::UQSAX) }, // ARMv6 + { "UQSUB8", MakeMatcher<0>("----01100110--------11111111----", &Visitor::UQSUB8) }, // ARMv6 + { "UQSUB16", MakeMatcher<0>("----01100110--------11110111----", &Visitor::UQSUB16) }, // ARMv6 // Parallel Add/Subtract (Halving) instructions - { "SHADD8", MakeMatcher<0>("----01100011--------11111001----", &Visitor::SHADD8) }, - { "SHADD16", MakeMatcher<0>("----01100011--------11110001----", &Visitor::SHADD16) }, - { "SHASX", MakeMatcher<0>("----01100011--------11110011----", &Visitor::SHASX) }, - { "SHSAX", MakeMatcher<0>("----01100011--------11110101----", &Visitor::SHSAX) }, - { "SHSUB8", MakeMatcher<0>("----01100011--------11111111----", &Visitor::SHSUB8) }, - { "SHSUB16", MakeMatcher<0>("----01100011--------11110111----", &Visitor::SHSUB16) }, - { "UHADD8", MakeMatcher<0>("----01100111--------11111001----", &Visitor::UHADD8) }, - { "UHADD16", MakeMatcher<0>("----01100111--------11110001----", &Visitor::UHADD16) }, - { "UHASX", MakeMatcher<0>("----01100111--------11110011----", &Visitor::UHASX) }, - { "UHSAX", MakeMatcher<0>("----01100111--------11110101----", &Visitor::UHSAX) }, - { "UHSUB8", MakeMatcher<0>("----01100111--------11111111----", &Visitor::UHSUB8) }, - { "UHSUB16", MakeMatcher<0>("----01100111--------11110111----", &Visitor::UHSUB16) }, + { "SHADD8", MakeMatcher<0>("----01100011--------11111001----", &Visitor::SHADD8) }, // ARMv6 + { "SHADD16", MakeMatcher<0>("----01100011--------11110001----", &Visitor::SHADD16) }, // ARMv6 + { "SHASX", MakeMatcher<0>("----01100011--------11110011----", &Visitor::SHASX) }, // ARMv6 + { "SHSAX", MakeMatcher<0>("----01100011--------11110101----", &Visitor::SHSAX) }, // ARMv6 + { "SHSUB8", MakeMatcher<0>("----01100011--------11111111----", &Visitor::SHSUB8) }, // ARMv6 + { "SHSUB16", MakeMatcher<0>("----01100011--------11110111----", &Visitor::SHSUB16) }, // ARMv6 + { "UHADD8", MakeMatcher<0>("----01100111--------11111001----", &Visitor::UHADD8) }, // ARMv6 + { "UHADD16", MakeMatcher<0>("----01100111--------11110001----", &Visitor::UHADD16) }, // ARMv6 + { "UHASX", MakeMatcher<0>("----01100111--------11110011----", &Visitor::UHASX) }, // ARMv6 + { "UHSAX", MakeMatcher<0>("----01100111--------11110101----", &Visitor::UHSAX) }, // ARMv6 + { "UHSUB8", MakeMatcher<0>("----01100111--------11111111----", &Visitor::UHSUB8) }, // ARMv6 + { "UHSUB16", MakeMatcher<0>("----01100111--------11110111----", &Visitor::UHSUB16) }, // ARMv6 // Saturated Add/Subtract instructions - { "QADD", MakeMatcher<0>("----00010000--------00000101----", &Visitor::QADD) }, - { "QSUB", MakeMatcher<0>("----00010010--------00000101----", &Visitor::QSUB) }, - { "QDADD", MakeMatcher<0>("----00010100--------00000101----", &Visitor::QDADD) }, - { "QDSUB", MakeMatcher<0>("----00010110--------00000101----", &Visitor::QDSUB) }, + { "QADD", MakeMatcher<0>("----00010000--------00000101----", &Visitor::QADD) }, // ARMv5xP + { "QSUB", MakeMatcher<0>("----00010010--------00000101----", &Visitor::QSUB) }, // ARMv5xP + { "QDADD", MakeMatcher<0>("----00010100--------00000101----", &Visitor::QDADD) }, // ARMv5xP + { "QDSUB", MakeMatcher<0>("----00010110--------00000101----", &Visitor::QDSUB) }, // ARMv5xP // Status Register Access instructions - { "CPS", MakeMatcher<0>("----00010000---00000000---0-----", &Visitor::CPS) }, - { "ERET", MakeMatcher<0>("----0001011000000000000001101110", &Visitor::ERET) }, - { "SETEND", MakeMatcher<0>("1111000100000001000000-000000000", &Visitor::SETEND) }, - { "MRS", MakeMatcher<0>("----000100001111----000000000000", &Visitor::MRS) }, - { "MRS (banked)", MakeMatcher<0>("----00010-00--------001-00000000", &Visitor::MRS) }, - { "MRS (system)", MakeMatcher<0>("----00010-001111----000000000000", &Visitor::MRS) }, - { "MSR (imm)", MakeMatcher<0>("----00110010--001111------------", &Visitor::MSR) }, - { "MSR (reg)", MakeMatcher<0>("----00010010--00111100000000----", &Visitor::MSR) }, - { "MSR (banked)", MakeMatcher<0>("----00010-10----1111001-0000----", &Visitor::MSR) }, - { "MSR (imm special)", MakeMatcher<0>("----00110-10----1111------------", &Visitor::MSR) }, - { "MSR (reg special)", MakeMatcher<0>("----00010-10----111100000000----", &Visitor::MSR) }, - { "RFE", MakeMatcher<0>("----0001101-0000---------110----", &Visitor::RFE) }, - { "SRS", MakeMatcher<0>("0000011--0-00000000000000001----", &Visitor::SRS) }, + { "CPS", MakeMatcher<0>("111100010000---00000000---0-----", &Visitor::CPS) }, // ARMv6 + { "SETEND", MakeMatcher<1>("1111000100000001000000e000000000", &Visitor::SETEND) }, // ARMv6 + { "MRS", MakeMatcher<0>("----00010-00--------00--00000000", &Visitor::MRS) }, // ARMv3 + { "MSR", MakeMatcher<0>("----00-10-10----1111------------", &Visitor::MSR) }, // ARMv3 + { "RFE", MakeMatcher<0>("----0001101-0000---------110----", &Visitor::RFE) }, // ARMv6 + { "SRS", MakeMatcher<0>("0000011--0-00000000000000001----", &Visitor::SRS) }, // ARMv6 }}; -const Instruction& DecodeArm(u32 i) { - return *std::find_if(arm_instruction_table.cbegin(), arm_instruction_table.cend(), [i](const auto& instruction) { +boost::optional DecodeArm(u32 i) { + auto iterator = std::find_if(arm_instruction_table.cbegin(), arm_instruction_table.cend(), [i](const Instruction& instruction) { return instruction.Match(i); }); + + return iterator != arm_instruction_table.cend() ? boost::make_optional(*iterator) : boost::none; } }; diff --git a/src/core/arm/decoder/decoder.h b/src/core/arm/decoder/decoder.h index 9cca91b69..41b44aab2 100644 --- a/src/core/arm/decoder/decoder.h +++ b/src/core/arm/decoder/decoder.h @@ -8,6 +8,8 @@ #include #include +#include + #include "common/common_types.h" #include "common/common_funcs.h" @@ -18,7 +20,7 @@ namespace ArmDecoder { class Instruction; class Visitor; -const Instruction& DecodeArm(u32 instruction); +boost::optional DecodeArm(u32 instruction); const Instruction& DecodeThumb(u16 instruction); struct Matcher { @@ -60,11 +62,6 @@ class Visitor { public: virtual ~Visitor() = default; - // Barrier instructions - virtual void DMB() = 0; - virtual void DSB() = 0; - virtual void ISB() = 0; - // Branch instructions virtual void B(Cond cond, Imm24 imm24) = 0; virtual void BL(Cond cond, Imm24 imm24) = 0; @@ -134,8 +131,6 @@ public: // Exception generation instructions virtual void BKPT() = 0; - virtual void HVC() = 0; - virtual void SMC() = 0; virtual void SVC() = 0; virtual void UDF() = 0; @@ -154,9 +149,11 @@ public: virtual void UXTH() = 0; // Hint instructions - virtual void DBG() = 0; virtual void PLD() = 0; - virtual void PLI() = 0; + virtual void SEV() = 0; + virtual void WFE() = 0; + virtual void WFI() = 0; + virtual void YIELD() = 0; // Load/Store instructions virtual void LDR_imm() = 0; @@ -194,7 +191,6 @@ public: // Miscellaneous instructions virtual void CLZ() = 0; - virtual void ERET() = 0; virtual void NOP() = 0; virtual void SEL() = 0; @@ -203,10 +199,10 @@ public: virtual void USADA8() = 0; // Packing instructions - virtual void PKH() = 0; + virtual void PKHBT(Cond cond, Register Rn, Register Rd, Imm5 imm5, Register Rm) = 0; + virtual void PKHTB(Cond cond, Register Rn, Register Rd, Imm5 imm5, Register Rm) = 0; // Reversal instructions - virtual void RBIT() = 0; virtual void REV() = 0; virtual void REV16() = 0; virtual void REVSH() = 0; @@ -219,7 +215,6 @@ public: // Multiply (Normal) instructions virtual void MLA() = 0; - virtual void MLS() = 0; virtual void MUL() = 0; // Multiply (Long) instructions @@ -316,7 +311,7 @@ public: virtual void MRS() = 0; virtual void MSR() = 0; virtual void RFE() = 0; - virtual void SETEND() = 0; + virtual void SETEND(bool E) = 0; virtual void SRS() = 0; // Thumb specific instructions diff --git a/src/core/arm/decoder/thumb.cpp b/src/core/arm/decoder/thumb.cpp index 4cec9258a..f988b42be 100644 --- a/src/core/arm/decoder/thumb.cpp +++ b/src/core/arm/decoder/thumb.cpp @@ -364,7 +364,7 @@ static const std::array thumb_instruction_table = { { })}, { "SETEND", MakeMatcher("101101100101x000", [](Visitor* v, u32 instruction) { bool E = bits<3, 3>(instruction); - v->SETEND(); + v->SETEND(E); })}, { "change processor state", MakeMatcher("10110110011x0xxx", [](Visitor* v, u32 instruction) { bool imod = bits<4, 4>(instruction); diff --git a/src/core/arm/jit_x64/instructions/barrier.cpp b/src/core/arm/jit_x64/instructions/barrier.cpp deleted file mode 100644 index 8034bb181..000000000 --- a/src/core/arm/jit_x64/instructions/barrier.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "core/arm/jit_x64/jit_x64.h" - -namespace JitX64 { - -void JitX64::DMB() { CompileInterpretInstruction(); } -void JitX64::DSB() { CompileInterpretInstruction(); } -void JitX64::ISB() { CompileInterpretInstruction(); } - -} diff --git a/src/core/arm/jit_x64/instructions/exception_generating.cpp b/src/core/arm/jit_x64/instructions/exception_generating.cpp index 111ee3263..07ae2faa0 100644 --- a/src/core/arm/jit_x64/instructions/exception_generating.cpp +++ b/src/core/arm/jit_x64/instructions/exception_generating.cpp @@ -7,8 +7,6 @@ namespace JitX64 { void JitX64::BKPT() { CompileInterpretInstruction(); } -void JitX64::HVC() { CompileInterpretInstruction(); } -void JitX64::SMC() { CompileInterpretInstruction(); } void JitX64::SVC() { CompileInterpretInstruction(); } void JitX64::UDF() { CompileInterpretInstruction(); } diff --git a/src/core/arm/jit_x64/instructions/hint.cpp b/src/core/arm/jit_x64/instructions/hint.cpp index 101bd1c38..e2030bc71 100644 --- a/src/core/arm/jit_x64/instructions/hint.cpp +++ b/src/core/arm/jit_x64/instructions/hint.cpp @@ -6,8 +6,10 @@ namespace JitX64 { -void JitX64::DBG() { CompileInterpretInstruction(); } +void JitX64::SEV() { CompileInterpretInstruction(); } void JitX64::PLD() { CompileInterpretInstruction(); } -void JitX64::PLI() { CompileInterpretInstruction(); } +void JitX64::WFI() { CompileInterpretInstruction(); } +void JitX64::WFE() { CompileInterpretInstruction(); } +void JitX64::YIELD() { CompileInterpretInstruction(); } } diff --git a/src/core/arm/jit_x64/instructions/misc.cpp b/src/core/arm/jit_x64/instructions/misc.cpp index 85fb3a1a8..ae4a1e531 100644 --- a/src/core/arm/jit_x64/instructions/misc.cpp +++ b/src/core/arm/jit_x64/instructions/misc.cpp @@ -7,7 +7,6 @@ namespace JitX64 { void JitX64::CLZ() { CompileInterpretInstruction(); } -void JitX64::ERET() { CompileInterpretInstruction(); } void JitX64::NOP() { CompileInterpretInstruction(); } void JitX64::SEL() { CompileInterpretInstruction(); } diff --git a/src/core/arm/jit_x64/instructions/multiply.cpp b/src/core/arm/jit_x64/instructions/multiply.cpp index 86b23fb90..a0311af5f 100644 --- a/src/core/arm/jit_x64/instructions/multiply.cpp +++ b/src/core/arm/jit_x64/instructions/multiply.cpp @@ -8,7 +8,6 @@ namespace JitX64 { // Multiply (Normal) instructions void JitX64::MLA() { CompileInterpretInstruction(); } -void JitX64::MLS() { CompileInterpretInstruction(); } void JitX64::MUL() { CompileInterpretInstruction(); } // Multiply (Long) instructions diff --git a/src/core/arm/jit_x64/instructions/packing.cpp b/src/core/arm/jit_x64/instructions/packing.cpp index 097b0e1ae..90f7ce848 100644 --- a/src/core/arm/jit_x64/instructions/packing.cpp +++ b/src/core/arm/jit_x64/instructions/packing.cpp @@ -6,6 +6,7 @@ namespace JitX64 { -void JitX64::PKH() { CompileInterpretInstruction(); } +void JitX64::PKHBT(Cond cond, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ArmReg Rm) { CompileInterpretInstruction(); } +void JitX64::PKHTB(Cond cond, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ArmReg Rm) { CompileInterpretInstruction(); } } diff --git a/src/core/arm/jit_x64/instructions/reversal.cpp b/src/core/arm/jit_x64/instructions/reversal.cpp index 5021f23f8..749e1998c 100644 --- a/src/core/arm/jit_x64/instructions/reversal.cpp +++ b/src/core/arm/jit_x64/instructions/reversal.cpp @@ -6,7 +6,6 @@ namespace JitX64 { -void JitX64::RBIT() { CompileInterpretInstruction(); } void JitX64::REV() { CompileInterpretInstruction(); } void JitX64::REV16() { CompileInterpretInstruction(); } void JitX64::REVSH() { CompileInterpretInstruction(); } diff --git a/src/core/arm/jit_x64/instructions/status_register.cpp b/src/core/arm/jit_x64/instructions/status_register.cpp index e1707e042..82a168848 100644 --- a/src/core/arm/jit_x64/instructions/status_register.cpp +++ b/src/core/arm/jit_x64/instructions/status_register.cpp @@ -10,7 +10,7 @@ void JitX64::CPS() { CompileInterpretInstruction(); } void JitX64::MRS() { CompileInterpretInstruction(); } void JitX64::MSR() { CompileInterpretInstruction(); } void JitX64::RFE() { CompileInterpretInstruction(); } -void JitX64::SETEND() { CompileInterpretInstruction(); } +void JitX64::SETEND(bool E) { CompileInterpretInstruction(); } void JitX64::SRS() { CompileInterpretInstruction(); } } diff --git a/src/core/arm/jit_x64/jit_x64.cpp b/src/core/arm/jit_x64/jit_x64.cpp index 79084f625..850dfee2f 100644 --- a/src/core/arm/jit_x64/jit_x64.cpp +++ b/src/core/arm/jit_x64/jit_x64.cpp @@ -133,7 +133,13 @@ void JitX64::Patch(LocationDescriptor desc, CodePtr bb) { void JitX64::CompileSingleArmInstruction() { u32 inst = Memory::Read32(current.arm_pc & 0xFFFFFFFC); - ArmDecoder::DecodeArm(inst).Visit(this, inst); + auto inst_info = ArmDecoder::DecodeArm(inst); + if (!inst_info) { + // TODO: Log message + CompileInterpretInstruction(); + } else { + inst_info->Visit(this, inst); + } } void JitX64::CompileSingleThumbInstruction() { diff --git a/src/core/arm/jit_x64/jit_x64.h b/src/core/arm/jit_x64/jit_x64.h index ffd2832cd..da4333d8a 100644 --- a/src/core/arm/jit_x64/jit_x64.h +++ b/src/core/arm/jit_x64/jit_x64.h @@ -46,7 +46,7 @@ private: public: JitX64() = delete; JitX64(Gen::XEmitter* code_); - virtual ~JitX64() override {} + ~JitX64() override {} void ClearCache(); @@ -133,270 +133,263 @@ private: private: void CompileInterpretInstruction(); - // Barrier instructions - virtual void DMB() override; - virtual void DSB() override; - virtual void ISB() override; - // Branch instructions - virtual void B(Cond cond, ArmImm24 imm24) override; - virtual void BL(Cond cond, ArmImm24 imm24) override; - virtual void BLX_imm(bool H, ArmImm24 imm24) override; - virtual void BLX_reg(Cond cond, ArmReg Rm) override; - virtual void BX(Cond cond, ArmReg Rm) override; - virtual void BXJ(Cond cond, ArmReg Rm) override; + void B(Cond cond, ArmImm24 imm24) override; + void BL(Cond cond, ArmImm24 imm24) override; + void BLX_imm(bool H, ArmImm24 imm24) override; + void BLX_reg(Cond cond, ArmReg Rm) override; + void BX(Cond cond, ArmReg Rm) override; + void BXJ(Cond cond, ArmReg Rm) override; // Coprocessor instructions - virtual void CDP() override; - virtual void LDC() override; - virtual void MCR() override; - virtual void MCRR() override; - virtual void MRC() override; - virtual void MRRC() override; - virtual void STC() override; + void CDP() override; + void LDC() override; + void MCR() override; + void MCRR() override; + void MRC() override; + void MRRC() override; + void STC() override; // Data processing instructions void CompileDataProcessingHelper(ArmReg Rn_index, ArmReg Rd_index, std::function body); void CompileDataProcessingHelper_Reverse(ArmReg Rn_index, ArmReg Rd_index, std::function body); - virtual void ADC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void ADC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void ADC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void ADD_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void ADD_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void ADD_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void AND_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void AND_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void AND_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void BIC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void BIC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void BIC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void CMN_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; - virtual void CMN_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void CMN_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void CMP_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; - virtual void CMP_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void CMP_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void EOR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void EOR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void EOR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void MOV_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void MOV_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void MOV_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void MVN_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void MVN_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void MVN_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void ORR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void ORR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void ORR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void RSB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void RSB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void RSB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void RSC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void RSC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void RSC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void SBC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void SBC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void SBC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void SUB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; - virtual void SUB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void SUB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void TEQ_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; - virtual void TEQ_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void TEQ_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; - virtual void TST_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; - virtual void TST_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; - virtual void TST_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void ADC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void ADC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void ADC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void ADD_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void ADD_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void ADD_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void AND_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void AND_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void AND_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void BIC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void BIC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void BIC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void CMN_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; + void CMN_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void CMN_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void CMP_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; + void CMP_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void CMP_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void EOR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void EOR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void EOR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void MOV_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void MOV_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void MOV_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void MVN_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void MVN_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void MVN_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void ORR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void ORR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void ORR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void RSB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void RSB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void RSB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void RSC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void RSC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void RSC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void SBC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void SBC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void SBC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void SUB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override; + void SUB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void SUB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void TEQ_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; + void TEQ_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void TEQ_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; + void TST_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) override; + void TST_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override; + void TST_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) override; // Exception generation instructions - virtual void BKPT() override; - virtual void HVC() override; - virtual void SMC() override; - virtual void SVC() override; - virtual void UDF() override; + void BKPT() override; + void SVC() override; + void UDF() override; // Extension functions - virtual void SXTAB() override; - virtual void SXTAB16() override; - virtual void SXTAH() override; - virtual void SXTB() override; - virtual void SXTB16() override; - virtual void SXTH() override; - virtual void UXTAB() override; - virtual void UXTAB16() override; - virtual void UXTAH() override; - virtual void UXTB() override; - virtual void UXTB16() override; - virtual void UXTH() override; + void SXTAB() override; + void SXTAB16() override; + void SXTAH() override; + void SXTB() override; + void SXTB16() override; + void SXTH() override; + void UXTAB() override; + void UXTAB16() override; + void UXTAH() override; + void UXTB() override; + void UXTB16() override; + void UXTH() override; // Hint instructions - virtual void DBG() override; - virtual void PLD() override; - virtual void PLI() override; + void PLD() override; + void SEV() override; + void WFE() override; + void WFI() override; + void YIELD() override; // Load/Store instructions - virtual void LDR_imm() override; - virtual void LDR_reg() override; - virtual void LDRB_imm() override; - virtual void LDRB_reg() override; - virtual void LDRBT() override; - virtual void LDRD_imm() override; - virtual void LDRD_reg() override; - virtual void LDRH_imm() override; - virtual void LDRH_reg() override; - virtual void LDRHT() override; - virtual void LDRSB_imm() override; - virtual void LDRSB_reg() override; - virtual void LDRSBT() override; - virtual void LDRSH_imm() override; - virtual void LDRSH_reg() override; - virtual void LDRSHT() override; - virtual void LDRT() override; - virtual void STR_imm() override; - virtual void STR_reg() override; - virtual void STRB_imm() override; - virtual void STRB_reg() override; - virtual void STRBT() override; - virtual void STRD_imm() override; - virtual void STRD_reg() override; - virtual void STRH_imm() override; - virtual void STRH_reg() override; - virtual void STRHT() override; - virtual void STRT() override; + void LDR_imm() override; + void LDR_reg() override; + void LDRB_imm() override; + void LDRB_reg() override; + void LDRBT() override; + void LDRD_imm() override; + void LDRD_reg() override; + void LDRH_imm() override; + void LDRH_reg() override; + void LDRHT() override; + void LDRSB_imm() override; + void LDRSB_reg() override; + void LDRSBT() override; + void LDRSH_imm() override; + void LDRSH_reg() override; + void LDRSHT() override; + void LDRT() override; + void STR_imm() override; + void STR_reg() override; + void STRB_imm() override; + void STRB_reg() override; + void STRBT() override; + void STRD_imm() override; + void STRD_reg() override; + void STRH_imm() override; + void STRH_reg() override; + void STRHT() override; + void STRT() override; // Load/Store multiple instructions - virtual void LDM() override; - virtual void STM() override; + void LDM() override; + void STM() override; // Miscellaneous instructions - virtual void CLZ() override; - virtual void ERET() override; - virtual void NOP() override; - virtual void SEL() override; + void CLZ() override; + void NOP() override; + void SEL() override; // Unsigned sum of absolute difference functions - virtual void USAD8() override; - virtual void USADA8() override; + void USAD8() override; + void USADA8() override; // Packing instructions - virtual void PKH() override; + void PKHBT(Cond cond, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ArmReg Rm) override; + void PKHTB(Cond cond, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ArmReg Rm) override; // Reversal instructions - virtual void RBIT() override; - virtual void REV() override; - virtual void REV16() override; - virtual void REVSH() override; + void REV() override; + void REV16() override; + void REVSH() override; // Saturation instructions - virtual void SSAT() override; - virtual void SSAT16() override; - virtual void USAT() override; - virtual void USAT16() override; + void SSAT() override; + void SSAT16() override; + void USAT() override; + void USAT16() override; // Multiply (Normal) instructions - virtual void MLA() override; - virtual void MLS() override; - virtual void MUL() override; + void MLA() override; + void MUL() override; // Multiply (Long) instructions - virtual void SMLAL() override; - virtual void SMULL() override; - virtual void UMAAL() override; - virtual void UMLAL() override; - virtual void UMULL() override; + void SMLAL() override; + void SMULL() override; + void UMAAL() override; + void UMLAL() override; + void UMULL() override; // Multiply (Halfword) instructions - virtual void SMLALxy() override; - virtual void SMLAxy() override; - virtual void SMULxy() override; + void SMLALxy() override; + void SMLAxy() override; + void SMULxy() override; // Multiply (word by halfword) instructions - virtual void SMLAWy() override; - virtual void SMULWy() override; + void SMLAWy() override; + void SMULWy() override; // Multiply (Most significant word) instructions - virtual void SMMLA() override; - virtual void SMMLS() override; - virtual void SMMUL() override; + void SMMLA() override; + void SMMLS() override; + void SMMUL() override; // Multiply (Dual) instructions - virtual void SMLAD() override; - virtual void SMLALD() override; - virtual void SMLSD() override; - virtual void SMLSLD() override; - virtual void SMUAD() override; - virtual void SMUSD() override; + void SMLAD() override; + void SMLALD() override; + void SMLSD() override; + void SMLSLD() override; + void SMUAD() override; + void SMUSD() override; // Parallel Add/Subtract (Modulo arithmetic) instructions - virtual void SADD8() override; - virtual void SADD16() override; - virtual void SASX() override; - virtual void SSAX() override; - virtual void SSUB8() override; - virtual void SSUB16() override; - virtual void UADD8() override; - virtual void UADD16() override; - virtual void UASX() override; - virtual void USAX() override; - virtual void USUB8() override; - virtual void USUB16() override; + void SADD8() override; + void SADD16() override; + void SASX() override; + void SSAX() override; + void SSUB8() override; + void SSUB16() override; + void UADD8() override; + void UADD16() override; + void UASX() override; + void USAX() override; + void USUB8() override; + void USUB16() override; // Parallel Add/Subtract (Saturating) instructions - virtual void QADD8() override; - virtual void QADD16() override; - virtual void QASX() override; - virtual void QSAX() override; - virtual void QSUB8() override; - virtual void QSUB16() override; - virtual void UQADD8() override; - virtual void UQADD16() override; - virtual void UQASX() override; - virtual void UQSAX() override; - virtual void UQSUB8() override; - virtual void UQSUB16() override; + void QADD8() override; + void QADD16() override; + void QASX() override; + void QSAX() override; + void QSUB8() override; + void QSUB16() override; + void UQADD8() override; + void UQADD16() override; + void UQASX() override; + void UQSAX() override; + void UQSUB8() override; + void UQSUB16() override; // Parallel Add/Subtract (Halving) instructions - virtual void SHADD8() override; - virtual void SHADD16() override; - virtual void SHASX() override; - virtual void SHSAX() override; - virtual void SHSUB8() override; - virtual void SHSUB16() override; - virtual void UHADD8() override; - virtual void UHADD16() override; - virtual void UHASX() override; - virtual void UHSAX() override; - virtual void UHSUB8() override; - virtual void UHSUB16() override; + void SHADD8() override; + void SHADD16() override; + void SHASX() override; + void SHSAX() override; + void SHSUB8() override; + void SHSUB16() override; + void UHADD8() override; + void UHADD16() override; + void UHASX() override; + void UHSAX() override; + void UHSUB8() override; + void UHSUB16() override; // Saturated Add/Subtract instructions - virtual void QADD() override; - virtual void QSUB() override; - virtual void QDADD() override; - virtual void QDSUB() override; + void QADD() override; + void QSUB() override; + void QDADD() override; + void QDSUB() override; // Synchronization Primitive instructions - virtual void CLREX() override; - virtual void LDREX() override; - virtual void LDREXB() override; - virtual void LDREXD() override; - virtual void LDREXH() override; - virtual void STREX() override; - virtual void STREXB() override; - virtual void STREXD() override; - virtual void STREXH() override; - virtual void SWP() override; + void CLREX() override; + void LDREX() override; + void LDREXB() override; + void LDREXD() override; + void LDREXH() override; + void STREX() override; + void STREXB() override; + void STREXD() override; + void STREXH() override; + void SWP() override; // Status register access instructions - virtual void CPS() override; - virtual void MRS() override; - virtual void MSR() override; - virtual void RFE() override; - virtual void SETEND() override; - virtual void SRS() override; + void CPS() override; + void MRS() override; + void MSR() override; + void RFE() override; + void SETEND(bool E) override; + void SRS() override; // Thumb specific instructions - virtual void thumb_BLX_prefix(ArmImm11 imm11) override; - virtual void thumb_BLX_suffix(bool L, ArmImm11 imm11) override; + void thumb_BLX_prefix(ArmImm11 imm11) override; + void thumb_BLX_suffix(bool L, ArmImm11 imm11) override; }; }