TranslateArm: Reorganisation - Split visitor into multiple .cpp files
This commit is contained in:
parent
93af160c97
commit
6097a21955
6 changed files with 423 additions and 296 deletions
|
@ -16,6 +16,9 @@ set(SRCS
|
||||||
frontend/ir/ir_emitter.cpp
|
frontend/ir/ir_emitter.cpp
|
||||||
frontend/translate/translate.cpp
|
frontend/translate/translate.cpp
|
||||||
frontend/translate/translate_arm.cpp
|
frontend/translate/translate_arm.cpp
|
||||||
|
frontend/translate/translate_arm/data_processing.cpp
|
||||||
|
frontend/translate/translate_arm/exception_generating.cpp
|
||||||
|
frontend/translate/translate_arm/reversal.cpp
|
||||||
frontend/translate/translate_thumb.cpp
|
frontend/translate/translate_thumb.cpp
|
||||||
ir_opt/dead_code_elimination_pass.cpp
|
ir_opt/dead_code_elimination_pass.cpp
|
||||||
ir_opt/get_set_elimination_pass.cpp
|
ir_opt/get_set_elimination_pass.cpp
|
||||||
|
@ -49,6 +52,7 @@ set(HEADERS
|
||||||
frontend/ir/ir_emitter.h
|
frontend/ir/ir_emitter.h
|
||||||
frontend/ir/opcodes.h
|
frontend/ir/opcodes.h
|
||||||
frontend/translate/translate.h
|
frontend/translate/translate.h
|
||||||
|
frontend/translate/translate_arm/translate_arm.h
|
||||||
interface/interface.h
|
interface/interface.h
|
||||||
ir_opt/passes.h
|
ir_opt/passes.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,307 +8,12 @@
|
||||||
#include "frontend/arm_types.h"
|
#include "frontend/arm_types.h"
|
||||||
#include "frontend/decoder/arm.h"
|
#include "frontend/decoder/arm.h"
|
||||||
#include "frontend/ir/ir.h"
|
#include "frontend/ir/ir.h"
|
||||||
#include "frontend/ir/ir_emitter.h"
|
|
||||||
#include "frontend/translate/translate.h"
|
#include "frontend/translate/translate.h"
|
||||||
|
#include "frontend/translate/translate_arm/translate_arm.h"
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
namespace Arm {
|
namespace Arm {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
enum class ConditionalState {
|
|
||||||
/// We haven't met any conditional instructions yet.
|
|
||||||
None,
|
|
||||||
/// Current instruction is a conditional. This marks the end of this basic block.
|
|
||||||
Break,
|
|
||||||
/// This basic block is made up solely of conditional instructions.
|
|
||||||
Translating,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ArmTranslatorVisitor final {
|
|
||||||
explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {
|
|
||||||
ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
IREmitter ir;
|
|
||||||
ConditionalState cond_state = ConditionalState::None;
|
|
||||||
|
|
||||||
bool InterpretThisInstruction() {
|
|
||||||
ir.SetTerm(IR::Term::Interpret(ir.current_location));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UnpredictableInstruction() {
|
|
||||||
ASSERT_MSG(false, "UNPREDICTABLE");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LinkToNextInstruction() {
|
|
||||||
auto next_location = ir.current_location.AdvancePC(4);
|
|
||||||
ir.SetTerm(IR::Term::LinkBlock{next_location});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConditionPassed(Cond cond) {
|
|
||||||
ASSERT_MSG(cond_state != ConditionalState::Translating,
|
|
||||||
"In the current impl, ConditionPassed should never be called again once a non-AL cond is hit. "
|
|
||||||
"(i.e.: one and only one conditional instruction per block)");
|
|
||||||
ASSERT_MSG(cond_state != ConditionalState::Break,
|
|
||||||
"This should never happen. We requested a break but that wasn't honored.");
|
|
||||||
ASSERT_MSG(cond != Cond::NV, "NV conditional is obsolete");
|
|
||||||
|
|
||||||
if (cond == Cond::AL) {
|
|
||||||
// Everything is fine with the world
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// non-AL cond
|
|
||||||
|
|
||||||
if (!ir.block.instructions.empty()) {
|
|
||||||
// We've already emitted instructions. Quit for now, we'll make a new block here later.
|
|
||||||
cond_state = ConditionalState::Break;
|
|
||||||
ir.SetTerm(IR::Term::LinkBlock{ir.current_location});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We've not emitted instructions yet.
|
|
||||||
// We'll emit one instruction, and set the block-entry conditional appropriately.
|
|
||||||
|
|
||||||
cond_state = ConditionalState::Translating;
|
|
||||||
ir.block.cond = cond;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 rotr(u32 x, int shift) {
|
|
||||||
shift &= 31;
|
|
||||||
if (!shift) return x;
|
|
||||||
return (x >> shift) | (x << (32 - shift));
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ArmExpandImm(int rotate, Imm8 imm8) {
|
|
||||||
return rotr(static_cast<u32>(imm8), rotate*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
u32 imm32 = ArmExpandImm(rotate, imm8);
|
|
||||||
// ADC{S}<c> <Rd>, <Rn>, #<imm>
|
|
||||||
if (ConditionPassed(cond)) {
|
|
||||||
auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
|
|
||||||
|
|
||||||
if (d == Reg::PC) {
|
|
||||||
ASSERT(!S);
|
|
||||||
ir.ALUWritePC(result.result);
|
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ir.SetRegister(d, result.result);
|
|
||||||
if (S) {
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_CMN_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_CMN_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_CMP_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
|
||||||
u32 imm32 = ArmExpandImm(rotate, imm8);
|
|
||||||
// CMP<c> <Rn>, #<imm>
|
|
||||||
if (ConditionPassed(cond)) {
|
|
||||||
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
|
||||||
ir.SetZFlag(ir.IsZero(result.result));
|
|
||||||
ir.SetCFlag(result.carry);
|
|
||||||
ir.SetVFlag(result.overflow);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_CMP_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MOV_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MVN_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TEQ_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TST_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TST_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_SVC(Cond cond, Imm24 imm24) {
|
|
||||||
u32 imm32 = imm24;
|
|
||||||
// SVC<c> #<imm24>
|
|
||||||
if (ConditionPassed(cond)) {
|
|
||||||
ir.CallSupervisor(ir.Imm32(imm32));
|
|
||||||
return LinkToNextInstruction();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_UDF() {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_REV(Cond cond, Reg d, Reg m) {
|
|
||||||
// REV<c> <Rd>, <Rm>
|
|
||||||
ASSERT(d != Reg::PC && m != Reg::PC);
|
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
|
||||||
auto result = ir.ByteReverseWord(ir.GetRegister(m));
|
|
||||||
ir.SetRegister(d, result);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_REV16(Cond cond, Reg d, Reg m) {
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arm_REVSH(Cond cond, Reg d, Reg m) {
|
|
||||||
// REVSH<c> <Rd>, <Rm>
|
|
||||||
ASSERT(d != Reg::PC && m != Reg::PC);
|
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
|
||||||
auto rev_half = ir.ByteReverseHalf(ir.LeastSignificantHalf(ir.GetRegister(m)));
|
|
||||||
ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // local namespace
|
|
||||||
|
|
||||||
IR::Block TranslateArm(LocationDescriptor descriptor, MemoryRead32FuncType memory_read_32) {
|
IR::Block TranslateArm(LocationDescriptor descriptor, MemoryRead32FuncType memory_read_32) {
|
||||||
ArmTranslatorVisitor visitor{descriptor};
|
ArmTranslatorVisitor visitor{descriptor};
|
||||||
|
|
||||||
|
@ -342,5 +47,51 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryRead32FuncType memor
|
||||||
return std::move(visitor.ir.block);
|
return std::move(visitor.ir.block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::ConditionPassed(Cond cond) {
|
||||||
|
ASSERT_MSG(cond_state != ConditionalState::Translating,
|
||||||
|
"In the current impl, ConditionPassed should never be called again once a non-AL cond is hit. "
|
||||||
|
"(i.e.: one and only one conditional instruction per block)");
|
||||||
|
ASSERT_MSG(cond_state != ConditionalState::Break,
|
||||||
|
"This should never happen. We requested a break but that wasn't honored.");
|
||||||
|
ASSERT_MSG(cond != Cond::NV, "NV conditional is obsolete");
|
||||||
|
|
||||||
|
if (cond == Cond::AL) {
|
||||||
|
// Everything is fine with the world
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-AL cond
|
||||||
|
|
||||||
|
if (!ir.block.instructions.empty()) {
|
||||||
|
// We've already emitted instructions. Quit for now, we'll make a new block here later.
|
||||||
|
cond_state = ConditionalState::Break;
|
||||||
|
ir.SetTerm(IR::Term::LinkBlock{ir.current_location});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've not emitted instructions yet.
|
||||||
|
// We'll emit one instruction, and set the block-entry conditional appropriately.
|
||||||
|
|
||||||
|
cond_state = ConditionalState::Translating;
|
||||||
|
ir.block.cond = cond;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::InterpretThisInstruction() {
|
||||||
|
ir.SetTerm(IR::Term::Interpret(ir.current_location));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::UnpredictableInstruction() {
|
||||||
|
ASSERT_MSG(false, "UNPREDICTABLE");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::LinkToNextInstruction() {
|
||||||
|
auto next_location = ir.current_location.AdvancePC(4);
|
||||||
|
ir.SetTerm(IR::Term::LinkBlock{next_location});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Arm
|
} // namespace Arm
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
191
src/frontend/translate/translate_arm/data_processing.cpp
Normal file
191
src/frontend/translate/translate_arm/data_processing.cpp
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "translate_arm.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace Arm {
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
u32 imm32 = ArmExpandImm(rotate, imm8);
|
||||||
|
// ADC{S}<c> <Rd>, <Rn>, #<imm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.GetCFlag());
|
||||||
|
|
||||||
|
if (d == Reg::PC) {
|
||||||
|
ASSERT(!S);
|
||||||
|
ir.ALUWritePC(result.result);
|
||||||
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
if (S) {
|
||||||
|
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
||||||
|
ir.SetZFlag(ir.IsZero(result.result));
|
||||||
|
ir.SetCFlag(result.carry);
|
||||||
|
ir.SetVFlag(result.overflow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
||||||
|
u32 imm32 = ArmExpandImm(rotate, imm8);
|
||||||
|
// CMP<c> <Rn>, #<imm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
|
||||||
|
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
||||||
|
ir.SetZFlag(ir.IsZero(result.result));
|
||||||
|
ir.SetCFlag(result.carry);
|
||||||
|
ir.SetVFlag(result.overflow);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm8 imm8) {
|
||||||
|
//auto result = ArmExpandImm_C(rotate, imm8);
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
bool ArmTranslatorVisitor::arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "translate_arm.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace Arm {
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BKPT(Cond cond, Imm12 imm12, Imm4 imm4) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm24 imm24) {
|
||||||
|
u32 imm32 = imm24;
|
||||||
|
// SVC<c> #<imm24>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
ir.CallSupervisor(ir.Imm32(imm32));
|
||||||
|
return LinkToNextInstruction();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_UDF() {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
39
src/frontend/translate/translate_arm/reversal.cpp
Normal file
39
src/frontend/translate/translate_arm/reversal.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "translate_arm.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace Arm {
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) {
|
||||||
|
// REV<c> <Rd>, <Rm>
|
||||||
|
ASSERT(d != Reg::PC && m != Reg::PC);
|
||||||
|
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto result = ir.ByteReverseWord(ir.GetRegister(m));
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_REV16(Cond cond, Reg d, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_REVSH(Cond cond, Reg d, Reg m) {
|
||||||
|
// REVSH<c> <Rd>, <Rm>
|
||||||
|
ASSERT(d != Reg::PC && m != Reg::PC);
|
||||||
|
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto rev_half = ir.ByteReverseHalf(ir.LeastSignificantHalf(ir.GetRegister(m)));
|
||||||
|
ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
111
src/frontend/translate/translate_arm/translate_arm.h
Normal file
111
src/frontend/translate/translate_arm/translate_arm.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "frontend/ir/ir_emitter.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace Arm {
|
||||||
|
|
||||||
|
enum class ConditionalState {
|
||||||
|
/// We haven't met any conditional instructions yet.
|
||||||
|
None,
|
||||||
|
/// Current instruction is a conditional. This marks the end of this basic block.
|
||||||
|
Break,
|
||||||
|
/// This basic block is made up solely of conditional instructions.
|
||||||
|
Translating,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArmTranslatorVisitor final {
|
||||||
|
explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {
|
||||||
|
ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
IREmitter ir;
|
||||||
|
ConditionalState cond_state = ConditionalState::None;
|
||||||
|
|
||||||
|
bool ConditionPassed(Cond cond);
|
||||||
|
bool InterpretThisInstruction();
|
||||||
|
bool UnpredictableInstruction();
|
||||||
|
bool LinkToNextInstruction();
|
||||||
|
|
||||||
|
static u32 rotr(u32 x, int shift) {
|
||||||
|
shift &= 31;
|
||||||
|
if (!shift) return x;
|
||||||
|
return (x >> shift) | (x << (32 - shift));
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 ArmExpandImm(int rotate, Imm8 imm8) {
|
||||||
|
return rotr(static_cast<u32>(imm8), rotate*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data processing instructions
|
||||||
|
bool arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_CMN_imm(Cond cond, Reg n, int rotate, Imm8 imm8);
|
||||||
|
bool arm_CMN_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_CMP_imm(Cond cond, Reg n, int rotate, Imm8 imm8);
|
||||||
|
bool arm_CMP_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_MOV_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_MVN_reg(Cond cond, bool S, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
||||||
|
bool arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm8 imm8);
|
||||||
|
bool arm_TEQ_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m);
|
||||||
|
bool arm_TST_imm(Cond cond, Reg n, int rotate, Imm8 imm8);
|
||||||
|
bool arm_TST_reg(Cond cond, Reg n, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
bool arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m);
|
||||||
|
|
||||||
|
// Exception generating instructions
|
||||||
|
bool arm_BKPT(Cond cond, Imm12 imm12, Imm4 imm4);
|
||||||
|
bool arm_SVC(Cond cond, Imm24 imm24);
|
||||||
|
bool arm_UDF();
|
||||||
|
|
||||||
|
// Reversal instructions
|
||||||
|
bool arm_REV(Cond cond, Reg d, Reg m);
|
||||||
|
bool arm_REV16(Cond cond, Reg d, Reg m);
|
||||||
|
bool arm_REVSH(Cond cond, Reg d, Reg m);
|
||||||
|
|
||||||
|
// Floating-point three-register data processing instructions
|
||||||
|
bool vfp2_VADD(Cond cond, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
Loading…
Reference in a new issue