diff --git a/include/PICA/dynapica/shader_rec_emitter_arm64.hpp b/include/PICA/dynapica/shader_rec_emitter_arm64.hpp index b73401f3..b8133b42 100644 --- a/include/PICA/dynapica/shader_rec_emitter_arm64.hpp +++ b/include/PICA/dynapica/shader_rec_emitter_arm64.hpp @@ -42,6 +42,12 @@ class ShaderEmitter : private oaknut::CodeBlock, public oaknut::CodeGenerator { oaknut::Label emitLog2Func(); oaknut::Label emitExp2Func(); + template + void getLabelPointer(const oaknut::Label& label) { + auto pointer = reinterpret_cast(oaknut::CodeBlock::ptr()) + label.offset(); + return reinterpret_cast(pointer); + } + // Compile all instructions from [current recompiler PC, end) void compileUntil(const PICAShader& shaderUnit, u32 endPC); // Compile instruction "instr" @@ -118,7 +124,7 @@ class ShaderEmitter : private oaknut::CodeBlock, public oaknut::CodeGenerator { // PC must be a valid entrypoint here. It doesn't have that much overhead in this case, so we use std::array<>::at() to assert it does InstructionCallback getInstructionCallback(u32 pc) { - return reinterpret_cast(oaknut::CodeBlock::ptr() + instructionLabels.at(pc).offset()); + return getLabelPointer(instructionLabels.at(pc)); } PrologueCallback getPrologueCallback() { return prologueCb; } diff --git a/src/core/PICA/dynapica/shader_rec_emitter_arm64.cpp b/src/core/PICA/dynapica/shader_rec_emitter_arm64.cpp index 77b003c4..f88661e4 100644 --- a/src/core/PICA/dynapica/shader_rec_emitter_arm64.cpp +++ b/src/core/PICA/dynapica/shader_rec_emitter_arm64.cpp @@ -39,7 +39,7 @@ void ShaderEmitter::compile(const PICAShader& shaderUnit) { align(16); l(prologueLabel); - prologueCb = reinterpret_cast(oaknut::CodeBlock::ptr() + prologueLabel.offset()); + prologueCb = getLabelPointer(prologueLabel); // Set state pointer to the proper pointer // state pointer is volatile, no need to preserve it @@ -407,7 +407,7 @@ void ShaderEmitter::storeRegister(QReg source, const PICAShader& shader, u32 des if (writeMask == 0xf) { // No lanes are masked, just use STR STR(source, statePointer, offset); } else { - u8* blendMaskPointer = reinterpret_cast(oaknut::CodeBlock::ptr() + blendMasks.offset()); + u8* blendMaskPointer = getLabelPointer(blendMasks)); LDR(scratch1, statePointer, offset); // Load current value LDR(scratch2, blendMaskPointer + writeMask * 16); // Load write mask for blending