thumb32: Implement exclusive loads

Implements the remaining loads for ARMv7
This commit is contained in:
Lioncash 2021-04-19 09:26:51 -04:00 committed by merry
parent 9c6332fcbd
commit f5263cc196
4 changed files with 62 additions and 4 deletions

View file

@ -12,7 +12,7 @@ INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiii
// Load/Store Dual, Load/Store Exclusive, Table Branch
INST(thumb32_STREX, "STREX", "111010000100nnnnttttddddiiiiiiii")
//INST(thumb32_LDREX, "LDREX", "111010000101--------------------")
INST(thumb32_LDREX, "LDREX", "111010000101nnnntttt1111iiiiiiii")
INST(thumb32_STRD_imm_1, "STRD (imm)", "11101000U110nnnnttttssssiiiiiiii")
INST(thumb32_STRD_imm_2, "STRD (imm)", "11101001U1W0nnnnttttssssiiiiiiii")
INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttssssiiiiiiii")
@ -24,9 +24,9 @@ INST(thumb32_STREXH, "STREXH", "111010001100nnnntttt11
INST(thumb32_STREXD, "STREXD", "111010001100nnnnttttuuuu0111dddd")
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----")
INST(thumb32_LDREXB, "LDREXB", "111010001101nnnntttt111101001111")
INST(thumb32_LDREXH, "LDREXH", "111010001101nnnntttt111101011111")
INST(thumb32_LDREXD, "LDREXD", "111010001101nnnnttttuuuu01111111")
// Data Processing (Shifted Register)
INST(thumb32_TST_reg, "TST (reg)", "111010100001nnnn0vvv1111vvttmmmm")

View file

@ -135,6 +135,56 @@ bool ThumbTranslatorVisitor::thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Re
return StoreDual(*this, true, U, W, n, t, t2, imm8);
}
bool ThumbTranslatorVisitor::thumb32_LDREX(Reg n, Reg t, Imm<8> imm8) {
if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend() << 2));
const auto value = ir.ExclusiveReadMemory32(address);
ir.SetRegister(t, value);
return true;
}
bool ThumbTranslatorVisitor::thumb32_LDREXB(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory8(address));
ir.SetRegister(t, value);
return true;
}
bool ThumbTranslatorVisitor::thumb32_LDREXD(Reg n, Reg t, Reg t2) {
if (t == Reg::PC || t2 == Reg::PC || t == t2 || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto [lo, hi] = ir.ExclusiveReadMemory64(address);
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
ir.SetRegister(t, lo);
ir.SetRegister(t2, hi);
return true;
}
bool ThumbTranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory16(address));
ir.SetRegister(t, value);
return true;
}
bool ThumbTranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();

View file

@ -186,6 +186,10 @@ struct ThumbTranslatorVisitor final {
bool thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDREX(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDREXD(Reg n, Reg t, Reg t2);
bool thumb32_LDREXB(Reg n, Reg t);
bool thumb32_LDREXH(Reg n, Reg t);
bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8);
bool thumb32_STREXB(Reg n, Reg t, Reg d);
bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d);

View file

@ -168,6 +168,10 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
"thumb16_SETEND",
// Exclusive load/stores
"thumb32_LDREX",
"thumb32_LDREXB",
"thumb32_LDREXD",
"thumb32_LDREXH",
"thumb32_STREX",
"thumb32_STREXB",
"thumb32_STREXD",