JitX64: Initial implementation of JitX64 compiler

This commit is contained in:
MerryMage 2016-03-20 02:59:31 +00:00
parent e34c66d62b
commit b9a852b048
26 changed files with 1219 additions and 0 deletions

View File

@ -266,11 +266,36 @@ 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
arm/jit_x64/instructions/exception_generating.cpp
arm/jit_x64/instructions/extension.cpp
arm/jit_x64/instructions/hint.cpp
arm/jit_x64/instructions/load_store.cpp
arm/jit_x64/instructions/misc.cpp
arm/jit_x64/instructions/usad.cpp
arm/jit_x64/instructions/packing.cpp
arm/jit_x64/instructions/reversal.cpp
arm/jit_x64/instructions/saturation.cpp
arm/jit_x64/instructions/multiply.cpp
arm/jit_x64/instructions/parallel_add_subtract_modulo.cpp
arm/jit_x64/instructions/parallel_add_subtract_saturating.cpp
arm/jit_x64/instructions/parallel_add_subtract_halving.cpp
arm/jit_x64/instructions/qadd_qsub.cpp
arm/jit_x64/instructions/synchronisation.cpp
arm/jit_x64/instructions/status_register.cpp
arm/jit_x64/instructions/thumb.cpp
arm/jit_x64/interpret.cpp
arm/jit_x64/jit_x64.cpp
arm/jit_x64/reg_alloc.cpp
)
set(HEADERS ${HEADERS}
arm/jit_x64/common.h
arm/jit_x64/jit_x64.h
arm/jit_x64/reg_alloc.h
)
endif()

View File

@ -0,0 +1,145 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "core/arm/jit_x64/jit_x64.h"
#include "core/memory.h"
namespace JitX64 {
using namespace Gen;
void JitX64::CondManager::Init(JitX64* jit_) {
jit = jit_;
current_cond = ConditionCode::AL;
flags_dirty = false;
current_cond_fixup = {};
}
void JitX64::CondManager::CompileCond(const ConditionCode new_cond) {
if (current_cond == new_cond && !flags_dirty)
return;
if (current_cond != ConditionCode::AL && current_cond != ConditionCode::NV) {
jit->reg_alloc.FlushEverything();
ASSERT(current_cond_fixup.ptr);
jit->code->SetJumpTarget(current_cond_fixup);
current_cond_fixup.ptr = nullptr;
}
if (new_cond != ConditionCode::AL && new_cond != ConditionCode::NV) {
CCFlags cc;
switch (new_cond) {
case ConditionCode::EQ: //z
jit->code->CMP(8, jit->MJitStateZFlag(), Imm8(0));
cc = CC_E;
break;
case ConditionCode::NE: //!z
jit->code->CMP(8, jit->MJitStateZFlag(), Imm8(0));
cc = CC_NE;
break;
case ConditionCode::CS: //c
jit->code->CMP(8, jit->MJitStateCFlag(), Imm8(0));
cc = CC_E;
break;
case ConditionCode::CC: //!c
jit->code->CMP(8, jit->MJitStateCFlag(), Imm8(0));
cc = CC_NE;
break;
case ConditionCode::MI: //n
jit->code->CMP(8, jit->MJitStateNFlag(), Imm8(0));
cc = CC_E;
break;
case ConditionCode::PL: //!n
jit->code->CMP(8, jit->MJitStateNFlag(), Imm8(0));
cc = CC_NE;
break;
case ConditionCode::VS: //v
jit->code->CMP(8, jit->MJitStateVFlag(), Imm8(0));
cc = CC_E;
break;
case ConditionCode::VC: //!v
jit->code->CMP(8, jit->MJitStateVFlag(), Imm8(0));
cc = CC_NE;
break;
case ConditionCode::HI: { //c & !z
const X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateZFlag());
jit->code->CMP(8, jit->MJitStateCFlag(), R(tmp));
cc = CC_BE;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
case ConditionCode::LS: { //!c | z
const X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateZFlag());
jit->code->CMP(8, jit->MJitStateCFlag(), R(tmp));
cc = CC_A;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
case ConditionCode::GE: { // n == v
const X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateVFlag());
jit->code->CMP(8, jit->MJitStateNFlag(), R(tmp));
cc = CC_NE;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
case ConditionCode::LT: { // n != v
const X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateVFlag());
jit->code->CMP(8, jit->MJitStateNFlag(), R(tmp));
cc = CC_E;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
case ConditionCode::GT: { // !z & (n == v)
const X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateNFlag());
jit->code->XOR(8, R(tmp), jit->MJitStateVFlag());
jit->code->OR(8, R(tmp), jit->MJitStateZFlag());
jit->code->TEST(8, R(tmp), R(tmp));
cc = CC_NZ;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
case ConditionCode::LE: { // z | (n != v)
X64Reg tmp = jit->reg_alloc.AllocAndLockTemp();
jit->code->MOVZX(64, 8, tmp, jit->MJitStateNFlag());
jit->code->XOR(8, R(tmp), jit->MJitStateVFlag());
jit->code->OR(8, R(tmp), jit->MJitStateZFlag());
jit->code->TEST(8, R(tmp), R(tmp));
cc = CC_Z;
jit->reg_alloc.UnlockTemp(tmp);
break;
}
default:
UNREACHABLE();
break;
}
jit->reg_alloc.FlushEverything();
this->current_cond_fixup = jit->code->J_CC(cc, true);
}
current_cond = new_cond;
flags_dirty = false;
}
void JitX64::CondManager::Always() {
CompileCond(ConditionCode::AL);
}
void JitX64::CondManager::FlagsDirty() {
flags_dirty = true;
}
ConditionCode JitX64::CondManager::CurrentCond() {
return current_cond;
}
}

