thumb32: Implement TBB/TBH
This commit is contained in:
parent
03575dea84
commit
258ca93c53
4 changed files with 57 additions and 2 deletions
|
@ -163,6 +163,7 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
|
|||
frontend/A32/translate/impl/thumb32_data_processing_shifted_register.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_byte.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_halfword.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_store_dual.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_store_multiple.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_word.cpp
|
||||
frontend/A32/translate/impl/thumb32_long_multiply.cpp
|
||||
|
|
|
@ -22,8 +22,8 @@ INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiii
|
|||
//INST(thumb32_STREXB, "STREXB", "111010001100------------0100----")
|
||||
//INST(thumb32_STREXH, "STREXH", "111010001100------------0101----")
|
||||
//INST(thumb32_STREXD, "STREXD", "111010001100------------0111----")
|
||||
//INST(thumb32_TBB, "TBB", "111010001101------------0000----")
|
||||
//INST(thumb32_TBH, "TBH", "111010001101------------0001----")
|
||||
INST(thumb32_TBB, "TBB", "111010001101nnnn111100000000mmmm")
|
||||
INST(thumb32_TBH, "TBH", "111010001101nnnn111100000001mmmm")
|
||||
//INST(thumb32_LDREXB, "LDREXB", "111010001101------------0100----")
|
||||
//INST(thumb32_LDREXH, "LDREXH", "111010001101------------0101----")
|
||||
//INST(thumb32_LDREXD, "LDREXD", "111010001101------------0111----")
|
||||
|
|
50
src/frontend/A32/translate/impl/thumb32_load_store_dual.cpp
Normal file
50
src/frontend/A32/translate/impl/thumb32_load_store_dual.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2021 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "frontend/A32/translate/impl/translate_thumb.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static bool ITBlockCheck(const A32::IREmitter& ir) {
|
||||
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
|
||||
}
|
||||
|
||||
static bool TableBranch(ThumbTranslatorVisitor& v, Reg n, Reg m, bool half) {
|
||||
if (m == Reg::PC) {
|
||||
return v.UnpredictableInstruction();
|
||||
}
|
||||
if (ITBlockCheck(v.ir)) {
|
||||
return v.UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const auto reg_m = v.ir.GetRegister(m);
|
||||
const auto reg_n = v.ir.GetRegister(n);
|
||||
|
||||
IR::U32 halfwords;
|
||||
if (half) {
|
||||
const auto data = v.ir.ReadMemory16(v.ir.Add(reg_n, v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(1))));
|
||||
halfwords = v.ir.ZeroExtendToWord(data);
|
||||
} else {
|
||||
halfwords = v.ir.ZeroExtendToWord(v.ir.ReadMemory8(v.ir.Add(reg_n, reg_m)));
|
||||
}
|
||||
|
||||
const auto current_pc = v.ir.Imm32(v.ir.PC());
|
||||
const auto branch_value = v.ir.Add(current_pc, v.ir.Add(halfwords, halfwords));
|
||||
|
||||
v.ir.UpdateUpperLocationDescriptor();
|
||||
v.ir.BranchWritePC(branch_value);
|
||||
v.ir.SetTerm(IR::Term::FastDispatchHint{});
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_TBB(Reg n, Reg m) {
|
||||
return TableBranch(*this, n, m, false);
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_TBH(Reg n, Reg m) {
|
||||
return TableBranch(*this, n, m, true);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
|
@ -179,6 +179,10 @@ struct ThumbTranslatorVisitor final {
|
|||
bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list);
|
||||
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
|
||||
|
||||
// thumb32 load/store dual, load/store exclusive, table branch instructions
|
||||
bool thumb32_TBB(Reg n, Reg m);
|
||||
bool thumb32_TBH(Reg n, Reg m);
|
||||
|
||||
// thumb32 data processing (shifted register) instructions
|
||||
bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
|
||||
bool thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
|
||||
|
|
Loading…
Reference in a new issue