Exclusive Monitor: Rework exclusive monitor interface.

This commit is contained in:
Fernando Sahmkow
2020-03-10 18:07:44 -04:00
committed by MerryMage
parent b5d8b24a3c
commit 97b9d3e058
15 changed files with 278 additions and 151 deletions

View File

@@ -100,11 +100,6 @@ void IREmitter::ClearExclusive() {
Inst(Opcode::A64ClearExclusive);
}
void IREmitter::SetExclusive(const IR::U64& vaddr, size_t byte_size) {
ASSERT(byte_size == 1 || byte_size == 2 || byte_size == 4 || byte_size == 8 || byte_size == 16);
Inst(Opcode::A64SetExclusive, vaddr, Imm8(u8(byte_size)));
}
IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr) {
return Inst<IR::U8>(Opcode::A64ReadMemory8, vaddr);
}
@@ -125,6 +120,26 @@ IR::U128 IREmitter::ReadMemory128(const IR::U64& vaddr) {
return Inst<IR::U128>(Opcode::A64ReadMemory128, vaddr);
}
IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U64& vaddr) {
return Inst<IR::U8>(Opcode::A64ExclusiveReadMemory8, vaddr);
}
IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U64& vaddr) {
return Inst<IR::U16>(Opcode::A64ExclusiveReadMemory16, vaddr);
}
IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U64& vaddr) {
return Inst<IR::U32>(Opcode::A64ExclusiveReadMemory32, vaddr);
}
IR::U64 IREmitter::ExclusiveReadMemory64(const IR::U64& vaddr) {
return Inst<IR::U64>(Opcode::A64ExclusiveReadMemory64, vaddr);
}
IR::U128 IREmitter::ExclusiveReadMemory128(const IR::U64& vaddr) {
return Inst<IR::U128>(Opcode::A64ExclusiveReadMemory128, vaddr);
}
void IREmitter::WriteMemory8(const IR::U64& vaddr, const IR::U8& value) {
Inst(Opcode::A64WriteMemory8, vaddr, value);
}

View File

@@ -54,12 +54,16 @@ public:
void SetTPIDR(const IR::U64& value);
void ClearExclusive();
void SetExclusive(const IR::U64& vaddr, size_t byte_size);
IR::U8 ReadMemory8(const IR::U64& vaddr);
IR::U16 ReadMemory16(const IR::U64& vaddr);
IR::U32 ReadMemory32(const IR::U64& vaddr);
IR::U64 ReadMemory64(const IR::U64& vaddr);
IR::U128 ReadMemory128(const IR::U64& vaddr);
IR::U8 ExclusiveReadMemory8(const IR::U64& vaddr);
IR::U16 ExclusiveReadMemory16(const IR::U64& vaddr);
IR::U32 ExclusiveReadMemory32(const IR::U64& vaddr);
IR::U64 ExclusiveReadMemory64(const IR::U64& vaddr);
IR::U128 ExclusiveReadMemory128(const IR::U64& vaddr);
void WriteMemory8(const IR::U64& vaddr, const IR::U8& value);
void WriteMemory16(const IR::U64& vaddr, const IR::U16& value);
void WriteMemory32(const IR::U64& vaddr, const IR::U32& value);

View File

