arm64/reg_alloc: Remove PrepareForCallReg and PrepareForCallVec
This commit is contained in:
parent
73eecfbaef
commit
4f1f7c8e97
6 changed files with 24 additions and 47 deletions
|
@ -24,19 +24,6 @@ static void EmitCoprocessorException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {
|
static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {
|
||||||
if (inst) {
|
|
||||||
const auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, arg0, arg1);
|
|
||||||
|
|
||||||
if (callback.user_arg) {
|
|
||||||
code.MOV(X0, reinterpret_cast<u64>(*callback.user_arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
code.MOV(Xscratch0, reinterpret_cast<u64>(callback.function));
|
|
||||||
code.BLR(Xscratch0);
|
|
||||||
code.MOV(Xresult, X0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.reg_alloc.PrepareForCall({}, arg0, arg1);
|
ctx.reg_alloc.PrepareForCall({}, arg0, arg1);
|
||||||
|
|
||||||
if (callback.user_arg) {
|
if (callback.user_arg) {
|
||||||
|
@ -45,6 +32,10 @@ static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A3
|
||||||
|
|
||||||
code.MOV(Xscratch0, reinterpret_cast<u64>(callback.function));
|
code.MOV(Xscratch0, reinterpret_cast<u64>(callback.function));
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
|
|
||||||
|
if (inst) {
|
||||||
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -25,19 +25,19 @@ static bool IsOrdered(IR::AccType acctype) {
|
||||||
|
|
||||||
static void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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, fn);
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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);
|
||||||
|
@ -46,7 +46,7 @@ static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ct
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
|
@ -65,7 +65,7 @@ static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I
|
||||||
|
|
||||||
static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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());
|
||||||
|
|
||||||
oaknut::Label end;
|
oaknut::Label end;
|
||||||
|
@ -81,7 +81,7 @@ static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.l(end);
|
code.l(end);
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -423,7 +423,7 @@ void EmitIR<IR::Opcode::A64GetCNTFRQ>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetCNTPCT>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A64GetCNTPCT>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst);
|
ctx.reg_alloc.PrepareForCall();
|
||||||
if (!ctx.conf.wall_clock_cntpct && ctx.conf.enable_cycle_counting) {
|
if (!ctx.conf.wall_clock_cntpct && ctx.conf.enable_cycle_counting) {
|
||||||
code.LDR(X1, SP, offsetof(StackLayout, cycles_to_run));
|
code.LDR(X1, SP, offsetof(StackLayout, cycles_to_run));
|
||||||
code.SUB(X1, X1, Xticks);
|
code.SUB(X1, X1, Xticks);
|
||||||
|
@ -433,7 +433,7 @@ void EmitIR<IR::Opcode::A64GetCNTPCT>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
code.MOV(Xticks, X0);
|
code.MOV(Xticks, X0);
|
||||||
}
|
}
|
||||||
EmitRelocation(code, ctx, LinkTarget::GetCNTPCT);
|
EmitRelocation(code, ctx, LinkTarget::GetCNTPCT);
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -25,31 +25,32 @@ static bool IsOrdered(IR::AccType acctype) {
|
||||||
|
|
||||||
static void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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, fn);
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qresult = ctx.reg_alloc.PrepareForCallVec(inst, {}, 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, fn);
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Qresult.B16(), Q0.B16());
|
code.MOV(Q8.B16(), Q0.B16());
|
||||||
|
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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);
|
||||||
|
@ -58,12 +59,12 @@ static void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ct
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qresult = ctx.reg_alloc.PrepareForCallVec(inst, {}, 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);
|
||||||
|
@ -72,7 +73,8 @@ static void EmitExclusiveReadMemory128(oaknut::CodeGenerator& code, EmitContext&
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.MOV(Qresult.B16(), Q0.B16());
|
code.MOV(Q8.B16(), Q0.B16());
|
||||||
|
ctx.reg_alloc.DefineAsRegister(inst, Q8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
|
@ -91,7 +93,7 @@ static void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I
|
||||||
|
|
||||||
static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, LinkTarget fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, 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());
|
||||||
|
|
||||||
oaknut::Label end;
|
oaknut::Label end;
|
||||||
|
@ -107,7 +109,7 @@ static void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
code.DMB(oaknut::BarrierOp::ISH);
|
code.DMB(oaknut::BarrierOp::ISH);
|
||||||
}
|
}
|
||||||
code.l(end);
|
code.l(end);
|
||||||
code.MOV(Xresult, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -182,20 +182,6 @@ void RegAlloc::PrepareForCall(std::optional<Argument::copyable_reference> arg0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oaknut::XReg RegAlloc::PrepareForCallReg(IR::Inst* result, std::optional<Argument::copyable_reference> arg0, std::optional<Argument::copyable_reference> arg1, std::optional<Argument::copyable_reference> arg2, std::optional<Argument::copyable_reference> arg3) {
|
|
||||||
PrepareForCall(arg0, arg1, arg2, arg3);
|
|
||||||
ASSERT(result && result->GetType() != IR::Type::U128);
|
|
||||||
DefineAsRegister(result, X0);
|
|
||||||
return X0;
|
|
||||||
}
|
|
||||||
|
|
||||||
oaknut::QReg RegAlloc::PrepareForCallVec(IR::Inst* result, std::optional<Argument::copyable_reference> arg0, std::optional<Argument::copyable_reference> arg1, std::optional<Argument::copyable_reference> arg2, std::optional<Argument::copyable_reference> arg3) {
|
|
||||||
PrepareForCall(arg0, arg1, arg2, arg3);
|
|
||||||
ASSERT(result && result->GetType() == IR::Type::U128);
|
|
||||||
DefineAsRegister(result, Q8);
|
|
||||||
return Q8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) {
|
||||||
ASSERT(!ValueLocation(inst));
|
ASSERT(!ValueLocation(inst));
|
||||||
|
|
||||||
|
|
|
@ -272,8 +272,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareForCall(std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}, std::optional<Argument::copyable_reference> arg2 = {}, std::optional<Argument::copyable_reference> arg3 = {});
|
void PrepareForCall(std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}, std::optional<Argument::copyable_reference> arg2 = {}, std::optional<Argument::copyable_reference> arg3 = {});
|
||||||
oaknut::XReg PrepareForCallReg(IR::Inst* result, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}, std::optional<Argument::copyable_reference> arg2 = {}, std::optional<Argument::copyable_reference> arg3 = {});
|
|
||||||
oaknut::QReg PrepareForCallVec(IR::Inst* result, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}, std::optional<Argument::copyable_reference> arg2 = {}, std::optional<Argument::copyable_reference> arg3 = {});
|
|
||||||
|
|
||||||
void DefineAsExisting(IR::Inst* inst, Argument& arg);
|
void DefineAsExisting(IR::Inst* inst, Argument& arg);
|
||||||
void DefineAsRegister(IR::Inst* inst, oaknut::Reg reg);
|
void DefineAsRegister(IR::Inst* inst, oaknut::Reg reg);
|
||||||
|
|
Loading…
Reference in a new issue