View File

@ -0,0 +1,13 @@
// 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(); }
}

View File

@ -0,0 +1,16 @@
// 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::B(Cond cond, ArmImm24 imm24) { CompileInterpretInstruction(); }
void JitX64::BL(Cond cond, ArmImm24 imm24) { CompileInterpretInstruction(); }
void JitX64::BLX_imm(bool H, ArmImm24 imm24) { CompileInterpretInstruction(); }
void JitX64::BLX_reg(Cond cond, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::BX(Cond cond, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::BXJ(Cond cond, ArmReg Rm) { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,17 @@
// 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::CDP() { CompileInterpretInstruction(); }
void JitX64::LDC() { CompileInterpretInstruction(); }
void JitX64::MCR() { CompileInterpretInstruction(); }
void JitX64::MCRR() { CompileInterpretInstruction(); }
void JitX64::MRC() { CompileInterpretInstruction(); }
void JitX64::MRRC() { CompileInterpretInstruction(); }
void JitX64::STC() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,58 @@
// 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::ADC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::ADC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::ADC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::ADD_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::ADD_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::ADD_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::AND_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::AND_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::AND_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::BIC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::BIC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::BIC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::CMN_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::CMN_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::CMN_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::CMP_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::CMP_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::CMP_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::EOR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::EOR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::EOR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::MOV_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::MOV_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::MOV_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::MVN_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::MVN_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::MVN_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::ORR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::ORR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::ORR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::RSB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::RSB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::RSB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::RSC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::RSC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::RSC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::SBC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::SBC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::SBC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::SUB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::SUB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::SUB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::TEQ_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::TEQ_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::TEQ_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::TST_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
void JitX64::TST_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
void JitX64::TST_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,15 @@
// 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::BKPT() { CompileInterpretInstruction(); }
void JitX64::HVC() { CompileInterpretInstruction(); }
void JitX64::SMC() { CompileInterpretInstruction(); }
void JitX64::SVC() { CompileInterpretInstruction(); }
void JitX64::UDF() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,22 @@
// 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::SXTAB() { CompileInterpretInstruction(); }
void JitX64::SXTAB16() { CompileInterpretInstruction(); }
void JitX64::SXTAH() { CompileInterpretInstruction(); }
void JitX64::SXTB() { CompileInterpretInstruction(); }
void JitX64::SXTB16() { CompileInterpretInstruction(); }
void JitX64::SXTH() { CompileInterpretInstruction(); }
void JitX64::UXTAB() { CompileInterpretInstruction(); }
void JitX64::UXTAB16() { CompileInterpretInstruction(); }
void JitX64::UXTAH() { CompileInterpretInstruction(); }
void JitX64::UXTB() { CompileInterpretInstruction(); }
void JitX64::UXTB16() { CompileInterpretInstruction(); }
void JitX64::UXTH() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,13 @@
// 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::DBG() { CompileInterpretInstruction(); }
void JitX64::PLD() { CompileInterpretInstruction(); }
void JitX64::PLI() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,43 @@
// 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 {
// Load/Store instructions
void JitX64::LDR_imm() { CompileInterpretInstruction(); }
void JitX64::LDR_reg() { CompileInterpretInstruction(); }
void JitX64::LDRB_imm() { CompileInterpretInstruction(); }
void JitX64::LDRB_reg() { CompileInterpretInstruction(); }
void JitX64::LDRBT() { CompileInterpretInstruction(); }
void JitX64::LDRD_imm() { CompileInterpretInstruction(); }
void JitX64::LDRD_reg() { CompileInterpretInstruction(); }
void JitX64::LDRH_imm() { CompileInterpretInstruction(); }
void JitX64::LDRH_reg() { CompileInterpretInstruction(); }
void JitX64::LDRHT() { CompileInterpretInstruction(); }
void JitX64::LDRSB_imm() { CompileInterpretInstruction(); }
void JitX64::LDRSB_reg() { CompileInterpretInstruction(); }
void JitX64::LDRSBT() { CompileInterpretInstruction(); }
void JitX64::LDRSH_imm() { CompileInterpretInstruction(); }
void JitX64::LDRSH_reg() { CompileInterpretInstruction(); }
void JitX64::LDRSHT() { CompileInterpretInstruction(); }
void JitX64::LDRT() { CompileInterpretInstruction(); }
void JitX64::STR_imm() { CompileInterpretInstruction(); }
void JitX64::STR_reg() { CompileInterpretInstruction(); }
void JitX64::STRB_imm() { CompileInterpretInstruction(); }
void JitX64::STRB_reg() { CompileInterpretInstruction(); }
void JitX64::STRBT() { CompileInterpretInstruction(); }
void JitX64::STRD_imm() { CompileInterpretInstruction(); }
void JitX64::STRD_reg() { CompileInterpretInstruction(); }
void JitX64::STRH_imm() { CompileInterpretInstruction(); }
void JitX64::STRH_reg() { CompileInterpretInstruction(); }
void JitX64::STRHT() { CompileInterpretInstruction(); }
void JitX64::STRT() { CompileInterpretInstruction(); }
// Load/Store multiple instructions
void JitX64::LDM() { CompileInterpretInstruction(); }
void JitX64::STM() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,14 @@
// 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::CLZ() { CompileInterpretInstruction(); }
void JitX64::ERET() { CompileInterpretInstruction(); }
void JitX64::NOP() { CompileInterpretInstruction(); }
void JitX64::SEL() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,43 @@
// 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 {
// Multiply (Normal) instructions
void JitX64::MLA() { CompileInterpretInstruction(); }
void JitX64::MLS() { CompileInterpretInstruction(); }
void JitX64::MUL() { CompileInterpretInstruction(); }
// Multiply (Long) instructions
void JitX64::SMLAL() { CompileInterpretInstruction(); }
void JitX64::SMULL() { CompileInterpretInstruction(); }
void JitX64::UMAAL() { CompileInterpretInstruction(); }
void JitX64::UMLAL() { CompileInterpretInstruction(); }
void JitX64::UMULL() { CompileInterpretInstruction(); }
// Multiply (Halfword) instructions
void JitX64::SMLALxy() { CompileInterpretInstruction(); }
void JitX64::SMLAxy() { CompileInterpretInstruction(); }
void JitX64::SMULxy() { CompileInterpretInstruction(); }
// Multiply (word by halfword) instructions
void JitX64::SMLAWy() { CompileInterpretInstruction(); }
void JitX64::SMULWy() { CompileInterpretInstruction(); }
// Multiply (Most significant word) instructions
void JitX64::SMMLA() { CompileInterpretInstruction(); }
void JitX64::SMMLS() { CompileInterpretInstruction(); }
void JitX64::SMMUL() { CompileInterpretInstruction(); }
// Multiply (Dual) instructions
void JitX64::SMLAD() { CompileInterpretInstruction(); }
void JitX64::SMLALD() { CompileInterpretInstruction(); }
void JitX64::SMLSD() { CompileInterpretInstruction(); }
void JitX64::SMLSLD() { CompileInterpretInstruction(); }
void JitX64::SMUAD() { CompileInterpretInstruction(); }
void JitX64::SMUSD() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,11 @@
// 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::PKH() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,22 @@
// 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::SHADD8() { CompileInterpretInstruction(); }
void JitX64::SHADD16() { CompileInterpretInstruction(); }
void JitX64::SHASX() { CompileInterpretInstruction(); }
void JitX64::SHSAX() { CompileInterpretInstruction(); }
void JitX64::SHSUB8() { CompileInterpretInstruction(); }
void JitX64::SHSUB16() { CompileInterpretInstruction(); }
void JitX64::UHADD8() { CompileInterpretInstruction(); }
void JitX64::UHADD16() { CompileInterpretInstruction(); }
void JitX64::UHASX() { CompileInterpretInstruction(); }
void JitX64::UHSAX() { CompileInterpretInstruction(); }
void JitX64::UHSUB8() { CompileInterpretInstruction(); }
void JitX64::UHSUB16() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,22 @@
// 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::SADD8() { CompileInterpretInstruction(); }
void JitX64::SADD16() { CompileInterpretInstruction(); }
void JitX64::SASX() { CompileInterpretInstruction(); }
void JitX64::SSAX() { CompileInterpretInstruction(); }
void JitX64::SSUB8() { CompileInterpretInstruction(); }
void JitX64::SSUB16() { CompileInterpretInstruction(); }
void JitX64::UADD8() { CompileInterpretInstruction(); }
void JitX64::UADD16() { CompileInterpretInstruction(); }
void JitX64::UASX() { CompileInterpretInstruction(); }
void JitX64::USAX() { CompileInterpretInstruction(); }
void JitX64::USUB8() { CompileInterpretInstruction(); }
void JitX64::USUB16() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,23 @@
// 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::QADD8() { CompileInterpretInstruction(); }
void JitX64::QADD16() { CompileInterpretInstruction(); }
void JitX64::QASX() { CompileInterpretInstruction(); }
void JitX64::QSAX() { CompileInterpretInstruction(); }
void JitX64::QSUB8() { CompileInterpretInstruction(); }
void JitX64::QSUB16() { CompileInterpretInstruction(); }
void JitX64::UQADD8() { CompileInterpretInstruction(); }
void JitX64::UQADD16() { CompileInterpretInstruction(); }
void JitX64::UQASX() { CompileInterpretInstruction(); }
void JitX64::UQSAX() { CompileInterpretInstruction(); }
void JitX64::UQSUB8() { CompileInterpretInstruction(); }
void JitX64::UQSUB16() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,14 @@
// 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::QADD() { CompileInterpretInstruction(); }
void JitX64::QSUB() { CompileInterpretInstruction(); }
void JitX64::QDADD() { CompileInterpretInstruction(); }
void JitX64::QDSUB() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,14 @@
// 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::RBIT() { CompileInterpretInstruction(); }
void JitX64::REV() { CompileInterpretInstruction(); }
void JitX64::REV16() { CompileInterpretInstruction(); }
void JitX64::REVSH() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,14 @@
// 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::SSAT() { CompileInterpretInstruction(); }
void JitX64::SSAT16() { CompileInterpretInstruction(); }
void JitX64::USAT() { CompileInterpretInstruction(); }
void JitX64::USAT16() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,16 @@
// 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::CPS() { CompileInterpretInstruction(); }
void JitX64::MRS() { CompileInterpretInstruction(); }
void JitX64::MSR() { CompileInterpretInstruction(); }
void JitX64::RFE() { CompileInterpretInstruction(); }
void JitX64::SETEND() { CompileInterpretInstruction(); }
void JitX64::SRS() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,20 @@
// 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::CLREX() { CompileInterpretInstruction(); }
void JitX64::LDREX() { CompileInterpretInstruction(); }
void JitX64::LDREXB() { CompileInterpretInstruction(); }
void JitX64::LDREXD() { CompileInterpretInstruction(); }
void JitX64::LDREXH() { CompileInterpretInstruction(); }
void JitX64::STREX() { CompileInterpretInstruction(); }
void JitX64::STREXB() { CompileInterpretInstruction(); }
void JitX64::STREXD() { CompileInterpretInstruction(); }
void JitX64::STREXH() { CompileInterpretInstruction(); }
void JitX64::SWP() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,12 @@
// 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::thumb_BLX_prefix(ArmImm11 imm11) { CompileInterpretInstruction(); }
void JitX64::thumb_BLX_suffix(bool L, ArmImm11 imm11) { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,12 @@
// 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::USAD8() { CompileInterpretInstruction(); }
void JitX64::USADA8() { CompileInterpretInstruction(); }
}

View File

@ -0,0 +1,73 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/x64/abi.h"
#include "core/arm/jit_x64/jit_x64.h"
extern unsigned InterpreterMainLoop(ARMul_State* cpu);
namespace JitX64 {
using namespace Gen;
static JitState* CallInterpreter(JitState* jit_state, u64 pc, u64 TFlag, u64 EFlag) {
ARMul_State* cpu = &jit_state->cpu_state;
cpu->Reg[15] = pc;
cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) |
(cpu->NFlag << 31) |
(cpu->ZFlag << 30) |
(cpu->CFlag << 29) |
(cpu->VFlag << 28) |
(cpu->TFlag << 5);
if (jit_state->cycles_remaining > 0) {
#if 0
cpu->NumInstrsToExecute = jit_state->cycles_remaining;
if (cpu->NumInstrsToExecute > 100) cpu->NumInstrsToExecute = 100;
jit_state->cycles_remaining -= InterpreterMainLoop(cpu);
#else
cpu->NumInstrsToExecute = 1;
jit_state->cycles_remaining -= InterpreterMainLoop(cpu);
#endif
}
return jit_state;
}
void JitX64::CompileInterpretInstruction() {
cond_manager.Always();
reg_alloc.FlushEverything();
CompileUpdateCycles();
ASSERT(reg_alloc.JitStateReg() != RSP);
code->MOV(64, R(RSP), MJitStateHostReturnRSP());
code->MOV(64, R(Gen::ABI_PARAM1), R(reg_alloc.JitStateReg()));
code->MOV(64, R(Gen::ABI_PARAM2), Imm64(current.arm_pc));
code->MOV(64, R(Gen::ABI_PARAM3), Imm64(current.TFlag));
code->MOV(64, R(Gen::ABI_PARAM4), Imm64(current.EFlag));
const void *const fn = &CallInterpreter;
const u64 distance = reinterpret_cast<u64>(fn) - (reinterpret_cast<u64>(code->GetCodePtr()) + 5);
if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
// Far call
code->MOV(64, R(RAX), ImmPtr(fn));
code->CALLptr(R(RAX));
} else {
code->CALL(fn);
}
code->MOV(64, R(reg_alloc.JitStateReg()), R(Gen::ABI_RETURN));
// Return to dispatch
code->JMPptr(MJitStateHostReturnRIP());
stop_compilation = true;
}
}

View File

@ -0,0 +1,174 @@
// 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"
#include "core/memory.h"
namespace JitX64 {
using namespace Gen;
JitX64::JitX64(XEmitter* code_) : code(code_) {}
CodePtr JitX64::GetBB(u32 pc, bool TFlag, bool EFlag) {
const LocationDescriptor desc = { pc, TFlag, EFlag };
if (basic_blocks.find(desc) == basic_blocks.end()) {
return Compile(pc, TFlag, EFlag);
}
return basic_blocks[desc];
}
CodePtr JitX64::Compile(u32 pc, bool TFlag, bool EFlag) {
const CodePtr bb = code->GetWritableCodePtr();
const LocationDescriptor desc = { pc, TFlag, EFlag };
ASSERT(basic_blocks.find(desc) == basic_blocks.end());
basic_blocks[desc] = bb;
Patch(desc, bb);
reg_alloc.Init(code);
cond_manager.Init(this);
current = desc;
instructions_compiled = 0;
stop_compilation = false;
do {
instructions_compiled++;
if (current.TFlag) {
CompileSingleThumbInstruction();
} else {
CompileSingleArmInstruction();
}
} while (!stop_compilation && ((current.arm_pc & 0xFFF) != 0));
if (!stop_compilation) {
// We're stopping compilation because we've reached a page boundary.
cond_manager.Always();
CompileUpdateCycles();
CompileJumpToBB(current.arm_pc);
}
// Insert easily searchable byte sequence for ease of lookup in memory dumps.
code->NOP();
code->INT3();
code->NOP();
return bb;
}
void JitX64::CompileUpdateCycles() {
// We're just taking one instruction == one cycle.
if (instructions_compiled) {
code->SUB(32, MJitStateCycleCount(), Imm32(instructions_compiled));
}
instructions_compiled = 0;
}
void JitX64::CompileJumpToBB(u32 new_pc) {
ASSERT(instructions_compiled == 0);
reg_alloc.FlushEverything();
code->CMP(32, MJitStateCycleCount(), Imm8(0));
const LocationDescriptor new_desc = { new_pc, current.TFlag, current.EFlag };
patch_jmp_locations[new_desc].emplace_back(code->GetWritableCodePtr());
if (basic_blocks.find(new_desc) == basic_blocks.end()) {
code->NOP(6); // Leave enough space for a jg instruction.
} else {
code->J_CC(CC_G, basic_blocks[new_desc], true);
}
code->MOV(32, MJitStateArmPC(), Imm32(new_pc));
code->JMPptr(MJitStateHostReturnRIP());
}
void JitX64::Patch(LocationDescriptor desc, CodePtr bb) {
const CodePtr save_code_ptr = code->GetWritableCodePtr();
for (CodePtr location : patch_jmp_locations[desc]) {
code->SetCodePtr(location);
code->J_CC(CC_G, bb, true);
ASSERT(code->GetCodePtr() - location == 6);
}
code->SetCodePtr(save_code_ptr);
}
void JitX64::CompileSingleArmInstruction() {
u32 inst = Memory::Read32(current.arm_pc & 0xFFFFFFFC);
ArmDecoder::DecodeArm(inst).Visit(this, inst);
}
void JitX64::CompileSingleThumbInstruction() {
u32 inst_u32 = Memory::Read32(current.arm_pc & 0xFFFFFFFC);
if ((current.arm_pc & 0x3) != 0) {
inst_u32 >>= 16;
}
inst_u32 &= 0xFFFFF;
u16 inst = inst_u32;
ArmDecoder::DecodeThumb(inst).Visit(this, inst);
}
// Convenience functions:
// We static_assert types because anything that calls these functions makes those assumptions.
// If the types of the variables are changed please update all code that calls these functions.
Gen::OpArg JitX64::MJitStateCycleCount() {
static_assert(std::is_same<decltype(JitState::cycles_remaining), s32>::value, "JitState::cycles_remaining must be s32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cycles_remaining));
}
Gen::OpArg JitX64::MJitStateArmPC() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::Reg), std::array<u32, 16>>::value, "ARMul_State::Reg must be std::array<u32, 16>");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, Reg) + 15 * sizeof(u32));
}
Gen::OpArg JitX64::MJitStateHostReturnRIP() {
static_assert(std::is_same<decltype(JitState::return_RIP), u64>::value, "JitState::return_RIP must be u64");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, return_RIP));
}
Gen::OpArg JitX64::MJitStateHostReturnRSP() {
static_assert(std::is_same<decltype(JitState::save_host_RSP), u64>::value, "JitState::save_host_RSP must be u64");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, save_host_RSP));
}
Gen::OpArg JitX64::MJitStateZFlag() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::ZFlag), u32>::value, "ZFlag must be u32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, ZFlag));
}
Gen::OpArg JitX64::MJitStateCFlag() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::CFlag), u32>::value, "CFlag must be u32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, CFlag));
}
Gen::OpArg JitX64::MJitStateNFlag() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::NFlag), u32>::value, "NFlag must be u32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, NFlag));
}
Gen::OpArg JitX64::MJitStateVFlag() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::VFlag), u32>::value, "VFlag must be u32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, VFlag));
}
}

