Merged in bunnei/dynarmic (pull request #8)
arm: Implement B/BL/BX instructions.
This commit is contained in:
commit
39563c8ea8
4 changed files with 77 additions and 3 deletions
|
@ -16,6 +16,7 @@ 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/branch.cpp
|
||||||
frontend/translate/translate_arm/data_processing.cpp
|
frontend/translate/translate_arm/data_processing.cpp
|
||||||
frontend/translate/translate_arm/exception_generating.cpp
|
frontend/translate/translate_arm/exception_generating.cpp
|
||||||
frontend/translate/translate_arm/extension.cpp
|
frontend/translate/translate_arm/extension.cpp
|
||||||
|
|
|
@ -66,9 +66,9 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
|
||||||
// Branch instructions
|
// Branch instructions
|
||||||
//INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv"), // v5
|
//INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv"), // v5
|
||||||
//INST(&V::arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm"), // v5
|
//INST(&V::arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm"), // v5
|
||||||
//INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||||
//INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||||
//INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm"), // v4T
|
INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm"), // v4T
|
||||||
//INST(&V::arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm"), // v5J
|
//INST(&V::arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm"), // v5J
|
||||||
|
|
||||||
// Coprocessor instructions
|
// Coprocessor instructions
|
||||||
|
|
65
src/frontend/translate/translate_arm/branch.cpp
Normal file
65
src/frontend/translate/translate_arm/branch.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/* 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 "common/bit_util.h"
|
||||||
|
|
||||||
|
#include "translate_arm.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace Arm {
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_B(Cond cond, Imm24 imm24)
|
||||||
|
{
|
||||||
|
s32 imm32 = Common::SignExtend<26, s32>(imm24 << 2) + 8;
|
||||||
|
// B <cond> <label>
|
||||||
|
if (ConditionPassed(cond))
|
||||||
|
{
|
||||||
|
auto new_location = ir.current_location.AdvancePC(imm32);
|
||||||
|
ir.SetTerm(IR::Term::LinkBlock{ new_location });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BL(Cond cond, Imm24 imm24)
|
||||||
|
{
|
||||||
|
s32 imm32 = Common::SignExtend<26, s32>(imm24 << 2) + 8;
|
||||||
|
// BL <cond> <label>
|
||||||
|
if (ConditionPassed(cond))
|
||||||
|
{
|
||||||
|
ir.SetRegister(Reg::LR, ir.Imm32(ir.current_location.PC() + 4));
|
||||||
|
auto new_location = ir.current_location.AdvancePC(imm32);
|
||||||
|
ir.SetTerm(IR::Term::LinkBlock{ new_location });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BLX_imm(Cond cond, Imm24 imm24)
|
||||||
|
{
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BX(Cond cond, Reg m) {
|
||||||
|
// BX <cond> <Rm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
ir.BXWritePC(ir.GetRegister(m));
|
||||||
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_BXJ(Cond cond, Reg m) {
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
|
@ -62,6 +62,14 @@ struct ArmTranslatorVisitor final {
|
||||||
IREmitter::ResultAndCarry EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in);
|
IREmitter::ResultAndCarry EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in);
|
||||||
IR::Value SignZeroExtendRor(Reg m, SignExtendRotation rotate);
|
IR::Value SignZeroExtendRor(Reg m, SignExtendRotation rotate);
|
||||||
|
|
||||||
|
// Branch instructions
|
||||||
|
bool arm_B(Cond cond, Imm24 imm24);
|
||||||
|
bool arm_BL(Cond cond, Imm24 imm24);
|
||||||
|
bool arm_BLX_imm(Cond cond, Imm24 imm24);
|
||||||
|
bool arm_BLX_reg(Cond cond, Reg m);
|
||||||
|
bool arm_BX(Cond cond, Reg m);
|
||||||
|
bool arm_BXJ(Cond cond, Reg m);
|
||||||
|
|
||||||
// Data processing instructions
|
// Data processing instructions
|
||||||
bool arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8);
|
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_reg(Cond cond, bool S, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
|
|
Loading…
Reference in a new issue