@@ -308,7 +308,24 @@ void TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccType /*acc_
}
}
IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType /*acc_type*/, IR::UAnyU128 value) {
IR::UAnyU128 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType /*acctype*/) {
switch (bytesize) {
case 1:
return ir.ExclusiveReadMemory8(address);
case 2:
return ir.ExclusiveReadMemory16(address);
case 4:
return ir.ExclusiveReadMemory32(address);
case 8:
return ir.ExclusiveReadMemory64(address);
case 16:
return ir.ExclusiveReadMemory128(address);
default:
ASSERT_FALSE("Invalid bytesize parameter {}", bytesize);
}
}
IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType /*acctype*/, IR::UAnyU128 value) {
switch (bytesize) {
case 1:
return ir.ExclusiveWriteMemory8(address, value);

View File

@@ -57,6 +57,7 @@ struct TranslatorVisitor final {
IR::UAnyU128 Mem(IR::U64 address, size_t size, IR::AccType acctype);
void Mem(IR::U64 address, size_t size, IR::AccType acctype, IR::UAnyU128 value);
IR::UAnyU128 ExclusiveMem(IR::U64 address, size_t size, IR::AccType acctype);
IR::U32 ExclusiveMem(IR::U64 address, size_t size, IR::AccType acctype, IR::UAnyU128 value);
IR::U32U64 SignExtend(IR::UAny value, size_t to_size);

View File

@@ -56,8 +56,7 @@ static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, s
break;
}
case IR::MemOp::LOAD: {
v.ir.SetExclusive(address, dbytes);
const IR::UAnyU128 data = v.Mem(address, dbytes, acctype);
const IR::UAnyU128 data = v.ExclusiveMem(address, dbytes, acctype);
if (pair && elsize == 64) {
v.X(64, Rt, v.ir.VectorGetElement(64, data, 0));
v.X(64, *Rt2, v.ir.VectorGetElement(64, data, 1));

View File

@@ -99,6 +99,20 @@ bool Inst::IsSharedMemoryReadOrWrite() const {
return IsSharedMemoryRead() || IsSharedMemoryWrite();
}
bool Inst::IsExclusiveMemoryRead() const {
switch (op) {
case Opcode::A64ExclusiveReadMemory8:
case Opcode::A64ExclusiveReadMemory16:
case Opcode::A64ExclusiveReadMemory32:
case Opcode::A64ExclusiveReadMemory64:
case Opcode::A64ExclusiveReadMemory128:
return true;
default:
return false;
}
}
bool Inst::IsExclusiveMemoryWrite() const {
switch (op) {
case Opcode::A32ExclusiveWriteMemory8:
@@ -118,7 +132,7 @@ bool Inst::IsExclusiveMemoryWrite() const {
}
bool Inst::IsMemoryRead() const {
return IsSharedMemoryRead();
return IsSharedMemoryRead() || IsExclusiveMemoryRead();
}
bool Inst::IsMemoryWrite() const {
@@ -457,7 +471,7 @@ bool Inst::AltersExclusiveState() const {
return op == Opcode::A32ClearExclusive ||
op == Opcode::A32SetExclusive ||
op == Opcode::A64ClearExclusive ||
op == Opcode::A64SetExclusive ||
IsExclusiveMemoryRead() ||
IsExclusiveMemoryWrite();
}

View File

@@ -44,6 +44,8 @@ public:
bool IsSharedMemoryWrite() const;
/// Determines whether or not this instruction performs a shared memory read or write.
bool IsSharedMemoryReadOrWrite() const;
/// Determines whether or not this instruction performs an atomic memory read.
bool IsExclusiveMemoryRead() const;
/// Determines whether or not this instruction performs an atomic memory write.
bool IsExclusiveMemoryWrite() const;

View File

@@ -637,12 +637,16 @@ A32OPC(ExclusiveWriteMemory64, U32, U32,
// A64 Memory access
A64OPC(ClearExclusive, Void, )
A64OPC(SetExclusive, Void, U64, U8 )
A64OPC(ReadMemory8, U8, U64 )
A64OPC(ReadMemory16, U16, U64 )
A64OPC(ReadMemory32, U32, U64 )
A64OPC(ReadMemory64, U64, U64 )
A64OPC(ReadMemory128, U128, U64 )
A64OPC(ExclusiveReadMemory8, U8, U64 )
A64OPC(ExclusiveReadMemory16, U16, U64 )
A64OPC(ExclusiveReadMemory32, U32, U64 )
A64OPC(ExclusiveReadMemory64, U64, U64 )
A64OPC(ExclusiveReadMemory128, U128, U64 )
A64OPC(WriteMemory8, Void, U64, U8 )
A64OPC(WriteMemory16, Void, U64, U16 )
A64OPC(WriteMemory32, Void, U64, U32 )