A32: Add AccType information and propagate to IR-level

This commit is contained in:
merry 2022-03-26 15:31:42 +00:00
parent 614ecb7020
commit 5cf2d59913
15 changed files with 286 additions and 248 deletions

View file

@ -229,55 +229,55 @@ void IREmitter::ClearExclusive() {
Inst(Opcode::A32ClearExclusive); Inst(Opcode::A32ClearExclusive);
} }
IR::UAny IREmitter::ReadMemory(size_t bitsize, const IR::U32& vaddr) { IR::UAny IREmitter::ReadMemory(size_t bitsize, const IR::U32& vaddr, IR::AccType acc_type) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return ReadMemory8(vaddr); return ReadMemory8(vaddr, acc_type);
case 16: case 16:
return ReadMemory16(vaddr); return ReadMemory16(vaddr, acc_type);
case 32: case 32:
return ReadMemory32(vaddr); return ReadMemory32(vaddr, acc_type);
case 64: case 64:
return ReadMemory64(vaddr); return ReadMemory64(vaddr, acc_type);
} }
ASSERT_FALSE("Invalid bitsize"); ASSERT_FALSE("Invalid bitsize");
} }
IR::U8 IREmitter::ReadMemory8(const IR::U32& vaddr) { IR::U8 IREmitter::ReadMemory8(const IR::U32& vaddr, IR::AccType acc_type) {
return Inst<IR::U8>(Opcode::A32ReadMemory8, vaddr); return Inst<IR::U8>(Opcode::A32ReadMemory8, vaddr, IR::Value{acc_type});
} }
IR::U16 IREmitter::ReadMemory16(const IR::U32& vaddr) { IR::U16 IREmitter::ReadMemory16(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U16>(Opcode::A32ReadMemory16, vaddr); const auto value = Inst<IR::U16>(Opcode::A32ReadMemory16, vaddr, IR::Value{acc_type});
return current_location.EFlag() ? ByteReverseHalf(value) : value; return current_location.EFlag() ? ByteReverseHalf(value) : value;
} }
IR::U32 IREmitter::ReadMemory32(const IR::U32& vaddr) { IR::U32 IREmitter::ReadMemory32(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U32>(Opcode::A32ReadMemory32, vaddr); const auto value = Inst<IR::U32>(Opcode::A32ReadMemory32, vaddr, IR::Value{acc_type});
return current_location.EFlag() ? ByteReverseWord(value) : value; return current_location.EFlag() ? ByteReverseWord(value) : value;
} }
IR::U64 IREmitter::ReadMemory64(const IR::U32& vaddr) { IR::U64 IREmitter::ReadMemory64(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U64>(Opcode::A32ReadMemory64, vaddr); const auto value = Inst<IR::U64>(Opcode::A32ReadMemory64, vaddr, IR::Value{acc_type});
return current_location.EFlag() ? ByteReverseDual(value) : value; return current_location.EFlag() ? ByteReverseDual(value) : value;
} }
IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U32& vaddr) { IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U32& vaddr, IR::AccType acc_type) {
return Inst<IR::U8>(Opcode::A32ExclusiveReadMemory8, vaddr); return Inst<IR::U8>(Opcode::A32ExclusiveReadMemory8, vaddr, IR::Value{acc_type});
} }
IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U32& vaddr) { IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U16>(Opcode::A32ExclusiveReadMemory16, vaddr); const auto value = Inst<IR::U16>(Opcode::A32ExclusiveReadMemory16, vaddr, IR::Value{acc_type});
return current_location.EFlag() ? ByteReverseHalf(value) : value; return current_location.EFlag() ? ByteReverseHalf(value) : value;
} }
IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U32& vaddr) { IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U32>(Opcode::A32ExclusiveReadMemory32, vaddr); const auto value = Inst<IR::U32>(Opcode::A32ExclusiveReadMemory32, vaddr, IR::Value{acc_type});
return current_location.EFlag() ? ByteReverseWord(value) : value; return current_location.EFlag() ? ByteReverseWord(value) : value;
} }
std::pair<IR::U32, IR::U32> IREmitter::ExclusiveReadMemory64(const IR::U32& vaddr) { std::pair<IR::U32, IR::U32> IREmitter::ExclusiveReadMemory64(const IR::U32& vaddr, IR::AccType acc_type) {
const auto value = Inst<IR::U64>(Opcode::A32ExclusiveReadMemory64, vaddr); const auto value = Inst<IR::U64>(Opcode::A32ExclusiveReadMemory64, vaddr, IR::Value{acc_type});
const auto lo = LeastSignificantWord(value); const auto lo = LeastSignificantWord(value);
const auto hi = MostSignificantWord(value).result; const auto hi = MostSignificantWord(value).result;
if (current_location.EFlag()) { if (current_location.EFlag()) {
@ -287,80 +287,80 @@ std::pair<IR::U32, IR::U32> IREmitter::ExclusiveReadMemory64(const IR::U32& vadd
return std::make_pair(lo, hi); return std::make_pair(lo, hi);
} }
void IREmitter::WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value) { void IREmitter::WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value, IR::AccType acc_type) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return WriteMemory8(vaddr, value); return WriteMemory8(vaddr, value, acc_type);
case 16: case 16:
return WriteMemory16(vaddr, value); return WriteMemory16(vaddr, value, acc_type);
case 32: case 32:
return WriteMemory32(vaddr, value); return WriteMemory32(vaddr, value, acc_type);
case 64: case 64:
return WriteMemory64(vaddr, value); return WriteMemory64(vaddr, value, acc_type);
} }
ASSERT_FALSE("Invalid bitsize"); ASSERT_FALSE("Invalid bitsize");
} }
void IREmitter::WriteMemory8(const IR::U32& vaddr, const IR::U8& value) { void IREmitter::WriteMemory8(const IR::U32& vaddr, const IR::U8& value, IR::AccType acc_type) {
Inst(Opcode::A32WriteMemory8, vaddr, value); Inst(Opcode::A32WriteMemory8, vaddr, value, IR::Value{acc_type});
} }
void IREmitter::WriteMemory16(const IR::U32& vaddr, const IR::U16& value) { void IREmitter::WriteMemory16(const IR::U32& vaddr, const IR::U16& value, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto v = ByteReverseHalf(value); const auto v = ByteReverseHalf(value);
Inst(Opcode::A32WriteMemory16, vaddr, v); Inst(Opcode::A32WriteMemory16, vaddr, v, IR::Value{acc_type});
} else { } else {
Inst(Opcode::A32WriteMemory16, vaddr, value); Inst(Opcode::A32WriteMemory16, vaddr, value, IR::Value{acc_type});
} }
} }
void IREmitter::WriteMemory32(const IR::U32& vaddr, const IR::U32& value) { void IREmitter::WriteMemory32(const IR::U32& vaddr, const IR::U32& value, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto v = ByteReverseWord(value); const auto v = ByteReverseWord(value);
Inst(Opcode::A32WriteMemory32, vaddr, v); Inst(Opcode::A32WriteMemory32, vaddr, v, IR::Value{acc_type});
} else { } else {
Inst(Opcode::A32WriteMemory32, vaddr, value); Inst(Opcode::A32WriteMemory32, vaddr, value, IR::Value{acc_type});
} }
} }
void IREmitter::WriteMemory64(const IR::U32& vaddr, const IR::U64& value) { void IREmitter::WriteMemory64(const IR::U32& vaddr, const IR::U64& value, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto v = ByteReverseDual(value); const auto v = ByteReverseDual(value);
Inst(Opcode::A32WriteMemory64, vaddr, v); Inst(Opcode::A32WriteMemory64, vaddr, v, IR::Value{acc_type});
} else { } else {
Inst(Opcode::A32WriteMemory64, vaddr, value); Inst(Opcode::A32WriteMemory64, vaddr, value, IR::Value{acc_type});
} }
} }
IR::U32 IREmitter::ExclusiveWriteMemory8(const IR::U32& vaddr, const IR::U8& value) { IR::U32 IREmitter::ExclusiveWriteMemory8(const IR::U32& vaddr, const IR::U8& value, IR::AccType acc_type) {
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory8, vaddr, value); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory8, vaddr, value, IR::Value{acc_type});
} }
IR::U32 IREmitter::ExclusiveWriteMemory16(const IR::U32& vaddr, const IR::U16& value) { IR::U32 IREmitter::ExclusiveWriteMemory16(const IR::U32& vaddr, const IR::U16& value, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto v = ByteReverseHalf(value); const auto v = ByteReverseHalf(value);
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory16, vaddr, v); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory16, vaddr, v, IR::Value{acc_type});
} else { } else {
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory16, vaddr, value); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory16, vaddr, value, IR::Value{acc_type});
} }
} }
IR::U32 IREmitter::ExclusiveWriteMemory32(const IR::U32& vaddr, const IR::U32& value) { IR::U32 IREmitter::ExclusiveWriteMemory32(const IR::U32& vaddr, const IR::U32& value, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto v = ByteReverseWord(value); const auto v = ByteReverseWord(value);
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory32, vaddr, v); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory32, vaddr, v, IR::Value{acc_type});
} else { } else {
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory32, vaddr, value); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory32, vaddr, value, IR::Value{acc_type});
} }
} }
IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& value_lo, const IR::U32& value_hi) { IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& value_lo, const IR::U32& value_hi, IR::AccType acc_type) {
if (current_location.EFlag()) { if (current_location.EFlag()) {
const auto vlo = ByteReverseWord(value_lo); const auto vlo = ByteReverseWord(value_lo);
const auto vhi = ByteReverseWord(value_hi); const auto vhi = ByteReverseWord(value_hi);
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(vlo, vhi)); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(vlo, vhi), IR::Value{acc_type});
} else { } else {
return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(value_lo, value_hi)); return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(value_lo, value_hi), IR::Value{acc_type});
} }
} }

