A32: Add AccType information and propagate to IR-level
This commit is contained in:
parent
614ecb7020
commit
5cf2d59913
15 changed files with 286 additions and 248 deletions
|
@ -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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ enum class AccType {
|
||||||
IC,
|
IC,
|
||||||
DCZVA,
|
DCZVA,
|
||||||
AT,
|
AT,
|
||||||
|
SWAP, // TODO: Remove
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dynarmic::IR
|
} // namespace Dynarmic::IR
|
||||||
|
|
|
@ -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, )
|
||||||
|
|
Loading…
Reference in a new issue