Shader: Save caller-saved registers in JIT before a CALL

master
aroulin 2015-08-19 01:49:45 +07:00
parent 7d3a6016d6
commit 2f9eb98f03
2 changed files with 33 additions and 0 deletions

@ -280,6 +280,22 @@ void JitCompiler::Compile_UniformCondition(Instruction instr) {
CMP(sizeof(bool) * 8, MDisp(UNIFORMS, offset), Imm8(0)); CMP(sizeof(bool) * 8, MDisp(UNIFORMS, offset), Imm8(0));
} }
void JitCompiler::Compile_PushCallerSavedXMM() {
#ifndef _WIN32
SUB(64, R(RSP), Imm8(2 * 16));
MOVUPS(MDisp(RSP, 16), ONE);
MOVUPS(MDisp(RSP, 0), NEGBIT);
#endif
}
void JitCompiler::Compile_PopCallerSavedXMM() {
#ifndef _WIN32
MOVUPS(NEGBIT, MDisp(RSP, 0));
MOVUPS(ONE, MDisp(RSP, 16));
ADD(64, R(RSP), Imm8(2 * 16));
#endif
}
void JitCompiler::Compile_ADD(Instruction instr) { void JitCompiler::Compile_ADD(Instruction instr) {
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1); Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2); Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
@ -334,7 +350,14 @@ void JitCompiler::Compile_DP4(Instruction instr) {
void JitCompiler::Compile_EX2(Instruction instr) { void JitCompiler::Compile_EX2(Instruction instr) {
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1); Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
MOVSS(XMM0, R(SRC1)); MOVSS(XMM0, R(SRC1));
// The following will actually break the stack alignment
ABI_PushAllCallerSavedRegsAndAdjustStack();
Compile_PushCallerSavedXMM();
ABI_CallFunction(reinterpret_cast<const void*>(exp2f)); ABI_CallFunction(reinterpret_cast<const void*>(exp2f));
Compile_PopCallerSavedXMM();
ABI_PopAllCallerSavedRegsAndAdjustStack();
SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0)); SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0));
MOVAPS(SRC1, R(XMM0)); MOVAPS(SRC1, R(XMM0));
Compile_DestEnable(instr, SRC1); Compile_DestEnable(instr, SRC1);
@ -343,7 +366,14 @@ void JitCompiler::Compile_EX2(Instruction instr) {
void JitCompiler::Compile_LG2(Instruction instr) { void JitCompiler::Compile_LG2(Instruction instr) {
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1); Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
MOVSS(XMM0, R(SRC1)); MOVSS(XMM0, R(SRC1));
// The following will actually break the stack alignment
ABI_PushAllCallerSavedRegsAndAdjustStack();
Compile_PushCallerSavedXMM();
ABI_CallFunction(reinterpret_cast<const void*>(log2f)); ABI_CallFunction(reinterpret_cast<const void*>(log2f));
Compile_PopCallerSavedXMM();
ABI_PopAllCallerSavedRegsAndAdjustStack();
SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0)); SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0));
MOVAPS(SRC1, R(XMM0)); MOVAPS(SRC1, R(XMM0));
Compile_DestEnable(instr, SRC1); Compile_DestEnable(instr, SRC1);

@ -69,6 +69,9 @@ private:
void Compile_EvaluateCondition(Instruction instr); void Compile_EvaluateCondition(Instruction instr);
void Compile_UniformCondition(Instruction instr); void Compile_UniformCondition(Instruction instr);
void Compile_PushCallerSavedXMM();
void Compile_PopCallerSavedXMM();
/// Pointer to the variable that stores the current Pica code offset. Used to handle nested code blocks. /// Pointer to the variable that stores the current Pica code offset. Used to handle nested code blocks.
unsigned* offset_ptr = nullptr; unsigned* offset_ptr = nullptr;