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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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
|
||||
|
|
|
@ -27,102 +27,102 @@ void EmitIR<IR::Opcode::A64ClearExclusive>(oaknut::CodeGenerator& code, EmitCont
|
|||
|
||||
template<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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
|
||||
|
|
|
@ -20,65 +20,118 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
|
||||
using namespace oaknut::util;
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsOrdered(IR::AccType acctype) {
|
||||
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) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
EmitRelocation(code, ctx, fn);
|
||||
if (ordered) {
|
||||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
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;
|
||||
}
|
||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||
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);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
EmitRelocation(code, ctx, fn);
|
||||
EmitRelocation(code, ctx, ReadMemoryLinkTarget(bitsize));
|
||||
if (ordered) {
|
||||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
}
|
||||
|
||||
if constexpr (bitsize == 128) {
|
||||
code.MOV(Q8.B16(), Q0.B16());
|
||||
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||
} else {
|
||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
code.MOV(Wscratch0, 1);
|
||||
code.STRB(Wscratch0, Xstate, ctx.conf.state_exclusive_state_offset);
|
||||
EmitRelocation(code, ctx, fn);
|
||||
EmitRelocation(code, ctx, ExclusiveReadMemoryLinkTarget(bitsize));
|
||||
if (ordered) {
|
||||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
}
|
||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||
}
|
||||
|
||||
void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
|
||||
|
||||
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);
|
||||
}
|
||||
if constexpr (bitsize == 128) {
|
||||
code.MOV(Q8.B16(), Q0.B16());
|
||||
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||
} else {
|
||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||
const bool ordered = IsOrdered(args[3].GetImmediateAccType());
|
||||
|
@ -86,13 +139,14 @@ void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* in
|
|||
if (ordered) {
|
||||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
}
|
||||
EmitRelocation(code, ctx, fn);
|
||||
EmitRelocation(code, ctx, WriteMemoryLinkTarget(bitsize));
|
||||
if (ordered) {
|
||||
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);
|
||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||
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.CBZ(Wscratch0, end);
|
||||
code.STRB(WZR, Xstate, ctx.conf.state_exclusive_state_offset);
|
||||
EmitRelocation(code, ctx, fn);
|
||||
EmitRelocation(code, ctx, ExclusiveWriteMemoryLinkTarget(bitsize));
|
||||
if (ordered) {
|
||||
code.DMB(oaknut::BarrierOp::ISH);
|
||||
}
|
||||
|
@ -114,4 +168,47 @@ void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
|||
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
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include <mcl/stdint.hpp>
|
||||
|
||||
namespace oaknut {
|
||||
struct PointerCodeGeneratorPolicy;
|
||||
template<typename>
|
||||
|
@ -21,12 +23,13 @@ namespace Dynarmic::Backend::Arm64 {
|
|||
struct EmitContext;
|
||||
enum class LinkTarget;
|
||||
|
||||
bool IsOrdered(IR::AccType acctype);
|
||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn);
|
||||
template<size_t bitsize>
|
||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
template<size_t bitsize>
|
||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||
|
||||
} // namespace Dynarmic::Backend::Arm64
|
||||
|
|
Loading…
Reference in a new issue