A32: Fix thumb32 BL and BLX
More fields required
This commit is contained in:
parent
df027a7998
commit
43a1a523f6
3 changed files with 22 additions and 21 deletions
|
@ -120,10 +120,11 @@
|
||||||
//INST(thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----")
|
//INST(thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----")
|
||||||
//INST(thumb32_HVC, "HVC", "111101111110----1000------------")
|
//INST(thumb32_HVC, "HVC", "111101111110----1000------------")
|
||||||
//INST(thumb32_SMC, "SMC", "111101111111----1000000000000000")
|
//INST(thumb32_SMC, "SMC", "111101111111----1000000000000000")
|
||||||
//INST(thumb32_UDF, "UDF", "111101111111----1010------------")
|
INST(thumb32_UDF, "UDF", "111101111111----1010------------") // v6T2
|
||||||
|
|
||||||
//INST(thumb32_BL, "BL", "11110-----------11-1------------")
|
// Branch instructions
|
||||||
//INST(thumb32_BLX, "BLX", "11110-----------11-0------------")
|
INST(thumb32_BL_imm, "BL (imm)", "11110Svvvvvvvvvv11j1jvvvvvvvvvvv") // v4T
|
||||||
|
INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jvvvvvvvvvvv") // v5T
|
||||||
//INST(thumb32_B, "B", "11110-----------10-1------------")
|
//INST(thumb32_B, "B", "11110-----------10-1------------")
|
||||||
//INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------")
|
//INST(thumb32_B_cond, "B (cond)", "11110-----------10-0------------")
|
||||||
|
|
||||||
|
@ -187,9 +188,6 @@
|
||||||
//INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------")
|
//INST(thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------")
|
||||||
//INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------")
|
//INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------")
|
||||||
|
|
||||||
// Undefined
|
|
||||||
//INST(thumb32_UDF, "UDF", "1111100--111--------------------")
|
|
||||||
|
|
||||||
// Data Processing (register)
|
// Data Processing (register)
|
||||||
//INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----")
|
//INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----")
|
||||||
//INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----")
|
//INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----")
|
||||||
|
@ -307,10 +305,3 @@ INST(thumb32_UMAAL, "UMAAL", "111110111110nnnnllllhh
|
||||||
//INST(thumb32_MCR, "MCR", "11101110---0---------------1----")
|
//INST(thumb32_MCR, "MCR", "11101110---0---------------1----")
|
||||||
//INST(thumb32_MRC2, "MRC2", "11111110---1---------------1----")
|
//INST(thumb32_MRC2, "MRC2", "11111110---1---------------1----")
|
||||||
//INST(thumb32_MRC, "MRC", "11101110---1---------------1----")
|
//INST(thumb32_MRC, "MRC", "11101110---1---------------1----")
|
||||||
|
|
||||||
// Branch instructions
|
|
||||||
INST(thumb32_BL_imm, "BL (imm)", "11110vvvvvvvvvvv11111vvvvvvvvvvv") // v4T
|
|
||||||
INST(thumb32_BLX_imm, "BLX (imm)", "11110vvvvvvvvvvv11101vvvvvvvvvvv") // v5T
|
|
||||||
|
|
||||||
// Misc instructions
|
|
||||||
INST(thumb32_UDF, "UDF", "111101111111----1010------------") // v6T2
|
|
||||||
|
|
|
@ -8,7 +8,10 @@
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
// BL <label>
|
// BL <label>
|
||||||
bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<11> hi, Imm<11> lo) {
|
bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
|
||||||
|
const Imm<1> i1{j1 == S};
|
||||||
|
const Imm<1> i2{j2 == S};
|
||||||
|
|
||||||
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
|
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
@ -16,14 +19,19 @@ bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<11> hi, Imm<11> lo) {
|
||||||
ir.PushRSB(ir.current_location.AdvancePC(4));
|
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||||
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
|
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
|
||||||
|
|
||||||
const s32 imm32 = static_cast<s32>((concatenate(hi, lo).SignExtend<u32>() << 1) + 4);
|
const s32 imm32 = static_cast<s32>((concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1) + 4);
|
||||||
const auto new_location = ir.current_location.AdvancePC(imm32).AdvanceIT();
|
const auto new_location = ir.current_location
|
||||||
|
.AdvancePC(imm32)
|
||||||
|
.AdvanceIT();
|
||||||
ir.SetTerm(IR::Term::LinkBlock{new_location});
|
ir.SetTerm(IR::Term::LinkBlock{new_location});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BLX <label>
|
// BLX <label>
|
||||||
bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<11> hi, Imm<11> lo) {
|
bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
|
||||||
|
const Imm<1> i1{j1 == S};
|
||||||
|
const Imm<1> i2{j2 == S};
|
||||||
|
|
||||||
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
|
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
@ -35,7 +43,7 @@ bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<11> hi, Imm<11> lo) {
|
||||||
ir.PushRSB(ir.current_location.AdvancePC(4));
|
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||||
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
|
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
|
||||||
|
|
||||||
const s32 imm32 = static_cast<s32>(concatenate(hi, lo).SignExtend<u32>() << 1);
|
const s32 imm32 = static_cast<s32>(concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1);
|
||||||
const auto new_location = ir.current_location
|
const auto new_location = ir.current_location
|
||||||
.SetPC(ir.AlignPC(4) + imm32)
|
.SetPC(ir.AlignPC(4) + imm32)
|
||||||
.SetTFlag(false)
|
.SetTFlag(false)
|
||||||
|
|
|
@ -116,11 +116,13 @@ struct ThumbTranslatorVisitor final {
|
||||||
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
|
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
|
||||||
bool thumb16_B_t2(Imm<11> imm11);
|
bool thumb16_B_t2(Imm<11> imm11);
|
||||||
|
|
||||||
// thumb32
|
// thumb32 miscellaneous control instructions
|
||||||
bool thumb32_BL_imm(Imm<11> hi, Imm<11> lo);
|
|
||||||
bool thumb32_BLX_imm(Imm<11> hi, Imm<11> lo);
|
|
||||||
bool thumb32_UDF();
|
bool thumb32_UDF();
|
||||||
|
|
||||||
|
// thumb32 branch instructions
|
||||||
|
bool thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
|
||||||
|
bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
|
||||||
|
|
||||||
// thumb32 data processing (register) instructions
|
// thumb32 data processing (register) instructions
|
||||||
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
|
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
|
||||||
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
|
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
|
||||||
|
|
Loading…
Reference in a new issue