View file

@ -80,24 +80,24 @@ public:
void SetFpscrNZCV(const IR::NZCV& new_fpscr_nzcv); void SetFpscrNZCV(const IR::NZCV& new_fpscr_nzcv);
void ClearExclusive(); void ClearExclusive();
IR::UAny ReadMemory(size_t bitsize, const IR::U32& vaddr); IR::UAny ReadMemory(size_t bitsize, const IR::U32& vaddr, IR::AccType acc_type);
IR::U8 ReadMemory8(const IR::U32& vaddr); IR::U8 ReadMemory8(const IR::U32& vaddr, IR::AccType acc_type);
IR::U16 ReadMemory16(const IR::U32& vaddr); IR::U16 ReadMemory16(const IR::U32& vaddr, IR::AccType acc_type);
IR::U32 ReadMemory32(const IR::U32& vaddr); IR::U32 ReadMemory32(const IR::U32& vaddr, IR::AccType acc_type);
IR::U64 ReadMemory64(const IR::U32& vaddr); IR::U64 ReadMemory64(const IR::U32& vaddr, IR::AccType acc_type);
IR::U8 ExclusiveReadMemory8(const IR::U32& vaddr); IR::U8 ExclusiveReadMemory8(const IR::U32& vaddr, IR::AccType acc_type);
IR::U16 ExclusiveReadMemory16(const IR::U32& vaddr); IR::U16 ExclusiveReadMemory16(const IR::U32& vaddr, IR::AccType acc_type);
IR::U32 ExclusiveReadMemory32(const IR::U32& vaddr); IR::U32 ExclusiveReadMemory32(const IR::U32& vaddr, IR::AccType acc_type);
std::pair<IR::U32, IR::U32> ExclusiveReadMemory64(const IR::U32& vaddr); std::pair<IR::U32, IR::U32> ExclusiveReadMemory64(const IR::U32& vaddr, IR::AccType acc_type);
void WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value); void WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value, IR::AccType acc_type);
void WriteMemory8(const IR::U32& vaddr, const IR::U8& value); void WriteMemory8(const IR::U32& vaddr, const IR::U8& value, IR::AccType acc_type);
void WriteMemory16(const IR::U32& vaddr, const IR::U16& value); void WriteMemory16(const IR::U32& vaddr, const IR::U16& value, IR::AccType acc_type);
void WriteMemory32(const IR::U32& vaddr, const IR::U32& value); void WriteMemory32(const IR::U32& vaddr, const IR::U32& value, IR::AccType acc_type);
void WriteMemory64(const IR::U32& vaddr, const IR::U64& value); void WriteMemory64(const IR::U32& vaddr, const IR::U64& value, IR::AccType acc_type);
IR::U32 ExclusiveWriteMemory8(const IR::U32& vaddr, const IR::U8& value); IR::U32 ExclusiveWriteMemory8(const IR::U32& vaddr, const IR::U8& value, IR::AccType acc_type);
IR::U32 ExclusiveWriteMemory16(const IR::U32& vaddr, const IR::U16& value); IR::U32 ExclusiveWriteMemory16(const IR::U32& vaddr, const IR::U16& value, IR::AccType acc_type);
IR::U32 ExclusiveWriteMemory32(const IR::U32& vaddr, const IR::U32& value); IR::U32 ExclusiveWriteMemory32(const IR::U32& vaddr, const IR::U32& value, IR::AccType acc_type);
IR::U32 ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& value_lo, const IR::U32& value_hi); IR::U32 ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& value_lo, const IR::U32& value_hi, IR::AccType acc_type);
void CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, size_t opc2); void CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, size_t opc2);
void CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, CoprocReg CRn, CoprocReg CRm, size_t opc2, const IR::U32& word); void CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, CoprocReg CRn, CoprocReg CRm, size_t opc2, const IR::U32& word);

View file

