From 4632791a40f8ec5af7e166ff90fd4f8cd69b2745 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 17 Mar 2016 19:45:09 -0400 Subject: shader_jit_x64: Rewrite flow control to support arbitrary CALL and JMP instructions. --- src/video_core/shader/shader_jit_x64.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'src/video_core/shader/shader_jit_x64.h') diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h index 5357c964b..d6f03892d 100644 --- a/src/video_core/shader/shader_jit_x64.h +++ b/src/video_core/shader/shader_jit_x64.h @@ -4,6 +4,9 @@ #pragma once +#include +#include + #include #include "common/x64/emitter.h" @@ -66,8 +69,9 @@ public: void Compile_MAD(Instruction instr); private: + void Compile_Block(unsigned end); - void Compile_NextInstr(unsigned* offset); + void Compile_NextInstr(); void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, Gen::X64Reg dest); void Compile_DestEnable(Instruction instr, Gen::X64Reg dest); @@ -81,13 +85,31 @@ private: void Compile_EvaluateCondition(Instruction instr); void Compile_UniformCondition(Instruction instr); + /** + * Emits the code to conditionally return from a subroutine envoked by the `CALL` instruction. + */ + void Compile_Return(); + BitSet32 PersistentCallerSavedRegs(); - /// Pointer to the variable that stores the current Pica code offset. Used to handle nested code blocks. - unsigned* offset_ptr = nullptr; + /** + * Analyzes the entire shader program for `CALL` instructions before emitting any code, + * identifying the locations where a return needs to be inserted. + */ + void FindReturnOffsets(); + + /// Mapping of Pica VS instructions to pointers in the emitted code + std::array code_ptr; + + /// Offsets in code where a return needs to be inserted + std::set return_offsets; + + unsigned last_program_counter; ///< Offset of the most recent instruction decoded + unsigned program_counter; ///< Offset of the next instruction to decode + bool looping = false; ///< True if compiling a loop, used to check for nested loops - /// Set to true if currently in a loop, used to check for the existence of nested loops - bool looping = false; + /// Branches that need to be fixed up once the entire shader program is compiled + std::vector> fixup_branches; }; } // Shader -- cgit v1.2.3