From f73138c5de481b53c7f393eabad76d6998a21809 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:30:35 +0300 Subject: [PATCH] [Shader JIT] Implement SGE(I) --- .../PICA/dynapica/shader_rec_emitter_x64.hpp | 1 - include/PICA/shader.hpp | 1 + .../PICA/dynapica/shader_rec_emitter_x64.cpp | 22 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/PICA/dynapica/shader_rec_emitter_x64.hpp b/include/PICA/dynapica/shader_rec_emitter_x64.hpp index 51e6a43d..0338911c 100644 --- a/include/PICA/dynapica/shader_rec_emitter_x64.hpp +++ b/include/PICA/dynapica/shader_rec_emitter_x64.hpp @@ -112,7 +112,6 @@ class ShaderEmitter : public Xbyak::CodeGenerator { void recRSQ(const PICAShader& shader, u32 instruction); void recSETEMIT(const PICAShader& shader, u32 instruction); void recSGE(const PICAShader& shader, u32 instruction); - void recSGEI(const PICAShader& shader, u32 instruction); void recSLT(const PICAShader& shader, u32 instruction); MAKE_LOG_FUNCTION(log, shaderJITLogger) diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index 0f3154f1..48db777d 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -23,6 +23,7 @@ namespace ShaderOpcodes { LG2 = 0x06, LIT = 0x07, MUL = 0x08, + SGE = 0x09, SLT = 0x0A, FLR = 0x0B, MAX = 0x0C, diff --git a/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp b/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp index 523c41db..7bcf4b46 100644 --- a/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp +++ b/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp @@ -180,6 +180,10 @@ void ShaderEmitter::compileInstruction(const PICAShader& shaderUnit) { case ShaderOpcodes::SLTI: recSLT(shaderUnit, instruction); break; + case ShaderOpcodes::SGE: + case ShaderOpcodes::SGEI: + recSGE(shaderUnit, instruction); break; + default: Helpers::panic("Shader JIT: Unimplemented PICA opcode %X", opcode); } @@ -681,6 +685,24 @@ void ShaderEmitter::recSLT(const PICAShader& shader, u32 instruction) { storeRegister(src1_xmm, shader, dest, operandDescriptor); } +void ShaderEmitter::recSGE(const PICAShader& shader, u32 instruction) { + const bool isSGEI = (instruction >> 26) == ShaderOpcodes::SGEI; + const u32 operandDescriptor = shader.operandDescriptors[instruction & 0x7f]; + + const u32 src1 = isSGEI ? getBits<14, 5>(instruction) : getBits<12, 7>(instruction); + const u32 src2 = isSGEI ? getBits<7, 7>(instruction) : getBits<7, 5>(instruction); + const u32 idx = getBits<19, 2>(instruction); + const u32 dest = getBits<21, 5>(instruction); + + loadRegister<1>(src1_xmm, shader, src1, isSGEI ? 0 : idx, operandDescriptor); + loadRegister<2>(src2_xmm, shader, src2, isSGEI ? idx : 0, operandDescriptor); + + // SSE does not have a cmpgeps instruction so we turn src1 >= src2 to src2 <= src1, result in src2 + cmpleps(src2_xmm, src1_xmm); + andps(src2_xmm, xword[rip + onesVector]); + storeRegister(src2_xmm, shader, dest, operandDescriptor); +} + void ShaderEmitter::recCMP(const PICAShader& shader, u32 instruction) { const u32 operandDescriptor = shader.operandDescriptors[instruction & 0x7f]; const u32 src1 = getBits<12, 7>(instruction);