|
|
|
@ -20,73 +20,73 @@ namespace Shader {
|
|
|
|
|
|
|
|
|
|
using namespace Gen;
|
|
|
|
|
|
|
|
|
|
typedef void (JitCompiler::*JitFunction)(Instruction instr);
|
|
|
|
|
typedef void (JitShader::*JitFunction)(Instruction instr);
|
|
|
|
|
|
|
|
|
|
const JitFunction instr_table[64] = {
|
|
|
|
|
&JitCompiler::Compile_ADD, // add
|
|
|
|
|
&JitCompiler::Compile_DP3, // dp3
|
|
|
|
|
&JitCompiler::Compile_DP4, // dp4
|
|
|
|
|
&JitCompiler::Compile_DPH, // dph
|
|
|
|
|
&JitShader::Compile_ADD, // add
|
|
|
|
|
&JitShader::Compile_DP3, // dp3
|
|
|
|
|
&JitShader::Compile_DP4, // dp4
|
|
|
|
|
&JitShader::Compile_DPH, // dph
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_EX2, // ex2
|
|
|
|
|
&JitCompiler::Compile_LG2, // lg2
|
|
|
|
|
&JitShader::Compile_EX2, // ex2
|
|
|
|
|
&JitShader::Compile_LG2, // lg2
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_MUL, // mul
|
|
|
|
|
&JitCompiler::Compile_SGE, // sge
|
|
|
|
|
&JitCompiler::Compile_SLT, // slt
|
|
|
|
|
&JitCompiler::Compile_FLR, // flr
|
|
|
|
|
&JitCompiler::Compile_MAX, // max
|
|
|
|
|
&JitCompiler::Compile_MIN, // min
|
|
|
|
|
&JitCompiler::Compile_RCP, // rcp
|
|
|
|
|
&JitCompiler::Compile_RSQ, // rsq
|
|
|
|
|
&JitShader::Compile_MUL, // mul
|
|
|
|
|
&JitShader::Compile_SGE, // sge
|
|
|
|
|
&JitShader::Compile_SLT, // slt
|
|
|
|
|
&JitShader::Compile_FLR, // flr
|
|
|
|
|
&JitShader::Compile_MAX, // max
|
|
|
|
|
&JitShader::Compile_MIN, // min
|
|
|
|
|
&JitShader::Compile_RCP, // rcp
|
|
|
|
|
&JitShader::Compile_RSQ, // rsq
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_MOVA, // mova
|
|
|
|
|
&JitCompiler::Compile_MOV, // mov
|
|
|
|
|
&JitShader::Compile_MOVA, // mova
|
|
|
|
|
&JitShader::Compile_MOV, // mov
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_DPH, // dphi
|
|
|
|
|
&JitShader::Compile_DPH, // dphi
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_SGE, // sgei
|
|
|
|
|
&JitCompiler::Compile_SLT, // slti
|
|
|
|
|
&JitShader::Compile_SGE, // sgei
|
|
|
|
|
&JitShader::Compile_SLT, // slti
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
nullptr, // unknown
|
|
|
|
|
&JitCompiler::Compile_NOP, // nop
|
|
|
|
|
&JitCompiler::Compile_END, // end
|
|
|
|
|
&JitShader::Compile_NOP, // nop
|
|
|
|
|
&JitShader::Compile_END, // end
|
|
|
|
|
nullptr, // break
|
|
|
|
|
&JitCompiler::Compile_CALL, // call
|
|
|
|
|
&JitCompiler::Compile_CALLC, // callc
|
|
|
|
|
&JitCompiler::Compile_CALLU, // callu
|
|
|
|
|
&JitCompiler::Compile_IF, // ifu
|
|
|
|
|
&JitCompiler::Compile_IF, // ifc
|
|
|
|
|
&JitCompiler::Compile_LOOP, // loop
|
|
|
|
|
&JitShader::Compile_CALL, // call
|
|
|
|
|
&JitShader::Compile_CALLC, // callc
|
|
|
|
|
&JitShader::Compile_CALLU, // callu
|
|
|
|
|
&JitShader::Compile_IF, // ifu
|
|
|
|
|
&JitShader::Compile_IF, // ifc
|
|
|
|
|
&JitShader::Compile_LOOP, // loop
|
|
|
|
|
nullptr, // emit
|
|
|
|
|
nullptr, // sete
|
|
|
|
|
&JitCompiler::Compile_JMP, // jmpc
|
|
|
|
|
&JitCompiler::Compile_JMP, // jmpu
|
|
|
|
|
&JitCompiler::Compile_CMP, // cmp
|
|
|
|
|
&JitCompiler::Compile_CMP, // cmp
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // madi
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitCompiler::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_JMP, // jmpc
|
|
|
|
|
&JitShader::Compile_JMP, // jmpu
|
|
|
|
|
&JitShader::Compile_CMP, // cmp
|
|
|
|
|
&JitShader::Compile_CMP, // cmp
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // madi
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
&JitShader::Compile_MAD, // mad
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// The following is used to alias some commonly used registers. Generally, RAX-RDX and XMM0-XMM3 can
|
|
|
|
@ -151,7 +151,7 @@ static void LogCritical(const char* msg) {
|
|
|
|
|
LOG_CRITICAL(HW_GPU, msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::RuntimeAssert(bool condition, const char* msg) {
|
|
|
|
|
void JitShader::RuntimeAssert(bool condition, const char* msg) {
|
|
|
|
|
if (!condition) {
|
|
|
|
|
ABI_CallFunctionP(reinterpret_cast<const void*>(LogCritical), const_cast<char*>(msg));
|
|
|
|
|
}
|
|
|
|
@ -164,7 +164,7 @@ void JitCompiler::RuntimeAssert(bool condition, const char* msg) {
|
|
|
|
|
* @param src_reg SourceRegister object corresponding to the source register to load
|
|
|
|
|
* @param dest Destination XMM register to store the loaded, swizzled source register
|
|
|
|
|
*/
|
|
|
|
|
void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, X64Reg dest) {
|
|
|
|
|
void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, X64Reg dest) {
|
|
|
|
|
X64Reg src_ptr;
|
|
|
|
|
size_t src_offset;
|
|
|
|
|
|
|
|
|
@ -236,7 +236,7 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_DestEnable(Instruction instr,X64Reg src) {
|
|
|
|
|
void JitShader::Compile_DestEnable(Instruction instr,X64Reg src) {
|
|
|
|
|
DestRegister dest;
|
|
|
|
|
unsigned operand_desc_id;
|
|
|
|
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD ||
|
|
|
|
@ -283,7 +283,7 @@ void JitCompiler::Compile_DestEnable(Instruction instr,X64Reg src) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_SanitizedMul(Gen::X64Reg src1, Gen::X64Reg src2, Gen::X64Reg scratch) {
|
|
|
|
|
void JitShader::Compile_SanitizedMul(Gen::X64Reg src1, Gen::X64Reg src2, Gen::X64Reg scratch) {
|
|
|
|
|
MOVAPS(scratch, R(src1));
|
|
|
|
|
CMPPS(scratch, R(src2), CMP_ORD);
|
|
|
|
|
|
|
|
|
@ -296,7 +296,7 @@ void JitCompiler::Compile_SanitizedMul(Gen::X64Reg src1, Gen::X64Reg src2, Gen::
|
|
|
|
|
ANDPS(src1, R(scratch));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_EvaluateCondition(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_EvaluateCondition(Instruction instr) {
|
|
|
|
|
// Note: NXOR is used below to check for equality
|
|
|
|
|
switch (instr.flow_control.op) {
|
|
|
|
|
case Instruction::FlowControlType::Or:
|
|
|
|
@ -327,23 +327,23 @@ void JitCompiler::Compile_EvaluateCondition(Instruction instr) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_UniformCondition(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_UniformCondition(Instruction instr) {
|
|
|
|
|
int offset = offsetof(decltype(g_state.vs.uniforms), b) + (instr.flow_control.bool_uniform_id * sizeof(bool));
|
|
|
|
|
CMP(sizeof(bool) * 8, MDisp(UNIFORMS, offset), Imm8(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BitSet32 JitCompiler::PersistentCallerSavedRegs() {
|
|
|
|
|
BitSet32 JitShader::PersistentCallerSavedRegs() {
|
|
|
|
|
return persistent_regs & ABI_ALL_CALLER_SAVED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_ADD(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_ADD(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
ADDPS(SRC1, R(SRC2));
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_DP3(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_DP3(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
|
|
|
|
@ -362,7 +362,7 @@ void JitCompiler::Compile_DP3(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_DP4(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_DP4(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
|
|
|
|
@ -379,7 +379,7 @@ void JitCompiler::Compile_DP4(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_DPH(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_DPH(Instruction instr) {
|
|
|
|
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::DPHI) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
|
|
|
@ -411,7 +411,7 @@ void JitCompiler::Compile_DPH(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_EX2(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_EX2(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
MOVSS(XMM0, R(SRC1));
|
|
|
|
|
|
|
|
|
@ -424,7 +424,7 @@ void JitCompiler::Compile_EX2(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_LG2(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_LG2(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
MOVSS(XMM0, R(SRC1));
|
|
|
|
|
|
|
|
|
@ -437,14 +437,14 @@ void JitCompiler::Compile_LG2(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MUL(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MUL(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
Compile_SanitizedMul(SRC1, SRC2, SCRATCH);
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_SGE(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_SGE(Instruction instr) {
|
|
|
|
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SGEI) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
|
|
|
@ -459,7 +459,7 @@ void JitCompiler::Compile_SGE(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_SLT(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_SLT(Instruction instr) {
|
|
|
|
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SLTI) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
|
|
|
@ -474,7 +474,7 @@ void JitCompiler::Compile_SLT(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_FLR(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_FLR(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
|
|
|
|
|
if (Common::GetCPUCaps().sse4_1) {
|
|
|
|
@ -487,7 +487,7 @@ void JitCompiler::Compile_FLR(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MAX(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MAX(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
// SSE semantics match PICA200 ones: In case of NaN, SRC2 is returned.
|
|
|
|
@ -495,7 +495,7 @@ void JitCompiler::Compile_MAX(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MIN(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MIN(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
|
|
|
|
// SSE semantics match PICA200 ones: In case of NaN, SRC2 is returned.
|
|
|
|
@ -503,7 +503,7 @@ void JitCompiler::Compile_MIN(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MOVA(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MOVA(Instruction instr) {
|
|
|
|
|
SwizzlePattern swiz = { g_state.vs.swizzle_data[instr.common.operand_desc_id] };
|
|
|
|
|
|
|
|
|
|
if (!swiz.DestComponentEnabled(0) && !swiz.DestComponentEnabled(1)) {
|
|
|
|
@ -548,12 +548,12 @@ void JitCompiler::Compile_MOVA(Instruction instr) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MOV(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MOV(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_RCP(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_RCP(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
|
|
|
|
|
// TODO(bunnei): RCPSS is a pretty rough approximation, this might cause problems if Pica
|
|
|
|
@ -564,7 +564,7 @@ void JitCompiler::Compile_RCP(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_RSQ(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_RSQ(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
|
|
|
|
|
|
|
|
|
// TODO(bunnei): RSQRTSS is a pretty rough approximation, this might cause problems if Pica
|
|
|
|
@ -575,15 +575,15 @@ void JitCompiler::Compile_RSQ(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_NOP(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_NOP(Instruction instr) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_END(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_END(Instruction instr) {
|
|
|
|
|
ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8);
|
|
|
|
|
RET();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_CALL(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_CALL(Instruction instr) {
|
|
|
|
|
// Push offset of the return
|
|
|
|
|
PUSH(64, Imm32(instr.flow_control.dest_offset + instr.flow_control.num_instructions));
|
|
|
|
|
|
|
|
|
@ -595,21 +595,21 @@ void JitCompiler::Compile_CALL(Instruction instr) {
|
|
|
|
|
ADD(64, R(RSP), Imm32(8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_CALLC(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_CALLC(Instruction instr) {
|
|
|
|
|
Compile_EvaluateCondition(instr);
|
|
|
|
|
FixupBranch b = J_CC(CC_Z, true);
|
|
|
|
|
Compile_CALL(instr);
|
|
|
|
|
SetJumpTarget(b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_CALLU(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_CALLU(Instruction instr) {
|
|
|
|
|
Compile_UniformCondition(instr);
|
|
|
|
|
FixupBranch b = J_CC(CC_Z, true);
|
|
|
|
|
Compile_CALL(instr);
|
|
|
|
|
SetJumpTarget(b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_CMP(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_CMP(Instruction instr) {
|
|
|
|
|
using Op = Instruction::Common::CompareOpType::Op;
|
|
|
|
|
Op op_x = instr.common.compare_op.x;
|
|
|
|
|
Op op_y = instr.common.compare_op.y;
|
|
|
|
@ -652,7 +652,7 @@ void JitCompiler::Compile_CMP(Instruction instr) {
|
|
|
|
|
SHR(64, R(COND1), Imm8(63));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_MAD(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_MAD(Instruction instr) {
|
|
|
|
|
Compile_SwizzleSrc(instr, 1, instr.mad.src1, SRC1);
|
|
|
|
|
|
|
|
|
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
|
|
|
|
@ -669,7 +669,7 @@ void JitCompiler::Compile_MAD(Instruction instr) {
|
|
|
|
|
Compile_DestEnable(instr, SRC1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_IF(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_IF(Instruction instr) {
|
|
|
|
|
RuntimeAssert(instr.flow_control.dest_offset >= program_counter, "Backwards if-statements not supported");
|
|
|
|
|
|
|
|
|
|
// Evaluate the "IF" condition
|
|
|
|
@ -700,7 +700,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
|
|
|
|
|
SetJumpTarget(b2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_LOOP(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_LOOP(Instruction instr) {
|
|
|
|
|
RuntimeAssert(instr.flow_control.dest_offset >= program_counter, "Backwards loops not supported");
|
|
|
|
|
RuntimeAssert(!looping, "Nested loops not supported");
|
|
|
|
|
|
|
|
|
@ -728,7 +728,7 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
|
|
|
|
|
looping = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_JMP(Instruction instr) {
|
|
|
|
|
void JitShader::Compile_JMP(Instruction instr) {
|
|
|
|
|
if (instr.opcode.Value() == OpCode::Id::JMPC)
|
|
|
|
|
Compile_EvaluateCondition(instr);
|
|
|
|
|
else if (instr.opcode.Value() == OpCode::Id::JMPU)
|
|
|
|
@ -743,13 +743,13 @@ void JitCompiler::Compile_JMP(Instruction instr) {
|
|
|
|
|
fixup_branches.push_back({ b, instr.flow_control.dest_offset });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_Block(unsigned end) {
|
|
|
|
|
void JitShader::Compile_Block(unsigned end) {
|
|
|
|
|
while (program_counter < end) {
|
|
|
|
|
Compile_NextInstr();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_Return() {
|
|
|
|
|
void JitShader::Compile_Return() {
|
|
|
|
|
// Peek return offset on the stack and check if we're at that offset
|
|
|
|
|
MOV(64, R(RAX), MDisp(RSP, 8));
|
|
|
|
|
CMP(32, R(RAX), Imm32(program_counter));
|
|
|
|
@ -760,7 +760,7 @@ void JitCompiler::Compile_Return() {
|
|
|
|
|
SetJumpTarget(b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile_NextInstr() {
|
|
|
|
|
void JitShader::Compile_NextInstr() {
|
|
|
|
|
if (std::binary_search(return_offsets.begin(), return_offsets.end(), program_counter)) {
|
|
|
|
|
Compile_Return();
|
|
|
|
|
}
|
|
|
|
@ -783,7 +783,7 @@ void JitCompiler::Compile_NextInstr() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::FindReturnOffsets() {
|
|
|
|
|
void JitShader::FindReturnOffsets() {
|
|
|
|
|
return_offsets.clear();
|
|
|
|
|
|
|
|
|
|
for (size_t offset = 0; offset < g_state.vs.program_code.size(); ++offset) {
|
|
|
|
@ -802,7 +802,7 @@ void JitCompiler::FindReturnOffsets() {
|
|
|
|
|
std::sort(return_offsets.begin(), return_offsets.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JitCompiler::Compile() {
|
|
|
|
|
void JitShader::Compile() {
|
|
|
|
|
// Reset flow control state
|
|
|
|
|
program = (CompiledShader*)GetCodePtr();
|
|
|
|
|
program_counter = 0;
|
|
|
|
@ -857,7 +857,7 @@ void JitCompiler::Compile() {
|
|
|
|
|
LOG_DEBUG(HW_GPU, "Compiled shader size=%d", size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JitCompiler::JitCompiler() {
|
|
|
|
|
JitShader::JitShader() {
|
|
|
|
|
AllocCodeSpace(MAX_SHADER_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|