View File

@ -0,0 +1,368 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "common/x64/emitter.h"
#include "core/arm/decoder/decoder.h"
#include "core/arm/jit_x64/common.h"
#include "core/arm/jit_x64/reg_alloc.h"
namespace JitX64 {
using CodePtr = u8*;
struct LocationDescriptor {
u32 arm_pc;
bool TFlag; ///< Thumb / ARM
bool EFlag; ///< Big / Little Endian
bool operator == (const LocationDescriptor& o) const {
return std::tie(arm_pc, TFlag, EFlag) == std::tie(o.arm_pc, o.TFlag, o.EFlag);
}
};
struct LocationDescriptorHash {
size_t operator()(const LocationDescriptor& x) const {
return std::hash<u64>()((u64)x.arm_pc ^ ((u64)x.TFlag << 32) ^ ((u64)x.EFlag << 33));
}
};
class JitX64 final : private ArmDecoder::Visitor {
private:
Gen::XEmitter* code;
RegAlloc reg_alloc;
/// ARM pc -> x64 code block
std::unordered_map<LocationDescriptor, CodePtr, LocationDescriptorHash> basic_blocks;
public:
JitX64() = delete;
JitX64(Gen::XEmitter* code_);
virtual ~JitX64() override {}
CodePtr GetBB(u32 pc, bool TFlag, bool EFlag);
/// Returns a pointer to the compiled basic block.
CodePtr Compile(u32 pc, bool TFlag, bool EFlag);
private:
LocationDescriptor current;
unsigned instructions_compiled;
bool stop_compilation;
size_t GetInstSize() { return current.TFlag ? 2 : 4; }
void CompileSingleArmInstruction();
void CompileSingleThumbInstruction();
/// Updates the cycle count in JitState and sets instructions_compiled to zero.
void CompileUpdateCycles();
/// If a basic_block starting at ARM pc is compiled -> these locations need to be patched
std::unordered_map<LocationDescriptor, std::vector<CodePtr>, LocationDescriptorHash> patch_jmp_locations;
/// Update JitState cycle count before calling this function. This function may instead update JitState PC and return to dispatcher.
void CompileJumpToBB(u32 arm_pc);
/// Patch missing jumps (fill in after CompileJumpToBB).
void Patch(LocationDescriptor desc, CodePtr bb);
private:
/// Convenience functions
Gen::OpArg MJitStateCycleCount();
Gen::OpArg MJitStateArmPC();
Gen::OpArg MJitStateHostReturnRIP();
Gen::OpArg MJitStateHostReturnRSP();
Gen::OpArg MJitStateZFlag();
Gen::OpArg MJitStateCFlag();
Gen::OpArg MJitStateNFlag();
Gen::OpArg MJitStateVFlag();
private:
struct CondManager {
private:
JitX64* jit;
ConditionCode current_cond;
bool flags_dirty;
Gen::FixupBranch current_cond_fixup;
public:
void Init(JitX64* jit_);
void CompileCond(ConditionCode cond);
void Always();
void FlagsDirty();
ConditionCode CurrentCond();
} cond_manager;
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;
// 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;
// Data processing instructions
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;
// Exception generation instructions
virtual void BKPT() override;
virtual void HVC() override;
virtual void SMC() override;
virtual void SVC() override;
virtual 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;
// Hint instructions
virtual void DBG() override;
virtual void PLD() override;
virtual void PLI() 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;
// Load/Store multiple instructions
virtual void LDM() override;
virtual void STM() override;
// Miscellaneous instructions
virtual void CLZ() override;
virtual void ERET() override;
virtual void NOP() override;
virtual void SEL() override;
// Unsigned sum of absolute difference functions
virtual void USAD8() override;
virtual void USADA8() override;
// Packing instructions
virtual void PKH() override;
// Reversal instructions
virtual void RBIT() override;
virtual void REV() override;
virtual void REV16() override;
virtual void REVSH() override;
// Saturation instructions
virtual void SSAT() override;
virtual void SSAT16() override;
virtual void USAT() override;
virtual void USAT16() override;
// Multiply (Normal) instructions
virtual void MLA() override;
virtual void MLS() override;
virtual 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;
// Multiply (Halfword) instructions
virtual void SMLALxy() override;
virtual void SMLAxy() override;
virtual void SMULxy() override;
// Multiply (word by halfword) instructions
virtual void SMLAWy() override;
virtual void SMULWy() override;
// Multiply (Most significant word) instructions
virtual void SMMLA() override;
virtual void SMMLS() override;
virtual 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;
// 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;
// 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;
// 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;
// Saturated Add/Subtract instructions
virtual void QADD() override;
virtual void QSUB() override;
virtual void QDADD() override;
virtual 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;
// 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;
// Thumb specific instructions
virtual void thumb_BLX_prefix(ArmImm11 imm11) override;
virtual void thumb_BLX_suffix(bool L, ArmImm11 imm11) override;
};
}