backend_x64: Remove all use of xmm0
This commit is contained in:
parent
8252efd7b1
commit
476c0f15da
5 changed files with 43 additions and 36 deletions
|
@ -145,18 +145,18 @@ void A64EmitX64::GenMemory128Accessors() {
|
||||||
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||||
code.lea(return_value_ptr, ptr[rsp + ABI_SHADOW_SPACE]);
|
code.lea(return_value_ptr, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||||
});
|
});
|
||||||
code.movups(xmm0, xword[code.ABI_RETURN]);
|
code.movups(xmm1, xword[code.ABI_RETURN]);
|
||||||
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||||
#else
|
#else
|
||||||
code.sub(rsp, 8);
|
code.sub(rsp, 8);
|
||||||
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code);
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code);
|
||||||
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE41)) {
|
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE41)) {
|
||||||
code.movq(xmm0, code.ABI_RETURN);
|
code.movq(xmm1, code.ABI_RETURN);
|
||||||
code.pinsrq(xmm0, code.ABI_RETURN2, 1);
|
code.pinsrq(xmm1, code.ABI_RETURN2, 1);
|
||||||
} else {
|
} else {
|
||||||
code.movq(xmm0, code.ABI_RETURN);
|
code.movq(xmm1, code.ABI_RETURN);
|
||||||
code.movq(xmm1, code.ABI_RETURN2);
|
code.movq(xmm2, code.ABI_RETURN2);
|
||||||
code.punpcklqdq(xmm0, xmm1);
|
code.punpcklqdq(xmm1, xmm2);
|
||||||
}
|
}
|
||||||
code.add(rsp, 8);
|
code.add(rsp, 8);
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,18 +167,18 @@ void A64EmitX64::GenMemory128Accessors() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||||
code.movaps(xword[code.ABI_PARAM3], xmm0);
|
code.movaps(xword[code.ABI_PARAM3], xmm1);
|
||||||
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code);
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code);
|
||||||
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||||
#else
|
#else
|
||||||
code.sub(rsp, 8);
|
code.sub(rsp, 8);
|
||||||
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE41)) {
|
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE41)) {
|
||||||
code.movq(code.ABI_PARAM3, xmm0);
|
code.movq(code.ABI_PARAM3, xmm1);
|
||||||
code.pextrq(code.ABI_PARAM4, xmm0, 1);
|
code.pextrq(code.ABI_PARAM4, xmm1, 1);
|
||||||
} else {
|
} else {
|
||||||
code.movq(code.ABI_PARAM3, xmm0);
|
code.movq(code.ABI_PARAM3, xmm1);
|
||||||
code.punpckhqdq(xmm0, xmm0);
|
code.punpckhqdq(xmm1, xmm1);
|
||||||
code.movq(code.ABI_PARAM4, xmm0);
|
code.movq(code.ABI_PARAM4, xmm1);
|
||||||
}
|
}
|
||||||
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code);
|
DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code);
|
||||||
code.add(rsp, 8);
|
code.add(rsp, 8);
|
||||||
|
@ -214,8 +214,8 @@ void A64EmitX64::GenFastmemFallbacks() {
|
||||||
code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx});
|
code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx});
|
||||||
}
|
}
|
||||||
code.call(memory_read_128);
|
code.call(memory_read_128);
|
||||||
if (value_idx != 0) {
|
if (value_idx != 1) {
|
||||||
code.movaps(Xbyak::Xmm{value_idx}, xmm0);
|
code.movaps(Xbyak::Xmm{value_idx}, xmm1);
|
||||||
}
|
}
|
||||||
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(value_idx));
|
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(value_idx));
|
||||||
code.ret();
|
code.ret();
|
||||||
|
@ -226,8 +226,8 @@ void A64EmitX64::GenFastmemFallbacks() {
|
||||||
if (vaddr_idx != code.ABI_PARAM2.getIdx()) {
|
if (vaddr_idx != code.ABI_PARAM2.getIdx()) {
|
||||||
code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx});
|
code.mov(code.ABI_PARAM2, Xbyak::Reg64{vaddr_idx});
|
||||||
}
|
}
|
||||||
if (value_idx != 0) {
|
if (value_idx != 1) {
|
||||||
code.movaps(xmm0, Xbyak::Xmm{value_idx});
|
code.movaps(xmm1, Xbyak::Xmm{value_idx});
|
||||||
}
|
}
|
||||||
code.call(memory_write_128);
|
code.call(memory_write_128);
|
||||||
ABI_PopCallerSaveRegistersAndAdjustStack(code);
|
ABI_PopCallerSaveRegistersAndAdjustStack(code);
|
||||||
|
@ -780,7 +780,7 @@ void A64EmitX64::EmitA64ReadMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.HostCall(nullptr, {}, args[0]);
|
ctx.reg_alloc.HostCall(nullptr, {}, args[0]);
|
||||||
code.CallFunction(memory_read_128);
|
code.CallFunction(memory_read_128);
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, xmm1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void A64EmitX64::EmitA64WriteMemory8(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64WriteMemory8(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
@ -849,7 +849,7 @@ void A64EmitX64::EmitA64WriteMemory128(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.Use(args[0], ABI_PARAM2);
|
ctx.reg_alloc.Use(args[0], ABI_PARAM2);
|
||||||
ctx.reg_alloc.Use(args[1], HostLoc::XMM0);
|
ctx.reg_alloc.Use(args[1], HostLoc::XMM1);
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
code.CallFunction(memory_write_128);
|
code.CallFunction(memory_write_128);
|
||||||
|
@ -863,7 +863,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t
|
||||||
ctx.reg_alloc.HostCall(inst, {}, args[0], args[1]);
|
ctx.reg_alloc.HostCall(inst, {}, args[0], args[1]);
|
||||||
} else {
|
} else {
|
||||||
ctx.reg_alloc.Use(args[0], ABI_PARAM2);
|
ctx.reg_alloc.Use(args[0], ABI_PARAM2);
|
||||||
ctx.reg_alloc.Use(args[1], HostLoc::XMM0);
|
ctx.reg_alloc.Use(args[1], HostLoc::XMM1);
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(inst);
|
ctx.reg_alloc.HostCall(inst);
|
||||||
}
|
}
|
||||||
|
@ -914,7 +914,7 @@ void A64EmitX64::EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t
|
||||||
case 128:
|
case 128:
|
||||||
code.sub(rsp, 16 + ABI_SHADOW_SPACE);
|
code.sub(rsp, 16 + ABI_SHADOW_SPACE);
|
||||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||||
code.movaps(xword[code.ABI_PARAM3], xmm0);
|
code.movaps(xword[code.ABI_PARAM3], xmm1);
|
||||||
code.CallFunction(static_cast<u32(*)(A64::UserConfig&, u64, A64::Vector&)>(
|
code.CallFunction(static_cast<u32(*)(A64::UserConfig&, u64, A64::Vector&)>(
|
||||||
[](A64::UserConfig& conf, u64 vaddr, A64::Vector& value) -> u32 {
|
[](A64::UserConfig& conf, u64 vaddr, A64::Vector& value) -> u32 {
|
||||||
return conf.global_monitor->DoExclusiveOperation(conf.processor_id, vaddr, 16, [&]{
|
return conf.global_monitor->DoExclusiveOperation(conf.processor_id, vaddr, 16, [&]{
|
||||||
|
|
|
@ -23,6 +23,7 @@ static void EmitAESFunction(std::array<Argument, 3> args, EmitContext& ctx, Bloc
|
||||||
IR::Inst* inst, AESFn fn) {
|
IR::Inst* inst, AESFn fn) {
|
||||||
constexpr u32 stack_space = static_cast<u32>(sizeof(AES::State)) * 2;
|
constexpr u32 stack_space = static_cast<u32>(sizeof(AES::State)) * 2;
|
||||||
const Xbyak::Xmm input = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm input = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
|
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
@ -34,12 +35,12 @@ static void EmitAESFunction(std::array<Argument, 3> args, EmitContext& ctx, Bloc
|
||||||
|
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
|
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE]);
|
||||||
|
|
||||||
// Free memory
|
// Free memory
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitAESDecryptSingleRound(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitAESDecryptSingleRound(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
|
@ -55,6 +55,7 @@ static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
||||||
constexpr u32 stack_space = 2 * 16;
|
constexpr u32 stack_space = 2 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
|
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
@ -64,11 +65,11 @@ static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
||||||
|
|
||||||
code.movaps(xword[code.ABI_PARAM2], arg1);
|
code.movaps(xword[code.ABI_PARAM2], arg1);
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||||
|
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lambda>
|
template <typename Lambda>
|
||||||
|
@ -77,6 +78,7 @@ static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
|
||||||
constexpr u32 stack_space = 2 * 16;
|
constexpr u32 stack_space = 2 * 16;
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
|
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
@ -86,13 +88,13 @@ static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
|
||||||
|
|
||||||
code.movaps(xword[code.ABI_PARAM2], arg1);
|
code.movaps(xword[code.ABI_PARAM2], arg1);
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||||
|
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
code.or_(code.byte[code.r15 + code.GetJitStateInfo().offsetof_fpsr_qc], code.ABI_RETURN.cvt8());
|
code.or_(code.byte[code.r15 + code.GetJitStateInfo().offsetof_fpsr_qc], code.ABI_RETURN.cvt8());
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lambda>
|
template <typename Lambda>
|
||||||
|
@ -102,6 +104,7 @@ static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
|
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
@ -113,11 +116,11 @@ static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
|
||||||
code.movaps(xword[code.ABI_PARAM2], arg1);
|
code.movaps(xword[code.ABI_PARAM2], arg1);
|
||||||
code.movaps(xword[code.ABI_PARAM3], arg2);
|
code.movaps(xword[code.ABI_PARAM3], arg2);
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||||
|
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorGetElement8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
|
@ -335,6 +335,7 @@ void EmitTwoOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lamb
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
|
||||||
|
@ -347,11 +348,11 @@ void EmitTwoOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lamb
|
||||||
|
|
||||||
code.movaps(xword[code.ABI_PARAM2], arg1);
|
code.movaps(xword[code.ABI_PARAM2], arg1);
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||||
|
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
|
@ -361,6 +362,7 @@ void EmitThreeOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, La
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
|
||||||
|
@ -388,14 +390,14 @@ void EmitThreeOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, La
|
||||||
code.CallFunction(fn);
|
code.CallFunction(fn);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||||
#else
|
#else
|
||||||
code.movaps(xmm0, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
code.movaps(result, xword[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
code.add(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
|
@ -443,12 +445,13 @@ void EmitFourOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lam
|
||||||
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
const Xbyak::Xmm arg2 = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
const Xbyak::Xmm arg3 = ctx.reg_alloc.UseXmm(args[2]);
|
const Xbyak::Xmm arg3 = ctx.reg_alloc.UseXmm(args[2]);
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
ctx.reg_alloc.EndOfAllocScope();
|
ctx.reg_alloc.EndOfAllocScope();
|
||||||
ctx.reg_alloc.HostCall(nullptr);
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
|
||||||
EmitFourOpFallbackWithoutRegAlloc(code, ctx, xmm0, arg1, arg2, arg3, lambda);
|
EmitFourOpFallbackWithoutRegAlloc(code, ctx, result, arg1, arg2, arg3, lambda);
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, xmm0);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
|
@ -90,8 +90,8 @@ const HostLocList any_gpr = {
|
||||||
HostLoc::R14,
|
HostLoc::R14,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// XMM0 is reserved for use by instructions that implicitly use it as an argument
|
||||||
const HostLocList any_xmm = {
|
const HostLocList any_xmm = {
|
||||||
HostLoc::XMM0,
|
|
||||||
HostLoc::XMM1,
|
HostLoc::XMM1,
|
||||||
HostLoc::XMM2,
|
HostLoc::XMM2,
|
||||||
HostLoc::XMM3,
|
HostLoc::XMM3,
|
||||||
|
|
Loading…
Reference in a new issue