3
0
Fork 0
forked from suyu/suyu

shader_jit_x64.cpp: Rename JitCompiler to JitShader.

This commit is contained in:
bunnei 2016-04-12 23:34:03 -04:00
parent 847fb951e2
commit 3f623b2561
3 changed files with 92 additions and 92 deletions

View file

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

View file

@ -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);
} }

View file

@ -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]);