arm: Implement B/BL/BX instructions.
This commit is contained in:
parent
fc33f1d374
commit
691e4139fa
4 changed files with 77 additions and 3 deletions
|
@ -16,6 +16,7 @@ set(SRCS
|
|||
frontend/ir/ir_emitter.cpp
|
||||
frontend/translate/translate.cpp
|
||||
frontend/translate/translate_arm.cpp
|
||||
frontend/translate/translate_arm/branch.cpp
|
||||
frontend/translate/translate_arm/data_processing.cpp
|
||||
frontend/translate/translate_arm/exception_generating.cpp
|
||||
frontend/translate/translate_arm/extension.cpp
|
||||
|
|
|
@ -66,9 +66,9 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
|
|||
// Branch instructions
|
||||
//INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv"), // v5
|
||||
//INST(&V::arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm"), // v5
|
||||
//INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||
//INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||
//INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm"), // v4T
|
||||
INST(&V::arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||
INST(&V::arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv"), // all
|
||||
INST(&V::arm_BX, "BX", "cccc000100101111111111110001mmmm"), // v4T
|
||||
//INST(&V::arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm"), // v5J
|
||||
|
||||
// Coprocessor instructions
|
||||
|
|
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);
|
||||
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
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue