IR: Add IR instructions A64Memory{Read,Write}128
Add the Windows ABI implementation
This commit is contained in:
parent
e1df7ae621
commit
f698848e26
1 changed files with 38 additions and 0 deletions
|
@ -320,6 +320,24 @@ void A64EmitX64::EmitA64ReadMemory64(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitA64ReadMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64ReadMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
static_assert(ABI_SHADOW_SPACE >= 16);
|
||||||
|
ctx.reg_alloc.HostCall(nullptr, {}, {}, args[0]);
|
||||||
|
code->lea(code->ABI_PARAM2, ptr[rsp]);
|
||||||
|
code->sub(rsp, ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code, [&](Xbyak::Reg64 return_value, Xbyak::Reg64 vaddr) {
|
||||||
|
ASSERT(return_value == code->ABI_PARAM2 && vaddr == code->ABI_PARAM3);
|
||||||
|
});
|
||||||
|
|
||||||
|
Xbyak::Xmm result = xmm0;
|
||||||
|
code->movups(result, code->xword[code->ABI_RETURN]);
|
||||||
|
code->add(rsp, ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
|
#else
|
||||||
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code, [&](Xbyak::Reg64 vaddr) {
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code, [&](Xbyak::Reg64 vaddr) {
|
||||||
ASSERT(vaddr == code->ABI_PARAM2);
|
ASSERT(vaddr == code->ABI_PARAM2);
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -336,6 +354,7 @@ void A64EmitX64::EmitA64ReadMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
code->punpcklqdq(result, tmp);
|
code->punpcklqdq(result, tmp);
|
||||||
}
|
}
|
||||||
ctx.reg_alloc.DefineValue(inst, result);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitA64WriteMemory8(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64WriteMemory8(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
@ -371,6 +390,24 @@ void A64EmitX64::EmitA64WriteMemory64(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitA64WriteMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64WriteMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
static_assert(ABI_SHADOW_SPACE >= 16);
|
||||||
|
ctx.reg_alloc.Use(args[0], ABI_PARAM2);
|
||||||
|
Xbyak::Xmm xmm_value = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
code->lea(code->ABI_PARAM3, ptr[rsp]);
|
||||||
|
code->sub(rsp, ABI_SHADOW_SPACE);
|
||||||
|
code->movaps(code->xword[code->ABI_PARAM3], xmm_value);
|
||||||
|
|
||||||
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code, [&](Xbyak::Reg64 return_value, Xbyak::Reg64 vaddr) {
|
||||||
|
ASSERT(return_value == code->ABI_PARAM2 && vaddr == code->ABI_PARAM3);
|
||||||
|
});
|
||||||
|
|
||||||
|
code->add(rsp, ABI_SHADOW_SPACE);
|
||||||
|
#else
|
||||||
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code, [&](Xbyak::Reg64 vaddr, Xbyak::Reg64 value0, Xbyak::Reg64 value1) {
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code, [&](Xbyak::Reg64 vaddr, Xbyak::Reg64 value0, Xbyak::Reg64 value1) {
|
||||||
ASSERT(vaddr == code->ABI_PARAM2 && value0 == code->ABI_PARAM3 && value1 == code->ABI_PARAM4);
|
ASSERT(vaddr == code->ABI_PARAM2 && value0 == code->ABI_PARAM3 && value1 == code->ABI_PARAM4);
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -390,6 +427,7 @@ void A64EmitX64::EmitA64WriteMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) {
|
void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) {
|
||||||
|
|
Loading…
Reference in a new issue