backend_x64: Remove all use of xmm0

This commit is contained in:
MerryMage 2018-07-31 20:53:33 +01:00
parent 8252efd7b1
commit 476c0f15da
5 changed files with 43 additions and 36 deletions

View file

@ -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, [&]{

View file

@ -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) {

View file

@ -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) {

View file

@ -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

View file

@ -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,