mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-05 22:18:16 +01:00
A32 global exlcusive monitor
This commit is contained in:
parent
58abdcce5b
commit
2c1a4843ad
12 changed files with 260 additions and 56 deletions
|
|
@ -188,11 +188,6 @@ void IREmitter::ClearExclusive() {
|
|||
Inst(Opcode::A32ClearExclusive);
|
||||
}
|
||||
|
||||
void IREmitter::SetExclusive(const IR::U32& vaddr, size_t byte_size) {
|
||||
ASSERT(byte_size == 1 || byte_size == 2 || byte_size == 4 || byte_size == 8 || byte_size == 16);
|
||||
Inst(Opcode::A32SetExclusive, vaddr, Imm8(u8(byte_size)));
|
||||
}
|
||||
|
||||
IR::UAny IREmitter::ReadMemory(size_t bitsize, const IR::U32& vaddr) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
|
|
@ -226,6 +221,31 @@ IR::U64 IREmitter::ReadMemory64(const IR::U32& vaddr) {
|
|||
return current_location.EFlag() ? ByteReverseDual(value) : value;
|
||||
}
|
||||
|
||||
IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U32& vaddr) {
|
||||
return Inst<IR::U8>(Opcode::A32ExclusiveReadMemory8, vaddr);
|
||||
}
|
||||
|
||||
IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U32& vaddr) {
|
||||
const auto value = Inst<IR::U16>(Opcode::A32ExclusiveReadMemory16, vaddr);
|
||||
return current_location.EFlag() ? ByteReverseHalf(value) : value;
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U32& vaddr) {
|
||||
const auto value = Inst<IR::U32>(Opcode::A32ExclusiveReadMemory32, vaddr);
|
||||
return current_location.EFlag() ? ByteReverseWord(value) : value;
|
||||
}
|
||||
|
||||
std::pair<IR::U32, IR::U32> IREmitter::ExclusiveReadMemory64(const IR::U32& vaddr) {
|
||||
const auto value = Inst<IR::U64>(Opcode::A32ExclusiveReadMemory64, vaddr);
|
||||
const auto lo = LeastSignificantWord(value);
|
||||
const auto hi = MostSignificantWord(value).result;
|
||||
if (current_location.EFlag()) {
|
||||
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
|
||||
return std::make_pair(ByteReverseWord(lo), ByteReverseWord(hi));
|
||||
}
|
||||
return std::make_pair(lo, hi);
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/A32/location_descriptor.h"
|
||||
#include "frontend/ir/ir_emitter.h"
|
||||
|
|
@ -71,12 +73,15 @@ public:
|
|||
void SetFpscrNZCV(const IR::NZCV& new_fpscr_nzcv);
|
||||
|
||||
void ClearExclusive();
|
||||
void SetExclusive(const IR::U32& vaddr, size_t byte_size);
|
||||
IR::UAny ReadMemory(size_t bitsize, const IR::U32& vaddr);
|
||||
IR::U8 ReadMemory8(const IR::U32& vaddr);
|
||||
IR::U16 ReadMemory16(const IR::U32& vaddr);
|
||||
IR::U32 ReadMemory32(const IR::U32& vaddr);
|
||||
IR::U64 ReadMemory64(const IR::U32& vaddr);
|
||||
IR::U8 ExclusiveReadMemory8(const IR::U32& vaddr);
|
||||
IR::U16 ExclusiveReadMemory16(const IR::U32& vaddr);
|
||||
IR::U32 ExclusiveReadMemory32(const IR::U32& vaddr);
|
||||
std::pair<IR::U32, IR::U32> ExclusiveReadMemory64(const IR::U32& vaddr);
|
||||
void WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny& value);
|
||||
void WriteMemory8(const IR::U32& vaddr, const IR::U8& value);
|
||||
void WriteMemory16(const IR::U32& vaddr, const IR::U16& value);
|
||||
|
|
|
|||
|
|
@ -103,8 +103,7 @@ bool ArmTranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 4);
|
||||
ir.SetRegister(t, ir.ReadMemory32(address)); // AccType::Ordered
|
||||
ir.SetRegister(t, ir.ExclusiveReadMemory32(address)); // AccType::Ordered
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +118,7 @@ bool ArmTranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 1);
|
||||
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ReadMemory8(address))); // AccType::Ordered
|
||||
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address))); // AccType::Ordered
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -135,12 +133,9 @@ bool ArmTranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 8);
|
||||
|
||||
const auto [lo, hi] = ir.ExclusiveReadMemory64(address); // AccType::Ordered
|
||||
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
|
||||
const auto lo = ir.ReadMemory32(address); // AccType::Ordered
|
||||
ir.SetRegister(t, lo);
|
||||
const auto hi = ir.ReadMemory32(ir.Add(address, ir.Imm32(4))); // AccType::Ordered
|
||||
ir.SetRegister(t+1, hi);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -156,8 +151,7 @@ bool ArmTranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 2);
|
||||
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ReadMemory16(address))); // AccType::Ordered
|
||||
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address))); // AccType::Ordered
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -302,8 +296,7 @@ bool ArmTranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 4);
|
||||
ir.SetRegister(t, ir.ReadMemory32(address));
|
||||
ir.SetRegister(t, ir.ExclusiveReadMemory32(address));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -318,8 +311,7 @@ bool ArmTranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 1);
|
||||
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ReadMemory8(address)));
|
||||
ir.SetRegister(t, ir.ZeroExtendByteToWord(ir.ExclusiveReadMemory8(address)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -334,12 +326,9 @@ bool ArmTranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 8);
|
||||
|
||||
const auto [lo, hi] = ir.ExclusiveReadMemory64(address);
|
||||
// DO NOT SWAP hi AND lo IN BIG ENDIAN MODE, THIS IS CORRECT BEHAVIOUR
|
||||
const auto lo = ir.ReadMemory32(address);
|
||||
ir.SetRegister(t, lo);
|
||||
const auto hi = ir.ReadMemory32(ir.Add(address, ir.Imm32(4)));
|
||||
ir.SetRegister(t+1, hi);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -355,8 +344,7 @@ bool ArmTranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) {
|
|||
}
|
||||
|
||||
const auto address = ir.GetRegister(n);
|
||||
ir.SetExclusive(address, 2);
|
||||
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)));
|
||||
ir.SetRegister(t, ir.ZeroExtendHalfToWord(ir.ExclusiveReadMemory16(address)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,10 @@ bool Inst::IsSharedMemoryReadOrWrite() const {
|
|||
|
||||
bool Inst::IsExclusiveMemoryRead() const {
|
||||
switch (op) {
|
||||
case Opcode::A32ExclusiveReadMemory8:
|
||||
case Opcode::A32ExclusiveReadMemory16:
|
||||
case Opcode::A32ExclusiveReadMemory32:
|
||||
case Opcode::A32ExclusiveReadMemory64:
|
||||
case Opcode::A64ExclusiveReadMemory8:
|
||||
case Opcode::A64ExclusiveReadMemory16:
|
||||
case Opcode::A64ExclusiveReadMemory32:
|
||||
|
|
@ -487,7 +491,6 @@ bool Inst::CausesCPUException() const {
|
|||
|
||||
bool Inst::AltersExclusiveState() const {
|
||||
return op == Opcode::A32ClearExclusive ||
|
||||
op == Opcode::A32SetExclusive ||
|
||||
op == Opcode::A64ClearExclusive ||
|
||||
IsExclusiveMemoryRead() ||
|
||||
IsExclusiveMemoryWrite();
|
||||
|
|
|
|||
|
|
@ -641,11 +641,14 @@ OPCODE(FPVectorToUnsignedFixed64, U128, U128
|
|||
|
||||
// A32 Memory access
|
||||
A32OPC(ClearExclusive, Void, )
|
||||
A32OPC(SetExclusive, Void, U32, U8 )
|
||||
A32OPC(ReadMemory8, U8, U32 )
|
||||
A32OPC(ReadMemory16, U16, U32 )
|
||||
A32OPC(ReadMemory32, U32, U32 )
|
||||
A32OPC(ReadMemory64, U64, U32 )
|
||||
A32OPC(ExclusiveReadMemory8, U8, U32 )
|
||||
A32OPC(ExclusiveReadMemory16, U16, U32 )
|
||||
A32OPC(ExclusiveReadMemory32, U32, U32 )
|
||||
A32OPC(ExclusiveReadMemory64, U64, U32 )
|
||||
A32OPC(WriteMemory8, Void, U32, U8 )
|
||||
A32OPC(WriteMemory16, Void, U32, U16 )
|
||||
A32OPC(WriteMemory32, Void, U32, U32 )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue