thumb32: Implement exclusive loads
Implements the remaining loads for ARMv7
This commit is contained in:
parent
9c6332fcbd
commit
f5263cc196
4 changed files with 62 additions and 4 deletions
|
@ -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")
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue