thumb32: Implement LDA and STL

Note that those are ARMv8 additions to the Thumb instruction set.
This commit is contained in:
Sergi Granell 2022-03-11 09:54:58 +01:00 committed by merry
parent e1a266b929
commit 0ec4a23710
3 changed files with 24 additions and 0 deletions

View file

@ -19,6 +19,8 @@ INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttss
INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii") INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii")
INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000U111nnnnttttssssiiiiiiii") INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000U111nnnnttttssssiiiiiiii")
INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001U1W1nnnnttttssssiiiiiiii") INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001U1W1nnnnttttssssiiiiiiii")
INST(thumb32_STL, "STL", "111010001100nnnntttt111110101111") // v8
INST(thumb32_LDA, "LDA", "111010001101nnnntttt111110101111") // v8
INST(thumb32_STREXB, "STREXB", "111010001100nnnntttt11110100dddd") INST(thumb32_STREXB, "STREXB", "111010001100nnnntttt11110100dddd")
INST(thumb32_STREXH, "STREXH", "111010001100nnnntttt11110101dddd") INST(thumb32_STREXH, "STREXH", "111010001100nnnntttt11110101dddd")
INST(thumb32_STREXD, "STREXD", "111010001100nnnnttttuuuu0111dddd") INST(thumb32_STREXD, "STREXD", "111010001100nnnnttttuuuu0111dddd")

View file

@ -493,6 +493,7 @@ struct TranslatorVisitor final {
bool thumb32_STMDB(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 // thumb32 load/store dual, load/store exclusive, table branch instructions
bool thumb32_LDA(Reg n, Reg t);
bool thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8); bool thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8); bool thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8); bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8);
@ -503,6 +504,7 @@ struct TranslatorVisitor final {
bool thumb32_LDREXD(Reg n, Reg t, Reg t2); bool thumb32_LDREXD(Reg n, Reg t, Reg t2);
bool thumb32_LDREXB(Reg n, Reg t); bool thumb32_LDREXB(Reg n, Reg t);
bool thumb32_LDREXH(Reg n, Reg t); bool thumb32_LDREXH(Reg n, Reg t);
bool thumb32_STL(Reg n, Reg t);
bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8); bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8);
bool thumb32_STREXB(Reg n, Reg t, Reg d); bool thumb32_STREXB(Reg n, Reg t, Reg d);
bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d); bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d);

View file

@ -110,6 +110,16 @@ static bool StoreDual(TranslatorVisitor& v, bool P, bool U, bool W, Reg n, Reg t
return true; return true;
} }
bool TranslatorVisitor::thumb32_LDA(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ReadMemory32(address)); // AccType::Ordered
return true;
}
bool TranslatorVisitor::thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualImmediate(*this, false, U, true, n, t, t2, imm8); return LoadDualImmediate(*this, false, U, true, n, t, t2, imm8);
} }
@ -184,6 +194,16 @@ bool TranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) {
return true; return true;
} }
bool TranslatorVisitor::thumb32_STL(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
ir.WriteMemory32(address, ir.GetRegister(t)); // AccType::Ordered
return true;
}
bool TranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) { if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();