forked from ShuriZma/suyu
shader_jit_x64.cpp: Rename JitCompiler to JitShader.
This commit is contained in:
parent
847fb951e2
commit
3f623b2561
|
@ -28,8 +28,8 @@ namespace Pica {
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
static std::unordered_map<u64, std::unique_ptr<JitCompiler>> shader_map;
|
static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map;
|
||||||
static const JitCompiler* jit_shader;
|
static const JitShader* jit_shader;
|
||||||
#endif // ARCHITECTURE_x86_64
|
#endif // ARCHITECTURE_x86_64
|
||||||
|
|
||||||
void Setup() {
|
void Setup() {
|
||||||
|
@ -42,7 +42,7 @@ void Setup() {
|
||||||
if (iter != shader_map.end()) {
|
if (iter != shader_map.end()) {
|
||||||
jit_shader = iter->second.get();
|
jit_shader = iter->second.get();
|
||||||
} else {
|
} else {
|
||||||
auto shader = std::make_unique<JitCompiler>();
|
auto shader = std::make_unique<JitShader>();
|
||||||
shader->Compile();
|
shader->Compile();
|
||||||
jit_shader = shader.get();
|
jit_shader = shader.get();
|
||||||
shader_map[cache_key] = std::move(shader);
|
shader_map[cache_key] = std::move(shader);
|
||||||
|
|
|
@ -20,73 +20,73 @@ namespace Shader {
|
||||||
|
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
typedef void (JitCompiler::*JitFunction)(Instruction instr);
|
typedef void (JitShader::*JitFunction)(Instruction instr);
|
||||||
|
|
||||||
const JitFunction instr_table[64] = {
|
const JitFunction instr_table[64] = {
|
||||||
&JitCompiler::Compile_ADD, // add
|
&JitShader::Compile_ADD, // add
|
||||||
&JitCompiler::Compile_DP3, // dp3
|
&JitShader::Compile_DP3, // dp3
|
||||||
&JitCompiler::Compile_DP4, // dp4
|
&JitShader::Compile_DP4, // dp4
|
||||||
&JitCompiler::Compile_DPH, // dph
|
&JitShader::Compile_DPH, // dph
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_EX2, // ex2
|
&JitShader::Compile_EX2, // ex2
|
||||||
&JitCompiler::Compile_LG2, // lg2
|
&JitShader::Compile_LG2, // lg2
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_MUL, // mul
|
&JitShader::Compile_MUL, // mul
|
||||||
&JitCompiler::Compile_SGE, // sge
|
&JitShader::Compile_SGE, // sge
|
||||||
&JitCompiler::Compile_SLT, // slt
|
&JitShader::Compile_SLT, // slt
|
||||||
&JitCompiler::Compile_FLR, // flr
|
&JitShader::Compile_FLR, // flr
|
||||||
&JitCompiler::Compile_MAX, // max
|
&JitShader::Compile_MAX, // max
|
||||||
&JitCompiler::Compile_MIN, // min
|
&JitShader::Compile_MIN, // min
|
||||||
&JitCompiler::Compile_RCP, // rcp
|
&JitShader::Compile_RCP, // rcp
|
||||||
&JitCompiler::Compile_RSQ, // rsq
|
&JitShader::Compile_RSQ, // rsq
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_MOVA, // mova
|
&JitShader::Compile_MOVA, // mova
|
||||||
&JitCompiler::Compile_MOV, // mov
|
&JitShader::Compile_MOV, // mov
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_DPH, // dphi
|
&JitShader::Compile_DPH, // dphi
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_SGE, // sgei
|
&JitShader::Compile_SGE, // sgei
|
||||||
&JitCompiler::Compile_SLT, // slti
|
&JitShader::Compile_SLT, // slti
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
nullptr, // unknown
|
nullptr, // unknown
|
||||||
&JitCompiler::Compile_NOP, // nop
|
&JitShader::Compile_NOP, // nop
|
||||||
&JitCompiler::Compile_END, // end
|
&JitShader::Compile_END, // end
|
||||||
nullptr, // break
|
nullptr, // break
|
||||||
&JitCompiler::Compile_CALL, // call
|
&JitShader::Compile_CALL, // call
|
||||||
&JitCompiler::Compile_CALLC, // callc
|
&JitShader::Compile_CALLC, // callc
|
||||||
&JitCompiler::Compile_CALLU, // callu
|
&JitShader::Compile_CALLU, // callu
|
||||||
&JitCompiler::Compile_IF, // ifu
|
&JitShader::Compile_IF, // ifu
|
||||||
&JitCompiler::Compile_IF, // ifc
|
&JitShader::Compile_IF, // ifc
|
||||||
&JitCompiler::Compile_LOOP, // loop
|
&JitShader::Compile_LOOP, // loop
|
||||||
nullptr, // emit
|
nullptr, // emit
|
||||||
nullptr, // sete
|
nullptr, // sete
|
||||||
&JitCompiler::Compile_JMP, // jmpc
|
&JitShader::Compile_JMP, // jmpc
|
||||||
&JitCompiler::Compile_JMP, // jmpu
|
&JitShader::Compile_JMP, // jmpu
|
||||||
&JitCompiler::Compile_CMP, // cmp
|
&JitShader::Compile_CMP, // cmp
|
||||||
&JitCompiler::Compile_CMP, // cmp
|
&JitShader::Compile_CMP, // cmp
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // madi
|
&JitShader::Compile_MAD, // madi
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
&JitCompiler::Compile_MAD, // mad
|
&JitShader::Compile_MAD, // mad
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following is used to alias some commonly used registers. Generally, RAX-RDX and XMM0-XMM3 can
|
// 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);
|
LOG_CRITICAL(HW_GPU, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::RuntimeAssert(bool condition, const char* msg) {
|
void JitShader::RuntimeAssert(bool condition, const char* msg) {
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
ABI_CallFunctionP(reinterpret_cast<const void*>(LogCritical), const_cast<char*>(msg));
|
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 src_reg SourceRegister object corresponding to the source register to load
|
||||||
* @param dest Destination XMM register to store the loaded, swizzled source register
|
* @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;
|
X64Reg src_ptr;
|
||||||
size_t src_offset;
|
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;
|
DestRegister dest;
|
||||||
unsigned operand_desc_id;
|
unsigned operand_desc_id;
|
||||||
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD ||
|
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));
|
MOVAPS(scratch, R(src1));
|
||||||
CMPPS(scratch, R(src2), CMP_ORD);
|
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));
|
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
|
// Note: NXOR is used below to check for equality
|
||||||
switch (instr.flow_control.op) {
|
switch (instr.flow_control.op) {
|
||||||
case Instruction::FlowControlType::Or:
|
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));
|
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));
|
CMP(sizeof(bool) * 8, MDisp(UNIFORMS, offset), Imm8(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
BitSet32 JitCompiler::PersistentCallerSavedRegs() {
|
BitSet32 JitShader::PersistentCallerSavedRegs() {
|
||||||
return persistent_regs & ABI_ALL_CALLER_SAVED;
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
ADDPS(SRC1, R(SRC2));
|
ADDPS(SRC1, R(SRC2));
|
||||||
Compile_DestEnable(instr, SRC1);
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ void JitCompiler::Compile_DP3(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ void JitCompiler::Compile_DP4(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_DPH(Instruction instr) {
|
void JitShader::Compile_DPH(Instruction instr) {
|
||||||
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::DPHI) {
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::DPHI) {
|
||||||
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
||||||
|
@ -411,7 +411,7 @@ void JitCompiler::Compile_DPH(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_EX2(Instruction instr) {
|
void JitShader::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));
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ void JitCompiler::Compile_EX2(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_LG2(Instruction instr) {
|
void JitShader::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));
|
||||||
|
|
||||||
|
@ -437,14 +437,14 @@ void JitCompiler::Compile_LG2(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
Compile_SanitizedMul(SRC1, SRC2, SCRATCH);
|
Compile_SanitizedMul(SRC1, SRC2, SCRATCH);
|
||||||
Compile_DestEnable(instr, SRC1);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_SGE(Instruction instr) {
|
void JitShader::Compile_SGE(Instruction instr) {
|
||||||
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SGEI) {
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SGEI) {
|
||||||
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
||||||
|
@ -459,7 +459,7 @@ void JitCompiler::Compile_SGE(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC2);
|
Compile_DestEnable(instr, SRC2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_SLT(Instruction instr) {
|
void JitShader::Compile_SLT(Instruction instr) {
|
||||||
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SLTI) {
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::SLTI) {
|
||||||
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1i, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2i, SRC2);
|
||||||
|
@ -474,7 +474,7 @@ void JitCompiler::Compile_SLT(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_FLR(Instruction instr) {
|
void JitShader::Compile_FLR(Instruction instr) {
|
||||||
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
||||||
|
|
||||||
if (Common::GetCPUCaps().sse4_1) {
|
if (Common::GetCPUCaps().sse4_1) {
|
||||||
|
@ -487,7 +487,7 @@ void JitCompiler::Compile_FLR(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
// SSE semantics match PICA200 ones: In case of NaN, SRC2 is returned.
|
// 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);
|
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, 1, instr.common.src1, SRC1);
|
||||||
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
Compile_SwizzleSrc(instr, 2, instr.common.src2, SRC2);
|
||||||
// SSE semantics match PICA200 ones: In case of NaN, SRC2 is returned.
|
// 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);
|
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] };
|
SwizzlePattern swiz = { g_state.vs.swizzle_data[instr.common.operand_desc_id] };
|
||||||
|
|
||||||
if (!swiz.DestComponentEnabled(0) && !swiz.DestComponentEnabled(1)) {
|
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_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
||||||
Compile_DestEnable(instr, 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);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
||||||
|
|
||||||
// TODO(bunnei): RCPSS is a pretty rough approximation, this might cause problems if Pica
|
// 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);
|
Compile_DestEnable(instr, SRC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_RSQ(Instruction instr) {
|
void JitShader::Compile_RSQ(Instruction instr) {
|
||||||
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1);
|
||||||
|
|
||||||
// TODO(bunnei): RSQRTSS is a pretty rough approximation, this might cause problems if Pica
|
// 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);
|
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);
|
ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8);
|
||||||
RET();
|
RET();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_CALL(Instruction instr) {
|
void JitShader::Compile_CALL(Instruction instr) {
|
||||||
// Push offset of the return
|
// Push offset of the return
|
||||||
PUSH(64, Imm32(instr.flow_control.dest_offset + instr.flow_control.num_instructions));
|
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));
|
ADD(64, R(RSP), Imm32(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_CALLC(Instruction instr) {
|
void JitShader::Compile_CALLC(Instruction instr) {
|
||||||
Compile_EvaluateCondition(instr);
|
Compile_EvaluateCondition(instr);
|
||||||
FixupBranch b = J_CC(CC_Z, true);
|
FixupBranch b = J_CC(CC_Z, true);
|
||||||
Compile_CALL(instr);
|
Compile_CALL(instr);
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_CALLU(Instruction instr) {
|
void JitShader::Compile_CALLU(Instruction instr) {
|
||||||
Compile_UniformCondition(instr);
|
Compile_UniformCondition(instr);
|
||||||
FixupBranch b = J_CC(CC_Z, true);
|
FixupBranch b = J_CC(CC_Z, true);
|
||||||
Compile_CALL(instr);
|
Compile_CALL(instr);
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_CMP(Instruction instr) {
|
void JitShader::Compile_CMP(Instruction instr) {
|
||||||
using Op = Instruction::Common::CompareOpType::Op;
|
using Op = Instruction::Common::CompareOpType::Op;
|
||||||
Op op_x = instr.common.compare_op.x;
|
Op op_x = instr.common.compare_op.x;
|
||||||
Op op_y = instr.common.compare_op.y;
|
Op op_y = instr.common.compare_op.y;
|
||||||
|
@ -652,7 +652,7 @@ void JitCompiler::Compile_CMP(Instruction instr) {
|
||||||
SHR(64, R(COND1), Imm8(63));
|
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);
|
Compile_SwizzleSrc(instr, 1, instr.mad.src1, SRC1);
|
||||||
|
|
||||||
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
|
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
|
||||||
|
@ -669,7 +669,7 @@ void JitCompiler::Compile_MAD(Instruction instr) {
|
||||||
Compile_DestEnable(instr, SRC1);
|
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");
|
RuntimeAssert(instr.flow_control.dest_offset >= program_counter, "Backwards if-statements not supported");
|
||||||
|
|
||||||
// Evaluate the "IF" condition
|
// Evaluate the "IF" condition
|
||||||
|
@ -700,7 +700,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
|
||||||
SetJumpTarget(b2);
|
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(instr.flow_control.dest_offset >= program_counter, "Backwards loops not supported");
|
||||||
RuntimeAssert(!looping, "Nested loops not supported");
|
RuntimeAssert(!looping, "Nested loops not supported");
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
|
||||||
looping = false;
|
looping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_JMP(Instruction instr) {
|
void JitShader::Compile_JMP(Instruction instr) {
|
||||||
if (instr.opcode.Value() == OpCode::Id::JMPC)
|
if (instr.opcode.Value() == OpCode::Id::JMPC)
|
||||||
Compile_EvaluateCondition(instr);
|
Compile_EvaluateCondition(instr);
|
||||||
else if (instr.opcode.Value() == OpCode::Id::JMPU)
|
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 });
|
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) {
|
while (program_counter < end) {
|
||||||
Compile_NextInstr();
|
Compile_NextInstr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_Return() {
|
void JitShader::Compile_Return() {
|
||||||
// Peek return offset on the stack and check if we're at that offset
|
// Peek return offset on the stack and check if we're at that offset
|
||||||
MOV(64, R(RAX), MDisp(RSP, 8));
|
MOV(64, R(RAX), MDisp(RSP, 8));
|
||||||
CMP(32, R(RAX), Imm32(program_counter));
|
CMP(32, R(RAX), Imm32(program_counter));
|
||||||
|
@ -760,7 +760,7 @@ void JitCompiler::Compile_Return() {
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile_NextInstr() {
|
void JitShader::Compile_NextInstr() {
|
||||||
if (std::binary_search(return_offsets.begin(), return_offsets.end(), program_counter)) {
|
if (std::binary_search(return_offsets.begin(), return_offsets.end(), program_counter)) {
|
||||||
Compile_Return();
|
Compile_Return();
|
||||||
}
|
}
|
||||||
|
@ -783,7 +783,7 @@ void JitCompiler::Compile_NextInstr() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::FindReturnOffsets() {
|
void JitShader::FindReturnOffsets() {
|
||||||
return_offsets.clear();
|
return_offsets.clear();
|
||||||
|
|
||||||
for (size_t offset = 0; offset < g_state.vs.program_code.size(); ++offset) {
|
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());
|
std::sort(return_offsets.begin(), return_offsets.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::Compile() {
|
void JitShader::Compile() {
|
||||||
// Reset flow control state
|
// Reset flow control state
|
||||||
program = (CompiledShader*)GetCodePtr();
|
program = (CompiledShader*)GetCodePtr();
|
||||||
program_counter = 0;
|
program_counter = 0;
|
||||||
|
@ -857,7 +857,7 @@ void JitCompiler::Compile() {
|
||||||
LOG_DEBUG(HW_GPU, "Compiled shader size=%d", size);
|
LOG_DEBUG(HW_GPU, "Compiled shader size=%d", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
JitCompiler::JitCompiler() {
|
JitShader::JitShader() {
|
||||||
AllocCodeSpace(MAX_SHADER_SIZE);
|
AllocCodeSpace(MAX_SHADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@ constexpr size_t MAX_SHADER_SIZE = 1024 * 64;
|
||||||
* This class implements the shader JIT compiler. It recompiles a Pica shader program into x86_64
|
* This class implements the shader JIT compiler. It recompiles a Pica shader program into x86_64
|
||||||
* code that can be executed on the host machine directly.
|
* code that can be executed on the host machine directly.
|
||||||
*/
|
*/
|
||||||
class JitCompiler : public Gen::XCodeBlock {
|
class JitShader : public Gen::XCodeBlock {
|
||||||
public:
|
public:
|
||||||
JitCompiler();
|
JitShader();
|
||||||
|
|
||||||
void Run(void* registers, unsigned offset) const {
|
void Run(void* registers, unsigned offset) const {
|
||||||
program(registers, code_ptr[offset]);
|
program(registers, code_ptr[offset]);
|
||||||
|
|
Loading…
Reference in New Issue