emit_arm64_memory: Simplify interface to just require a bitsize
This commit is contained in:
parent
f8d8618af1
commit
ac0a20795a
4 changed files with 177 additions and 77 deletions
|
@ -26,82 +26,82 @@ void EmitIR<IR::Opcode::A32ClearExclusive>(oaknut::CodeGenerator& code, EmitCont
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory8);
|
EmitReadMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory16);
|
EmitReadMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory32);
|
EmitReadMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory64);
|
EmitReadMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory8);
|
EmitExclusiveReadMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory16);
|
EmitExclusiveReadMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory32);
|
EmitExclusiveReadMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory64);
|
EmitExclusiveReadMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32WriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory8);
|
EmitWriteMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32WriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory16);
|
EmitWriteMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32WriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory32);
|
EmitWriteMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32WriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory64);
|
EmitWriteMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory8);
|
EmitExclusiveWriteMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory16);
|
EmitExclusiveWriteMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory32);
|
EmitExclusiveWriteMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory64);
|
EmitExclusiveWriteMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
@ -27,102 +27,102 @@ void EmitIR<IR::Opcode::A64ClearExclusive>(oaknut::CodeGenerator& code, EmitCont
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory8);
|
EmitReadMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory16);
|
EmitReadMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory32);
|
EmitReadMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory(code, ctx, inst, LinkTarget::ReadMemory64);
|
EmitReadMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ReadMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitReadMemory128(code, ctx, inst, LinkTarget::ReadMemory128);
|
EmitReadMemory<128>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory8);
|
EmitExclusiveReadMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory16);
|
EmitExclusiveReadMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory32);
|
EmitExclusiveReadMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory(code, ctx, inst, LinkTarget::ExclusiveReadMemory64);
|
EmitExclusiveReadMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveReadMemory128(code, ctx, inst, LinkTarget::ExclusiveReadMemory128);
|
EmitExclusiveReadMemory<128>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64WriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory8);
|
EmitWriteMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64WriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory16);
|
EmitWriteMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64WriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory32);
|
EmitWriteMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64WriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory64);
|
EmitWriteMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64WriteMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitWriteMemory(code, ctx, inst, LinkTarget::WriteMemory128);
|
EmitWriteMemory<128>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory8);
|
EmitExclusiveWriteMemory<8>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory16);
|
EmitExclusiveWriteMemory<16>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory32);
|
EmitExclusiveWriteMemory<32>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory64);
|
EmitExclusiveWriteMemory<64>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitExclusiveWriteMemory(code, ctx, inst, LinkTarget::ExclusiveWriteMemory128);
|
EmitExclusiveWriteMemory<128>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
@ -20,65 +20,118 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
bool IsOrdered(IR::AccType acctype) {
|
bool IsOrdered(IR::AccType acctype) {
|
||||||
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
|
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
return LinkTarget::ReadMemory8;
|
||||||
|
case 16:
|
||||||
|
return LinkTarget::ReadMemory16;
|
||||||
|
case 32:
|
||||||
|
return LinkTarget::ReadMemory32;
|
||||||
|
case 64:
|
||||||
|
return LinkTarget::ReadMemory64;
|
||||||
|
case 128:
|
||||||
|
return LinkTarget::ReadMemory128;
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
return LinkTarget::WriteMemory8;
|
||||||
|
case 16:
|
||||||
|
return LinkTarget::WriteMemory16;
|
||||||
|
case 32:
|
||||||
|
return LinkTarget::WriteMemory32;
|
||||||
|
case 64:
|
||||||
|
return LinkTarget::WriteMemory64;
|
||||||
|
case 128:
|
||||||
|
return LinkTarget::WriteMemory128;
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
return LinkTarget::ExclusiveReadMemory8;
|
||||||
|
case 16:
|
||||||
|
return LinkTarget::ExclusiveReadMemory16;
|
||||||
|
case 32:
|
||||||
|
return LinkTarget::ExclusiveReadMemory32;
|
||||||
|
case 64:
|
||||||
|
return LinkTarget::ExclusiveReadMemory64;
|
||||||
|
case 128:
|
||||||
|
return LinkTarget::ExclusiveReadMemory128;
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
return LinkTarget::ExclusiveWriteMemory8;
|
||||||
|
case 16:
|
||||||
|
return LinkTarget::ExclusiveWriteMemory16;
|
||||||
|
case 32:
|
||||||
|
return LinkTarget::ExclusiveWriteMemory32;
|
||||||
|
case 64:
|
||||||
|
return LinkTarget::ExclusiveWriteMemory64;
|
||||||
|
case 128:
|
||||||
|
return LinkTarget::ExclusiveWriteMemory128;
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t bitsize>
|
||||||
|
void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||||
|
|
||||||
EmitRelocation(code, ctx, fn);
|
EmitRelocation(code, ctx, ReadMemoryLinkTarget(bitsize));
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
if constexpr (bitsize == 128) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
code.MOV(Q8.B16(), Q0.B16());
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
} else {
|
||||||
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
EmitRelocation(code, ctx, fn);
|
|
||||||
if (ordered) {
|
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
|
||||||
}
|
}
|
||||||
code.MOV(Q8.B16(), Q0.B16());
|
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
template<size_t bitsize>
|
||||||
|
void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||||
|
|
||||||
code.MOV(Wscratch0, 1);
|
code.MOV(Wscratch0, 1);
|
||||||
code.STRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
code.STRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
||||||
EmitRelocation(code, ctx, fn);
|
EmitRelocation(code, ctx, ExclusiveReadMemoryLinkTarget(bitsize));
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
if constexpr (bitsize == 128) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
code.MOV(Q8.B16(), Q0.B16());
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
} else {
|
||||||
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
code.MOV(Wscratch0, 1);
|
|
||||||
code.STRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
|
||||||
EmitRelocation(code, ctx, fn);
|
|
||||||
if (ordered) {
|
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
|
||||||
}
|
}
|
||||||
code.MOV(Q8.B16(), Q0.B16());
|
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
template<size_t bitsize>
|
||||||
|
void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||||
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
||||||
|
@ -86,13 +139,14 @@ void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* in
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
EmitRelocation(code, ctx, fn);
|
EmitRelocation(code, ctx, WriteMemoryLinkTarget(bitsize));
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
template<size_t bitsize>
|
||||||
|
void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||||
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
||||||
|
@ -106,7 +160,7 @@ void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
||||||
code.LDRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
code.LDRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
||||||
code.CBZ(Wscratch0, end);
|
code.CBZ(Wscratch0, end);
|
||||||
code.STRB(WZR, Xstate, ctx.conf.state_exclusive_state_offset);
|
code.STRB(WZR, Xstate, ctx.conf.state_exclusive_state_offset);
|
||||||
EmitRelocation(code, ctx, fn);
|
EmitRelocation(code, ctx, ExclusiveWriteMemoryLinkTarget(bitsize));
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
|
@ -114,4 +168,47 @@ void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
template<size_t bitsize>
|
||||||
|
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
CallbackOnlyEmitReadMemory<bitsize>(code, ctx, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t bitsize>
|
||||||
|
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
CallbackOnlyEmitExclusiveReadMemory<bitsize>(code, ctx, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t bitsize>
|
||||||
|
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
CallbackOnlyEmitWriteMemory<bitsize>(code, ctx, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t bitsize>
|
||||||
|
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
CallbackOnlyEmitExclusiveWriteMemory<bitsize>(code, ctx, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
template void EmitReadMemory<8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitReadMemory<16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitReadMemory<32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitReadMemory<64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitReadMemory<128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveReadMemory<8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveReadMemory<16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveReadMemory<32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveReadMemory<64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveReadMemory<128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitWriteMemory<8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitWriteMemory<16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitWriteMemory<32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitWriteMemory<64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitWriteMemory<128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveWriteMemory<8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveWriteMemory<16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveWriteMemory<32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveWriteMemory<64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
template void EmitExclusiveWriteMemory<128>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
namespace oaknut {
|
namespace oaknut {
|
||||||
struct PointerCodeGeneratorPolicy;
|
struct PointerCodeGeneratorPolicy;
|
||||||
template<typename>
|
template<typename>
|
||||||
|
@ -21,12 +23,13 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
struct EmitContext;
|
struct EmitContext;
|
||||||
enum class LinkTarget;
|
enum class LinkTarget;
|
||||||
|
|
||||||
bool IsOrdered(IR::AccType acctype);
|
template<size_t bitsize>
|
||||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
template<size_t bitsize>
|
||||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
template<size_t bitsize>
|
||||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
template<size_t bitsize>
|
||||||
|
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
Loading…
Reference in a new issue