@ -103,7 +103,7 @@ bool TranslatorVisitor::v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, s
const ExtReg ext_reg = d + i * inc + r; const ExtReg ext_reg = d + i * inc + r;
const IR::U64 shifted_element = ir.LogicalShiftRight(ir.GetExtendedRegister(ext_reg), ir.Imm8(static_cast<u8>(e * ebytes * 8))); const IR::U64 shifted_element = ir.LogicalShiftRight(ir.GetExtendedRegister(ext_reg), ir.Imm8(static_cast<u8>(e * ebytes * 8)));
const IR::UAny element = ir.LeastSignificant(8 * ebytes, shifted_element); const IR::UAny element = ir.LeastSignificant(8 * ebytes, shifted_element);
ir.WriteMemory(8 * ebytes, address, element); ir.WriteMemory(8 * ebytes, address, element, IR::AccType::NORMAL);
address = ir.Add(address, ir.Imm32(static_cast<u32>(ebytes))); address = ir.Add(address, ir.Imm32(static_cast<u32>(ebytes)));
} }
@ -156,7 +156,7 @@ bool TranslatorVisitor::v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type, s
for (size_t r = 0; r < regs; r++) { for (size_t r = 0; r < regs; r++) {
for (size_t e = 0; e < elements; e++) { for (size_t e = 0; e < elements; e++) {
for (size_t i = 0; i < nelem; i++) { for (size_t i = 0; i < nelem; i++) {
const IR::U64 element = ir.ZeroExtendToLong(ir.ReadMemory(ebytes * 8, address)); const IR::U64 element = ir.ZeroExtendToLong(ir.ReadMemory(ebytes * 8, address, IR::AccType::NORMAL));
const IR::U64 shifted_element = ir.LogicalShiftLeft(element, ir.Imm8(static_cast<u8>(e * ebytes * 8))); const IR::U64 shifted_element = ir.LogicalShiftLeft(element, ir.Imm8(static_cast<u8>(e * ebytes * 8)));
const ExtReg ext_reg = d + i * inc + r; const ExtReg ext_reg = d + i * inc + r;
@ -221,7 +221,7 @@ bool TranslatorVisitor::v8_VLD_all_lanes(bool D, Reg n, size_t Vd, size_t nn, si
auto address = ir.GetRegister(n); auto address = ir.GetRegister(n);
for (size_t i = 0; i < nelem; i++) { for (size_t i = 0; i < nelem; i++) {
const auto element = ir.ReadMemory(ebytes * 8, address); const auto element = ir.ReadMemory(ebytes * 8, address, IR::AccType::NORMAL);
const auto replicated_element = ir.VectorBroadcast(ebytes * 8, element); const auto replicated_element = ir.VectorBroadcast(ebytes * 8, element);
for (size_t r = 0; r < regs; r++) { for (size_t r = 0; r < regs; r++) {
@ -291,7 +291,7 @@ bool TranslatorVisitor::v8_VST_single(bool D, Reg n, size_t Vd, size_t sz, size_
const ExtReg ext_reg = d + i * inc; const ExtReg ext_reg = d + i * inc;
const auto element = ir.VectorGetElement(ebytes * 8, ir.GetVector(ext_reg), index); const auto element = ir.VectorGetElement(ebytes * 8, ir.GetVector(ext_reg), index);
ir.WriteMemory(ebytes * 8, address, element); ir.WriteMemory(ebytes * 8, address, element, IR::AccType::NORMAL);
address = ir.Add(address, ir.Imm32(static_cast<u32>(ebytes))); address = ir.Add(address, ir.Imm32(static_cast<u32>(ebytes)));
} }
@ -352,7 +352,7 @@ bool TranslatorVisitor::v8_VLD_single(bool D, Reg n, size_t Vd, size_t sz, size_
auto address = ir.GetRegister(n); auto address = ir.GetRegister(n);
for (size_t i = 0; i < nelem; i++) { for (size_t i = 0; i < nelem; i++) {
const auto element = ir.ReadMemory(ebytes * 8, address); const auto element = ir.ReadMemory(ebytes * 8, address, IR::AccType::NORMAL);
const ExtReg ext_reg = d + i * inc; const ExtReg ext_reg = d + i * inc;
const auto new_reg = ir.VectorSetElement(ebytes * 8, ir.GetVector(ext_reg), index, element); const auto new_reg = ir.VectorSetElement(ebytes * 8, ir.GetVector(ext_reg), index, element);

View file

@ -71,7 +71,7 @@ bool TranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
const bool add = U; const bool add = U;
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm12.ZeroExtend()) : (base - imm12.ZeroExtend()); const u32 address = add ? (base + imm12.ZeroExtend()) : (base - imm12.ZeroExtend());
const auto data = ir.ReadMemory32(ir.Imm32(address)); const auto data = ir.ReadMemory32(ir.Imm32(address), IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.LoadWritePC(data); ir.LoadWritePC(data);
@ -102,7 +102,7 @@ bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.LoadWritePC(data); ir.LoadWritePC(data);
@ -138,7 +138,7 @@ bool TranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Re
const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result; const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result;
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.LoadWritePC(data); ir.LoadWritePC(data);
@ -164,7 +164,7 @@ bool TranslatorVisitor::arm_LDRB_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
const bool add = U; const bool add = U;
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm32) : (base - imm32); const u32 address = add ? (base + imm32) : (base - imm32);
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(ir.Imm32(address))); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(ir.Imm32(address), IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -193,7 +193,7 @@ bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -217,7 +217,7 @@ bool TranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result; const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result;
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -243,11 +243,17 @@ bool TranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm32) : (base - imm32); const u32 address = add ? (base + imm32) : (base - imm32);
const auto data_a = ir.ReadMemory32(ir.Imm32(address));
const auto data_b = ir.ReadMemory32(ir.Imm32(address + 4));
ir.SetRegister(t, data_a); // NOTE: If alignment is exactly off by 4, each word is an atomic access.
ir.SetRegister(t2, data_b); const IR::U64 data = ir.ReadMemory64(ir.Imm32(address), IR::AccType::ATOMIC);
if (ir.current_location.EFlag()) {
ir.SetRegister(t, ir.MostSignificantWord(data).result);
ir.SetRegister(t2, ir.LeastSignificantWord(data));
} else {
ir.SetRegister(t, ir.LeastSignificantWord(data));
ir.SetRegister(t2, ir.MostSignificantWord(data).result);
}
return true; return true;
} }
@ -282,13 +288,18 @@ bool TranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend(); const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address_a = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto address_b = ir.Add(address_a, ir.Imm32(4));
const auto data_a = ir.ReadMemory32(address_a);
const auto data_b = ir.ReadMemory32(address_b);
ir.SetRegister(t, data_a); // NOTE: If alignment is exactly off by 4, each word is an atomic access.
ir.SetRegister(t2, data_b); const IR::U64 data = ir.ReadMemory64(address, IR::AccType::ATOMIC);
if (ir.current_location.EFlag()) {
ir.SetRegister(t, ir.MostSignificantWord(data).result);
ir.SetRegister(t2, ir.LeastSignificantWord(data));
} else {
ir.SetRegister(t, ir.LeastSignificantWord(data));
ir.SetRegister(t2, ir.MostSignificantWord(data).result);
}
return true; return true;
} }
@ -317,13 +328,18 @@ bool TranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, R
const Reg t2 = t + 1; const Reg t2 = t + 1;
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address_a = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto address_b = ir.Add(address_a, ir.Imm32(4));
const auto data_a = ir.ReadMemory32(address_a);
const auto data_b = ir.ReadMemory32(address_b);
ir.SetRegister(t, data_a); // NOTE: If alignment is exactly off by 4, each word is an atomic access.
ir.SetRegister(t2, data_b); const IR::U64 data = ir.ReadMemory64(address, IR::AccType::ATOMIC);
if (ir.current_location.EFlag()) {
ir.SetRegister(t, ir.MostSignificantWord(data).result);
ir.SetRegister(t2, ir.LeastSignificantWord(data));
} else {
ir.SetRegister(t, ir.LeastSignificantWord(data));
ir.SetRegister(t2, ir.MostSignificantWord(data).result);
}
return true; return true;
} }
@ -346,7 +362,7 @@ bool TranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t, I
const bool add = U; const bool add = U;
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm32) : (base - imm32); const u32 address = add ? (base + imm32) : (base - imm32);
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(ir.Imm32(address))); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(ir.Imm32(address), IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -375,7 +391,7 @@ bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend(); const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -399,7 +415,7 @@ bool TranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -420,7 +436,7 @@ bool TranslatorVisitor::arm_LDRSB_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Im
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm32) : (base - imm32); const u32 address = add ? (base + imm32) : (base - imm32);
const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(ir.Imm32(address))); const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(ir.Imm32(address), IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -449,7 +465,7 @@ bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n,
const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend(); const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -473,7 +489,7 @@ bool TranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg n,
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -493,7 +509,7 @@ bool TranslatorVisitor::arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Im
const bool add = U; const bool add = U;
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = add ? (base + imm32) : (base - imm32); const u32 address = add ? (base + imm32) : (base - imm32);
const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(ir.Imm32(address))); const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(ir.Imm32(address), IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -522,7 +538,7 @@ bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n,
const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend(); const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -546,7 +562,7 @@ bool TranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n,
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -565,7 +581,7 @@ bool TranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
const auto offset = ir.Imm32(imm12.ZeroExtend()); const auto offset = ir.Imm32(imm12.ZeroExtend());
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory32(address, ir.GetRegister(t)); ir.WriteMemory32(address, ir.GetRegister(t), IR::AccType::NORMAL);
return true; return true;
} }
@ -586,7 +602,7 @@ bool TranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Re
const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result; const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result;
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory32(address, ir.GetRegister(t)); ir.WriteMemory32(address, ir.GetRegister(t), IR::AccType::NORMAL);
return true; return true;
} }
@ -607,7 +623,7 @@ bool TranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = ir.Imm32(imm12.ZeroExtend()); const auto offset = ir.Imm32(imm12.ZeroExtend());
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t))); ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t)), IR::AccType::NORMAL);
return true; return true;
} }
@ -628,7 +644,7 @@ bool TranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result; const auto offset = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()).result;
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t))); ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t)), IR::AccType::NORMAL);
return true; return true;
} }
@ -658,13 +674,15 @@ bool TranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend(); const u32 imm32 = concatenate(imm8a, imm8b).ZeroExtend();
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address_a = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto address_b = ir.Add(address_a, ir.Imm32(4));
const auto value_a = ir.GetRegister(t); const auto value_a = ir.GetRegister(t);
const auto value_b = ir.GetRegister(t2); const auto value_b = ir.GetRegister(t2);
ir.WriteMemory32(address_a, value_a); const IR::U64 data = ir.current_location.EFlag() ? ir.Pack2x32To1x64(value_b, value_a)
ir.WriteMemory32(address_b, value_b); : ir.Pack2x32To1x64(value_a, value_b);
// NOTE: If alignment is exactly off by 4, each word is an atomic access.
ir.WriteMemory64(address, data, IR::AccType::ATOMIC);
return true; return true;
} }
@ -693,13 +711,15 @@ bool TranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, R
} }
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address_a = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
const auto address_b = ir.Add(address_a, ir.Imm32(4));
const auto value_a = ir.GetRegister(t); const auto value_a = ir.GetRegister(t);
const auto value_b = ir.GetRegister(t2); const auto value_b = ir.GetRegister(t2);
ir.WriteMemory32(address_a, value_a); const IR::U64 data = ir.current_location.EFlag() ? ir.Pack2x32To1x64(value_b, value_a)
ir.WriteMemory32(address_b, value_b); : ir.Pack2x32To1x64(value_a, value_b);
// NOTE: If alignment is exactly off by 4, each word is an atomic access.
ir.WriteMemory64(address, data, IR::AccType::ATOMIC);
return true; return true;
} }
@ -722,7 +742,7 @@ bool TranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = ir.Imm32(imm32); const auto offset = ir.Imm32(imm32);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t))); ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t)), IR::AccType::NORMAL);
return true; return true;
} }
@ -744,7 +764,7 @@ bool TranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, R
const auto offset = ir.GetRegister(m); const auto offset = ir.GetRegister(m);
const auto address = GetAddress(ir, P, U, W, n, offset); const auto address = GetAddress(ir, P, U, W, n, offset);
ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t))); ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t)), IR::AccType::NORMAL);
return true; return true;
} }
@ -752,7 +772,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
auto address = start_address; auto address = start_address;
for (size_t i = 0; i <= 14; i++) { for (size_t i = 0; i <= 14; i++) {
if (Common::Bit(i, list)) { if (Common::Bit(i, list)) {
ir.SetRegister(static_cast<Reg>(i), ir.ReadMemory32(address)); ir.SetRegister(static_cast<Reg>(i), ir.ReadMemory32(address, IR::AccType::ATOMIC));
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -760,7 +780,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
ir.SetRegister(n, writeback_address); ir.SetRegister(n, writeback_address);
} }
if (Common::Bit<15>(list)) { if (Common::Bit<15>(list)) {
ir.LoadWritePC(ir.ReadMemory32(address)); ir.LoadWritePC(ir.ReadMemory32(address, IR::AccType::ATOMIC));
if (n == Reg::R13) if (n == Reg::R13)
ir.SetTerm(IR::Term::PopRSBHint{}); ir.SetTerm(IR::Term::PopRSBHint{});
else else
@ -854,7 +874,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
auto address = start_address; auto address = start_address;
for (size_t i = 0; i <= 14; i++) { for (size_t i = 0; i <= 14; i++) {
if (Common::Bit(i, list)) { if (Common::Bit(i, list)) {
ir.WriteMemory32(address, ir.GetRegister(static_cast<Reg>(i))); ir.WriteMemory32(address, ir.GetRegister(static_cast<Reg>(i)), IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -862,7 +882,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
ir.SetRegister(n, writeback_address); ir.SetRegister(n, writeback_address);
} }
if (Common::Bit<15>(list)) { if (Common::Bit<15>(list)) {
ir.WriteMemory32(address, ir.Imm32(ir.PC())); ir.WriteMemory32(address, ir.Imm32(ir.PC()), IR::AccType::ATOMIC);
} }
return true; return true;
} }

View file

@ -24,8 +24,9 @@ bool TranslatorVisitor::arm_SWP(Cond cond, Reg n, Reg t, Reg t2) {
return true; return true;
} }
const auto data = ir.ReadMemory32(ir.GetRegister(n)); // TODO (HACK): Implement bus locking here
ir.WriteMemory32(ir.GetRegister(n), ir.GetRegister(t2)); const auto data = ir.ReadMemory32(ir.GetRegister(n), IR::AccType::SWAP);
ir.WriteMemory32(ir.GetRegister(n), ir.GetRegister(t2), IR::AccType::SWAP);
// TODO: Alignment check // TODO: Alignment check
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -42,8 +43,9 @@ bool TranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) {
return true; return true;
} }
const auto data = ir.ReadMemory8(ir.GetRegister(n)); // TODO (HACK): Implement bus locking here
ir.WriteMemory8(ir.GetRegister(n), ir.LeastSignificantByte(ir.GetRegister(t2))); const auto data = ir.ReadMemory8(ir.GetRegister(n), IR::AccType::SWAP);
ir.WriteMemory8(ir.GetRegister(n), ir.LeastSignificantByte(ir.GetRegister(t2)), IR::AccType::SWAP);
// TODO: Alignment check // TODO: Alignment check
ir.SetRegister(t, ir.ZeroExtendByteToWord(data)); ir.SetRegister(t, ir.ZeroExtendByteToWord(data));
return true; return true;
@ -60,7 +62,7 @@ bool TranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ReadMemory32(address)); // AccType::Ordered ir.SetRegister(t, ir.ReadMemory32(address, IR::AccType::ORDERED));
return true; return true;
} }
// LDAB<c> <Rt>, [<Rn>] // LDAB<c> <Rt>, [<Rn>]
@ -74,7 +76,7 @@ bool TranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory8(address))); // AccType::Ordered ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory8(address, IR::AccType::ORDERED)));
return true; return true;
} }
// LDAH<c> <Rt>, [<Rn>] // LDAH<c> <Rt>, [<Rn>]
@ -88,7 +90,7 @@ bool TranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory16(address))); // AccType::Ordered ir.SetRegister(t, ir.ZeroExtendToWord(ir.ReadMemory16(address, IR::AccType::ORDERED)));
return true; return true;
} }
@ -103,7 +105,7 @@ bool TranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ExclusiveReadMemory32(address)); // AccType::Ordered ir.SetRegister(t, ir.ExclusiveReadMemory32(address, IR::AccType::ORDERED));
return true; return true;
} }
@ -118,7 +120,7 @@ bool TranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address))); // AccType::Ordered ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address, IR::AccType::ORDERED)));
return true; return true;
} }
@ -133,7 +135,7 @@ bool TranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto [lo, hi] = ir.ExclusiveReadMemory64(address); // AccType::Ordered const auto [lo, hi] = ir.ExclusiveReadMemory64(address, IR::AccType::ORDERED);
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR // DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
ir.SetRegister(t, lo); ir.SetRegister(t, lo);
ir.SetRegister(t + 1, hi); ir.SetRegister(t + 1, hi);
@ -151,7 +153,7 @@ bool TranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address))); // AccType::Ordered ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address, IR::AccType::ORDERED)));
return true; return true;
} }
@ -166,7 +168,7 @@ bool TranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.WriteMemory32(address, ir.GetRegister(t)); // AccType::Ordered ir.WriteMemory32(address, ir.GetRegister(t), IR::AccType::ORDERED);
return true; return true;
} }
@ -181,7 +183,7 @@ bool TranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t))); // AccType::Ordered ir.WriteMemory8(address, ir.LeastSignificantByte(ir.GetRegister(t)), IR::AccType::ORDERED);
return true; return true;
} }
@ -196,7 +198,7 @@ bool TranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t))); // AccType::Ordered ir.WriteMemory16(address, ir.LeastSignificantHalf(ir.GetRegister(t)), IR::AccType::ORDERED);
return true; return true;
} }
@ -216,7 +218,7 @@ bool TranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantByte(ir.GetRegister(t)); const auto value = ir.LeastSignificantByte(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory8(address, value); // AccType::Ordered const auto passed = ir.ExclusiveWriteMemory8(address, value, IR::AccType::ORDERED);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -238,7 +240,7 @@ bool TranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value_lo = ir.GetRegister(t); const auto value_lo = ir.GetRegister(t);
const auto value_hi = ir.GetRegister(t2); const auto value_hi = ir.GetRegister(t2);
const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi); // AccType::Ordered const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi, IR::AccType::ORDERED);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -259,7 +261,7 @@ bool TranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto value = ir.LeastSignificantHalf(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory16(address, value); // AccType::Ordered const auto passed = ir.ExclusiveWriteMemory16(address, value, IR::AccType::ORDERED);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -280,7 +282,7 @@ bool TranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.GetRegister(t); const auto value = ir.GetRegister(t);
const auto passed = ir.ExclusiveWriteMemory32(address, value); const auto passed = ir.ExclusiveWriteMemory32(address, value, IR::AccType::ORDERED);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -296,7 +298,7 @@ bool TranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ExclusiveReadMemory32(address)); ir.SetRegister(t, ir.ExclusiveReadMemory32(address, IR::AccType::ATOMIC));
return true; return true;
} }
@ -311,7 +313,7 @@ bool TranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address))); ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address, IR::AccType::ATOMIC)));
return true; return true;
} }
@ -326,7 +328,7 @@ bool TranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto [lo, hi] = ir.ExclusiveReadMemory64(address); const auto [lo, hi] = ir.ExclusiveReadMemory64(address, IR::AccType::ATOMIC);
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR // DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
ir.SetRegister(t, lo); ir.SetRegister(t, lo);
ir.SetRegister(t + 1, hi); ir.SetRegister(t + 1, hi);
@ -344,7 +346,7 @@ bool TranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address))); ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address, IR::AccType::ATOMIC)));
return true; return true;
} }
@ -364,7 +366,7 @@ bool TranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.GetRegister(t); const auto value = ir.GetRegister(t);
const auto passed = ir.ExclusiveWriteMemory32(address, value); const auto passed = ir.ExclusiveWriteMemory32(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -385,7 +387,7 @@ bool TranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantByte(ir.GetRegister(t)); const auto value = ir.LeastSignificantByte(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory8(address, value); const auto passed = ir.ExclusiveWriteMemory8(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -408,7 +410,7 @@ bool TranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value_lo = ir.GetRegister(t); const auto value_lo = ir.GetRegister(t);
const auto value_hi = ir.GetRegister(t2); const auto value_hi = ir.GetRegister(t2);
const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi); const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -429,7 +431,7 @@ bool TranslatorVisitor::arm_STREXH(Cond cond, Reg n, Reg d, Reg t) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto value = ir.LeastSignificantHalf(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory16(address, value); const auto passed = ir.ExclusiveWriteMemory16(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }

View file

@ -444,7 +444,7 @@ bool TranslatorVisitor::thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) {
bool TranslatorVisitor::thumb16_LDR_literal(Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb16_LDR_literal(Reg t, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const u32 address = ir.AlignPC(4) + imm32; const u32 address = ir.AlignPC(4) + imm32;
const auto data = ir.ReadMemory32(ir.Imm32(address)); const auto data = ir.ReadMemory32(ir.Imm32(address), IR::AccType::NORMAL);
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -456,7 +456,7 @@ bool TranslatorVisitor::thumb16_STR_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.GetRegister(t); const auto data = ir.GetRegister(t);
ir.WriteMemory32(address, data); ir.WriteMemory32(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -466,7 +466,7 @@ bool TranslatorVisitor::thumb16_STRH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto data = ir.LeastSignificantHalf(ir.GetRegister(t));
ir.WriteMemory16(address, data); ir.WriteMemory16(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -476,7 +476,7 @@ bool TranslatorVisitor::thumb16_STRB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.LeastSignificantByte(ir.GetRegister(t)); const auto data = ir.LeastSignificantByte(ir.GetRegister(t));
ir.WriteMemory8(address, data); ir.WriteMemory8(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -484,7 +484,7 @@ bool TranslatorVisitor::thumb16_STRB_reg(Reg m, Reg n, Reg t) {
// Rt cannot encode R15. // Rt cannot encode R15.
bool TranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -494,7 +494,7 @@ bool TranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) {
// Rt cannot encode R15. // Rt cannot encode R15.
bool TranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -504,7 +504,7 @@ bool TranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) {
// Rt cannot encode R15. // Rt cannot encode R15.
bool TranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -514,7 +514,7 @@ bool TranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) {
// Rt cannot encode R15. // Rt cannot encode R15.
bool TranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -524,7 +524,7 @@ bool TranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) {
// Rt cannot encode R15. // Rt cannot encode R15.
bool TranslatorVisitor::thumb16_LDRSH_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRSH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -537,7 +537,7 @@ bool TranslatorVisitor::thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.GetRegister(t); const auto data = ir.GetRegister(t);
ir.WriteMemory32(address, data); ir.WriteMemory32(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -546,7 +546,7 @@ bool TranslatorVisitor::thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
bool TranslatorVisitor::thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 2; const u32 imm32 = imm5.ZeroExtend() << 2;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -559,7 +559,7 @@ bool TranslatorVisitor::thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.LeastSignificantByte(ir.GetRegister(t)); const auto data = ir.LeastSignificantByte(ir.GetRegister(t));
ir.WriteMemory8(address, data); ir.WriteMemory8(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -568,7 +568,7 @@ bool TranslatorVisitor::thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t) {
bool TranslatorVisitor::thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend(); const u32 imm32 = imm5.ZeroExtend();
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -580,7 +580,7 @@ bool TranslatorVisitor::thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto data = ir.LeastSignificantHalf(ir.GetRegister(t));
ir.WriteMemory16(address, data); ir.WriteMemory16(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -588,7 +588,7 @@ bool TranslatorVisitor::thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t) {
bool TranslatorVisitor::thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 1; const u32 imm32 = imm5.ZeroExtend() << 1;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address, IR::AccType::NORMAL));
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -602,7 +602,7 @@ bool TranslatorVisitor::thumb16_STR_imm_t2(Reg t, Imm<8> imm8) {
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.GetRegister(t); const auto data = ir.GetRegister(t);
ir.WriteMemory32(address, data); ir.WriteMemory32(address, data, IR::AccType::NORMAL);
return true; return true;
} }
@ -612,7 +612,7 @@ bool TranslatorVisitor::thumb16_LDR_imm_t2(Reg t, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const Reg n = Reg::SP; const Reg n = Reg::SP;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
ir.SetRegister(t, data); ir.SetRegister(t, data);
return true; return true;
@ -766,7 +766,7 @@ bool TranslatorVisitor::thumb16_PUSH(bool M, RegList reg_list) {
if (Common::Bit(i, reg_list)) { if (Common::Bit(i, reg_list)) {
// TODO: Deal with alignment // TODO: Deal with alignment
const auto Ri = ir.GetRegister(static_cast<Reg>(i)); const auto Ri = ir.GetRegister(static_cast<Reg>(i));
ir.WriteMemory32(address, Ri); ir.WriteMemory32(address, Ri, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -789,7 +789,7 @@ bool TranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
for (size_t i = 0; i < 15; i++) { for (size_t i = 0; i < 15; i++) {
if (Common::Bit(i, reg_list)) { if (Common::Bit(i, reg_list)) {
// TODO: Deal with alignment // TODO: Deal with alignment
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::ATOMIC);
ir.SetRegister(static_cast<Reg>(i), data); ir.SetRegister(static_cast<Reg>(i), data);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
@ -797,7 +797,7 @@ bool TranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
if (Common::Bit<15>(reg_list)) { if (Common::Bit<15>(reg_list)) {
// TODO(optimization): Possible location for an RSB pop. // TODO(optimization): Possible location for an RSB pop.
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::ATOMIC);
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
ir.LoadWritePC(data); ir.LoadWritePC(data);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
@ -879,7 +879,7 @@ bool TranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
if (Common::Bit(i, reg_list)) { if (Common::Bit(i, reg_list)) {
const auto Ri = ir.GetRegister(static_cast<Reg>(i)); const auto Ri = ir.GetRegister(static_cast<Reg>(i));
ir.WriteMemory32(address, Ri); ir.WriteMemory32(address, Ri, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -899,7 +899,7 @@ bool TranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) {
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
if (Common::Bit(i, reg_list)) { if (Common::Bit(i, reg_list)) {
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::ATOMIC);
ir.SetRegister(static_cast<Reg>(i), data); ir.SetRegister(static_cast<Reg>(i), data);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }

View file

@ -31,7 +31,7 @@ static bool LoadByteLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const u32 base = v.ir.AlignPC(4); const u32 base = v.ir.AlignPC(4);
const u32 address = U ? (base + imm32) : (base - imm32); const u32 address = U ? (base + imm32) : (base - imm32);
const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory8(v.ir.Imm32(address))); const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory8(v.ir.Imm32(address), IR::AccType::NORMAL));
v.ir.SetRegister(t, data); v.ir.SetRegister(t, data);
return true; return true;
@ -46,7 +46,7 @@ static bool LoadByteRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Re
const auto reg_m = v.ir.GetRegister(m); const auto reg_m = v.ir.GetRegister(m);
const auto offset = v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(imm2.ZeroExtend<u8>())); const auto offset = v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(imm2.ZeroExtend<u8>()));
const auto address = v.ir.Add(reg_n, offset); const auto address = v.ir.Add(reg_n, offset);
const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory8(address)); const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory8(address, IR::AccType::NORMAL));
v.ir.SetRegister(t, data); v.ir.SetRegister(t, data);
return true; return true;
@ -58,7 +58,7 @@ static bool LoadByteImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32)) const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32))
: v.ir.Sub(reg_n, v.ir.Imm32(imm32)); : v.ir.Sub(reg_n, v.ir.Imm32(imm32));
const IR::U32 address = P ? offset_address : reg_n; const IR::U32 address = P ? offset_address : reg_n;
const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory8(address)); const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory8(address, IR::AccType::NORMAL));
v.ir.SetRegister(t, data); v.ir.SetRegister(t, data);
if (W) { if (W) {

View file

@ -13,7 +13,7 @@ static bool LoadHalfLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
const auto imm32 = imm12.ZeroExtend(); const auto imm32 = imm12.ZeroExtend();
const auto base = v.ir.AlignPC(4); const auto base = v.ir.AlignPC(4);
const auto address = U ? (base + imm32) : (base - imm32); const auto address = U ? (base + imm32) : (base - imm32);
const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory16(v.ir.Imm32(address))); const auto data = (v.ir.*ext_fn)(v.ir.ReadMemory16(v.ir.Imm32(address), IR::AccType::NORMAL));
v.ir.SetRegister(t, data); v.ir.SetRegister(t, data);
return true; return true;
@ -28,7 +28,7 @@ static bool LoadHalfRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Re
const IR::U32 reg_n = v.ir.GetRegister(n); const IR::U32 reg_n = v.ir.GetRegister(n);
const IR::U32 offset = v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(imm2.ZeroExtend<u8>())); const IR::U32 offset = v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(imm2.ZeroExtend<u8>()));
const IR::U32 address = v.ir.Add(reg_n, offset); const IR::U32 address = v.ir.Add(reg_n, offset);
const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory16(address)); const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory16(address, IR::AccType::NORMAL));
v.ir.SetRegister(t, data); v.ir.SetRegister(t, data);
return true; return true;
@ -41,7 +41,7 @@ static bool LoadHalfImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U
: v.ir.Sub(reg_n, v.ir.Imm32(imm32)); : v.ir.Sub(reg_n, v.ir.Imm32(imm32));
const IR::U32 address = P ? offset_address const IR::U32 address = P ? offset_address
: reg_n; : reg_n;
const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory16(address)); const IR::U32 data = (v.ir.*ext_fn)(v.ir.ReadMemory16(address, IR::AccType::NORMAL));
if (W) { if (W) {
v.ir.SetRegister(n, offset_address); v.ir.SetRegister(n, offset_address);

View file

@ -24,10 +24,10 @@ static bool TableBranch(TranslatorVisitor& v, Reg n, Reg m, bool half) {
IR::U32 halfwords; IR::U32 halfwords;
if (half) { if (half) {
const auto data = v.ir.ReadMemory16(v.ir.Add(reg_n, v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(1)))); const auto data = v.ir.ReadMemory16(v.ir.Add(reg_n, v.ir.LogicalShiftLeft(reg_m, v.ir.Imm8(1))), IR::AccType::NORMAL);
halfwords = v.ir.ZeroExtendToWord(data); halfwords = v.ir.ZeroExtendToWord(data);
} else { } else {
halfwords = v.ir.ZeroExtendToWord(v.ir.ReadMemory8(v.ir.Add(reg_n, reg_m))); halfwords = v.ir.ZeroExtendToWord(v.ir.ReadMemory8(v.ir.Add(reg_n, reg_m), IR::AccType::NORMAL));
} }
const auto current_pc = v.ir.Imm32(v.ir.PC()); const auto current_pc = v.ir.Imm32(v.ir.PC());
@ -51,12 +51,18 @@ static bool LoadDualImmediate(TranslatorVisitor& v, bool P, bool U, bool W, Reg
const IR::U32 reg_n = v.ir.GetRegister(n); const IR::U32 reg_n = v.ir.GetRegister(n);
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm)) const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm))
: v.ir.Sub(reg_n, v.ir.Imm32(imm)); : v.ir.Sub(reg_n, v.ir.Imm32(imm));
const IR::U32 address_1 = P ? offset_address const IR::U32 address = P ? offset_address : reg_n;
: reg_n;
const IR::U32 address_2 = v.ir.Add(address_1, v.ir.Imm32(4));
v.ir.SetRegister(t, v.ir.ReadMemory32(address_1)); // NOTE: If alignment is exactly off by 4, each word is an atomic access.
v.ir.SetRegister(t2, v.ir.ReadMemory32(address_2)); const IR::U64 data = v.ir.ReadMemory64(address, IR::AccType::ATOMIC);
if (v.ir.current_location.EFlag()) {
v.ir.SetRegister(t, v.ir.MostSignificantWord(data).result);
v.ir.SetRegister(t2, v.ir.LeastSignificantWord(data));
} else {
v.ir.SetRegister(t, v.ir.LeastSignificantWord(data));
v.ir.SetRegister(t2, v.ir.MostSignificantWord(data).result);
}
if (W) { if (W) {
v.ir.SetRegister(n, offset_address); v.ir.SetRegister(n, offset_address);
@ -73,12 +79,20 @@ static bool LoadDualLiteral(TranslatorVisitor& v, bool U, bool W, Reg t, Reg t2,
} }
const auto imm = imm8.ZeroExtend() << 2; const auto imm = imm8.ZeroExtend() << 2;
const auto address_1 = U ? v.ir.Add(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm)) const auto address = U ? v.ir.Add(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm))
: v.ir.Sub(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm)); : v.ir.Sub(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm));
const auto address_2 = v.ir.Add(address_1, v.ir.Imm32(4));
// NOTE: If alignment is exactly off by 4, each word is an atomic access.
const IR::U64 data = v.ir.ReadMemory64(address, IR::AccType::ATOMIC);
if (v.ir.current_location.EFlag()) {
v.ir.SetRegister(t, v.ir.MostSignificantWord(data).result);
v.ir.SetRegister(t2, v.ir.LeastSignificantWord(data));
} else {
v.ir.SetRegister(t, v.ir.LeastSignificantWord(data));
v.ir.SetRegister(t2, v.ir.MostSignificantWord(data).result);
}
v.ir.SetRegister(t, v.ir.ReadMemory32(address_1));
v.ir.SetRegister(t2, v.ir.ReadMemory32(address_2));
return true; return true;
} }
@ -97,12 +111,13 @@ static bool StoreDual(TranslatorVisitor& v, bool P, bool U, bool W, Reg n, Reg t
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm)) const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm))
: v.ir.Sub(reg_n, v.ir.Imm32(imm)); : v.ir.Sub(reg_n, v.ir.Imm32(imm));
const IR::U32 address_1 = P ? offset_address const IR::U32 address = P ? offset_address : reg_n;
: reg_n;
const IR::U32 address_2 = v.ir.Add(address_1, v.ir.Imm32(4));
v.ir.WriteMemory32(address_1, reg_t); const IR::U64 data = v.ir.current_location.EFlag() ? v.ir.Pack2x32To1x64(reg_t2, reg_t)
v.ir.WriteMemory32(address_2, reg_t2); : v.ir.Pack2x32To1x64(reg_t, reg_t2);
// NOTE: If alignment is exactly off by 4, each word is an atomic access.
v.ir.WriteMemory64(address, data, IR::AccType::ATOMIC);
if (W) { if (W) {
v.ir.SetRegister(n, offset_address); v.ir.SetRegister(n, offset_address);
@ -116,7 +131,7 @@ bool TranslatorVisitor::thumb32_LDA(Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.SetRegister(t, ir.ReadMemory32(address)); // AccType::Ordered ir.SetRegister(t, ir.ReadMemory32(address, IR::AccType::ORDERED));
return true; return true;
} }
@ -150,7 +165,7 @@ bool TranslatorVisitor::thumb32_LDREX(Reg n, Reg t, Imm<8> imm8) {
} }
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend() << 2)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend() << 2));
const auto value = ir.ExclusiveReadMemory32(address); const auto value = ir.ExclusiveReadMemory32(address, IR::AccType::ATOMIC);
ir.SetRegister(t, value); ir.SetRegister(t, value);
return true; return true;
@ -162,7 +177,7 @@ bool TranslatorVisitor::thumb32_LDREXB(Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory8(address)); const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory8(address, IR::AccType::ATOMIC));
ir.SetRegister(t, value); ir.SetRegister(t, value);
return true; return true;
@ -174,7 +189,7 @@ bool TranslatorVisitor::thumb32_LDREXD(Reg n, Reg t, Reg t2) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto [lo, hi] = ir.ExclusiveReadMemory64(address); const auto [lo, hi] = ir.ExclusiveReadMemory64(address, IR::AccType::ATOMIC);
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR // DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
ir.SetRegister(t, lo); ir.SetRegister(t, lo);
@ -188,7 +203,7 @@ bool TranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory16(address)); const auto value = ir.ZeroExtendToWord(ir.ExclusiveReadMemory16(address, IR::AccType::ATOMIC));
ir.SetRegister(t, value); ir.SetRegister(t, value);
return true; return true;
@ -200,7 +215,7 @@ bool TranslatorVisitor::thumb32_STL(Reg n, Reg t) {
} }
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
ir.WriteMemory32(address, ir.GetRegister(t)); // AccType::Ordered ir.WriteMemory32(address, ir.GetRegister(t), IR::AccType::ORDERED);
return true; return true;
} }
@ -214,7 +229,7 @@ bool TranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend() << 2)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend() << 2));
const auto value = ir.GetRegister(t); const auto value = ir.GetRegister(t);
const auto passed = ir.ExclusiveWriteMemory32(address, value); const auto passed = ir.ExclusiveWriteMemory32(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -229,7 +244,7 @@ bool TranslatorVisitor::thumb32_STREXB(Reg n, Reg t, Reg d) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantByte(ir.GetRegister(t)); const auto value = ir.LeastSignificantByte(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory8(address, value); const auto passed = ir.ExclusiveWriteMemory8(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -245,7 +260,7 @@ bool TranslatorVisitor::thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value_lo = ir.GetRegister(t); const auto value_lo = ir.GetRegister(t);
const auto value_hi = ir.GetRegister(t2); const auto value_hi = ir.GetRegister(t2);
const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi); const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }
@ -260,7 +275,7 @@ bool TranslatorVisitor::thumb32_STREXH(Reg n, Reg t, Reg d) {
const auto address = ir.GetRegister(n); const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto value = ir.LeastSignificantHalf(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory16(address, value); const auto passed = ir.ExclusiveWriteMemory16(address, value, IR::AccType::ATOMIC);
ir.SetRegister(d, passed); ir.SetRegister(d, passed);
return true; return true;
} }

View file

@ -15,7 +15,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, const IR::U32
auto address = start_address; auto address = start_address;
for (size_t i = 0; i <= 14; i++) { for (size_t i = 0; i <= 14; i++) {
if (Common::Bit(i, list)) { if (Common::Bit(i, list)) {
ir.SetRegister(static_cast<Reg>(i), ir.ReadMemory32(address)); ir.SetRegister(static_cast<Reg>(i), ir.ReadMemory32(address, IR::AccType::ATOMIC));
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -24,7 +24,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, const IR::U32
} }
if (Common::Bit<15>(list)) { if (Common::Bit<15>(list)) {
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
ir.LoadWritePC(ir.ReadMemory32(address)); ir.LoadWritePC(ir.ReadMemory32(address, IR::AccType::ATOMIC));
if (n == Reg::R13) { if (n == Reg::R13) {
ir.SetTerm(IR::Term::PopRSBHint{}); ir.SetTerm(IR::Term::PopRSBHint{});
} else { } else {
@ -39,7 +39,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, const IR::U32
auto address = start_address; auto address = start_address;
for (size_t i = 0; i <= 14; i++) { for (size_t i = 0; i <= 14; i++) {
if (Common::Bit(i, list)) { if (Common::Bit(i, list)) {
ir.WriteMemory32(address, ir.GetRegister(static_cast<Reg>(i))); ir.WriteMemory32(address, ir.GetRegister(static_cast<Reg>(i)), IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }

View file

@ -18,7 +18,7 @@ bool TranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) {
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const u32 base = ir.AlignPC(4); const u32 base = ir.AlignPC(4);
const u32 address = U ? base + imm32 : base - imm32; const u32 address = U ? base + imm32 : base - imm32;
const auto data = ir.ReadMemory32(ir.Imm32(address)); const auto data = ir.ReadMemory32(ir.Imm32(address), IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
@ -48,7 +48,7 @@ bool TranslatorVisitor::thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool W, I
: ir.Sub(reg_n, ir.Imm32(imm32)); : ir.Sub(reg_n, ir.Imm32(imm32));
const IR::U32 address = P ? offset_address const IR::U32 address = P ? offset_address
: reg_n; : reg_n;
const IR::U32 data = ir.ReadMemory32(address); const IR::U32 data = ir.ReadMemory32(address, IR::AccType::NORMAL);
if (W) { if (W) {
ir.SetRegister(n, offset_address); ir.SetRegister(n, offset_address);
@ -79,7 +79,7 @@ bool TranslatorVisitor::thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12) {
const auto imm32 = imm12.ZeroExtend(); const auto imm32 = imm12.ZeroExtend();
const auto reg_n = ir.GetRegister(n); const auto reg_n = ir.GetRegister(n);
const auto address = ir.Add(reg_n, ir.Imm32(imm32)); const auto address = ir.Add(reg_n, ir.Imm32(imm32));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
@ -104,7 +104,7 @@ bool TranslatorVisitor::thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
const auto reg_n = ir.GetRegister(n); const auto reg_n = ir.GetRegister(n);
const auto offset = ir.LogicalShiftLeft(reg_m, ir.Imm8(imm2.ZeroExtend<u8>())); const auto offset = ir.LogicalShiftLeft(reg_m, ir.Imm8(imm2.ZeroExtend<u8>()));
const auto address = ir.Add(reg_n, offset); const auto address = ir.Add(reg_n, offset);
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address, IR::AccType::NORMAL);
if (t == Reg::PC) { if (t == Reg::PC) {
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();

View file

@ -32,15 +32,15 @@ static bool StoreRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m
using StoreImmFn = void (*)(TranslatorVisitor&, const IR::U32&, const IR::U32&); using StoreImmFn = void (*)(TranslatorVisitor&, const IR::U32&, const IR::U32&);
static void StoreImmByteFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmByteFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory8(address, v.ir.LeastSignificantByte(data)); v.ir.WriteMemory8(address, v.ir.LeastSignificantByte(data), IR::AccType::NORMAL);
} }
static void StoreImmHalfFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmHalfFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory16(address, v.ir.LeastSignificantHalf(data)); v.ir.WriteMemory16(address, v.ir.LeastSignificantHalf(data), IR::AccType::NORMAL);
} }
static void StoreImmWordFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmWordFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory32(address, data); v.ir.WriteMemory32(address, data, IR::AccType::NORMAL);
} }
static bool StoreImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, StoreImmFn store_fn) { static bool StoreImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, StoreImmFn store_fn) {
@ -110,7 +110,7 @@ bool TranslatorVisitor::thumb32_STRBT(Reg n, Reg t, Imm<8> imm8) {
bool TranslatorVisitor::thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory8(offset_address, ir.LeastSignificantByte(data)); ir.WriteMemory8(offset_address, ir.LeastSignificantByte(data), IR::AccType::NORMAL);
}); });
} }
@ -163,7 +163,7 @@ bool TranslatorVisitor::thumb32_STRHT(Reg n, Reg t, Imm<8> imm8) {
bool TranslatorVisitor::thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory16(offset_address, ir.LeastSignificantHalf(data)); ir.WriteMemory16(offset_address, ir.LeastSignificantHalf(data), IR::AccType::NORMAL);
}); });
} }
@ -216,7 +216,7 @@ bool TranslatorVisitor::thumb32_STRT(Reg n, Reg t, Imm<8> imm8) {
bool TranslatorVisitor::thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory32(offset_address, data); ir.WriteMemory32(offset_address, data, IR::AccType::NORMAL);
}); });
} }

View file

@ -1186,16 +1186,16 @@ bool TranslatorVisitor::vfp_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm<8> i
for (size_t i = 0; i < regs; ++i) { for (size_t i = 0; i < regs; ++i) {
if (sz) { if (sz) {
auto lo = ir.ReadMemory32(address); auto lo = ir.ReadMemory32(address, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
auto hi = ir.ReadMemory32(address); auto hi = ir.ReadMemory32(address, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
if (ir.current_location.EFlag()) { if (ir.current_location.EFlag()) {
std::swap(lo, hi); std::swap(lo, hi);
} }
ir.SetExtendedRegister(d + i, ir.Pack2x32To1x64(lo, hi)); ir.SetExtendedRegister(d + i, ir.Pack2x32To1x64(lo, hi));
} else { } else {
const auto res = ir.ReadMemory32(address); const auto res = ir.ReadMemory32(address, IR::AccType::ATOMIC);
ir.SetExtendedRegister(d + i, res); ir.SetExtendedRegister(d + i, res);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
@ -1232,12 +1232,12 @@ bool TranslatorVisitor::vfp_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm<8>
auto hi = ir.MostSignificantWord(reg_d).result; auto hi = ir.MostSignificantWord(reg_d).result;
if (ir.current_location.EFlag()) if (ir.current_location.EFlag())
std::swap(lo, hi); std::swap(lo, hi);
ir.WriteMemory32(address, lo); ir.WriteMemory32(address, lo, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
ir.WriteMemory32(address, hi); ir.WriteMemory32(address, hi, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} else { } else {
ir.WriteMemory32(address, ir.GetExtendedRegister(d + i)); ir.WriteMemory32(address, ir.GetExtendedRegister(d + i), IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
} }
@ -1258,14 +1258,14 @@ bool TranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd, bo
const auto address = U ? ir.Add(base, ir.Imm32(imm32)) : ir.Sub(base, ir.Imm32(imm32)); const auto address = U ? ir.Add(base, ir.Imm32(imm32)) : ir.Sub(base, ir.Imm32(imm32));
if (sz) { if (sz) {
auto lo = ir.ReadMemory32(address); auto lo = ir.ReadMemory32(address, IR::AccType::ATOMIC);
auto hi = ir.ReadMemory32(ir.Add(address, ir.Imm32(4))); auto hi = ir.ReadMemory32(ir.Add(address, ir.Imm32(4)), IR::AccType::ATOMIC);
if (ir.current_location.EFlag()) { if (ir.current_location.EFlag()) {
std::swap(lo, hi); std::swap(lo, hi);
} }
ir.SetExtendedRegister(d, ir.Pack2x32To1x64(lo, hi)); ir.SetExtendedRegister(d, ir.Pack2x32To1x64(lo, hi));
} else { } else {
ir.SetExtendedRegister(d, ir.ReadMemory32(address)); ir.SetExtendedRegister(d, ir.ReadMemory32(address, IR::AccType::ATOMIC));
} }
return true; return true;
@ -1289,10 +1289,10 @@ bool TranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bo
if (ir.current_location.EFlag()) { if (ir.current_location.EFlag()) {
std::swap(lo, hi); std::swap(lo, hi);
} }
ir.WriteMemory32(address, lo); ir.WriteMemory32(address, lo, IR::AccType::ATOMIC);
ir.WriteMemory32(ir.Add(address, ir.Imm32(4)), hi); ir.WriteMemory32(ir.Add(address, ir.Imm32(4)), hi, IR::AccType::ATOMIC);
} else { } else {
ir.WriteMemory32(address, ir.GetExtendedRegister(d)); ir.WriteMemory32(address, ir.GetExtendedRegister(d), IR::AccType::ATOMIC);
} }
return true; return true;
@ -1341,9 +1341,9 @@ bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, R
std::swap(word1, word2); std::swap(word1, word2);
} }
ir.WriteMemory32(address, word1); ir.WriteMemory32(address, word1, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
ir.WriteMemory32(address, word2); ir.WriteMemory32(address, word2, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
@ -1386,7 +1386,7 @@ bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, R
} }
for (size_t i = 0; i < regs; i++) { for (size_t i = 0; i < regs; i++) {
const auto word = ir.GetExtendedRegister(d + i); const auto word = ir.GetExtendedRegister(d + i);
ir.WriteMemory32(address, word); ir.WriteMemory32(address, word, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
} }
@ -1428,9 +1428,9 @@ bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, R
ir.SetRegister(n, u ? IR::U32(ir.Add(address, ir.Imm32(imm32))) : address); ir.SetRegister(n, u ? IR::U32(ir.Add(address, ir.Imm32(imm32))) : address);
} }
for (size_t i = 0; i < regs; i++) { for (size_t i = 0; i < regs; i++) {
auto word1 = ir.ReadMemory32(address); auto word1 = ir.ReadMemory32(address, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
auto word2 = ir.ReadMemory32(address); auto word2 = ir.ReadMemory32(address, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
if (ir.current_location.EFlag()) { if (ir.current_location.EFlag()) {
@ -1478,7 +1478,7 @@ bool TranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, R
ir.SetRegister(n, u ? IR::U32(ir.Add(address, ir.Imm32(imm32))) : address); ir.SetRegister(n, u ? IR::U32(ir.Add(address, ir.Imm32(imm32))) : address);
} }
for (size_t i = 0; i < regs; i++) { for (size_t i = 0; i < regs; i++) {
const auto word = ir.ReadMemory32(address); const auto word = ir.ReadMemory32(address, IR::AccType::ATOMIC);
address = ir.Add(address, ir.Imm32(4)); address = ir.Add(address, ir.Imm32(4));
ir.SetExtendedRegister(d + i, word); ir.SetExtendedRegister(d + i, word);
} }

View file

@ -23,6 +23,7 @@ enum class AccType {
IC, IC,
DCZVA, DCZVA,
AT, AT,
SWAP, // TODO: Remove
}; };
} // namespace Dynarmic::IR } // namespace Dynarmic::IR

View file

@ -688,22 +688,22 @@ OPCODE(FPVectorToUnsignedFixed64, U128, U128
// A32 Memory access // A32 Memory access
A32OPC(ClearExclusive, Void, ) A32OPC(ClearExclusive, Void, )
A32OPC(ReadMemory8, U8, U32 ) A32OPC(ReadMemory8, U8, U32, AccType )
A32OPC(ReadMemory16, U16, U32 ) A32OPC(ReadMemory16, U16, U32, AccType )
A32OPC(ReadMemory32, U32, U32 ) A32OPC(ReadMemory32, U32, U32, AccType )
A32OPC(ReadMemory64, U64, U32 ) A32OPC(ReadMemory64, U64, U32, AccType )
A32OPC(ExclusiveReadMemory8, U8, U32 ) A32OPC(ExclusiveReadMemory8, U8, U32, AccType )
A32OPC(ExclusiveReadMemory16, U16, U32 ) A32OPC(ExclusiveReadMemory16, U16, U32, AccType )
A32OPC(ExclusiveReadMemory32, U32, U32 ) A32OPC(ExclusiveReadMemory32, U32, U32, AccType )
A32OPC(ExclusiveReadMemory64, U64, U32 ) A32OPC(ExclusiveReadMemory64, U64, U32, AccType )
A32OPC(WriteMemory8, Void, U32, U8 ) A32OPC(WriteMemory8, Void, U32, U8, AccType )
A32OPC(WriteMemory16, Void, U32, U16 ) A32OPC(WriteMemory16, Void, U32, U16, AccType )
A32OPC(WriteMemory32, Void, U32, U32 ) A32OPC(WriteMemory32, Void, U32, U32, AccType )
A32OPC(WriteMemory64, Void, U32, U64 ) A32OPC(WriteMemory64, Void, U32, U64, AccType )
A32OPC(ExclusiveWriteMemory8, U32, U32, U8 ) A32OPC(ExclusiveWriteMemory8, U32, U32, U8, AccType )
A32OPC(ExclusiveWriteMemory16, U32, U32, U16 ) A32OPC(ExclusiveWriteMemory16, U32, U32, U16, AccType )
A32OPC(ExclusiveWriteMemory32, U32, U32, U32 ) A32OPC(ExclusiveWriteMemory32, U32, U32, U32, AccType )
A32OPC(ExclusiveWriteMemory64, U32, U32, U64 ) A32OPC(ExclusiveWriteMemory64, U32, U32, U64, AccType )
// A64 Memory access // A64 Memory access
A64OPC(ClearExclusive, Void, ) A64OPC(ClearExclusive, Void, )