mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	shader/jit: implement breakc
This commit is contained in:
		
							parent
							
								
									09982c3386
								
							
						
					
					
						commit
						9060e08e49
					
				
					 2 changed files with 81 additions and 64 deletions
				
			
		|  | @ -68,7 +68,7 @@ const JitFunction instr_table[64] = { | ||||||
|     nullptr,                    // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_NOP,    // nop
 |     &JitShader::Compile_NOP,    // nop
 | ||||||
|     &JitShader::Compile_END,    // end
 |     &JitShader::Compile_END,    // end
 | ||||||
|     nullptr,                   // break
 |     &JitShader::Compile_BREAKC, // breakc
 | ||||||
|     &JitShader::Compile_CALL,   // call
 |     &JitShader::Compile_CALL,   // call
 | ||||||
|     &JitShader::Compile_CALLC,  // callc
 |     &JitShader::Compile_CALLC,  // callc
 | ||||||
|     &JitShader::Compile_CALLU,  // callu
 |     &JitShader::Compile_CALLU,  // callu
 | ||||||
|  | @ -584,6 +584,14 @@ void JitShader::Compile_END(Instruction instr) { | ||||||
|     ret(); |     ret(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void JitShader::Compile_BREAKC(Instruction instr) { | ||||||
|  |     Compile_Assert(looping, "BREAKC must be inside a LOOP"); | ||||||
|  |     if (looping) { | ||||||
|  |         Compile_EvaluateCondition(instr); | ||||||
|  |         jnz(*loop_break_label); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void JitShader::Compile_CALL(Instruction instr) { | void JitShader::Compile_CALL(Instruction instr) { | ||||||
|     // Push offset of the return
 |     // Push offset of the return
 | ||||||
|     push(qword, (instr.flow_control.dest_offset + instr.flow_control.num_instructions)); |     push(qword, (instr.flow_control.dest_offset + instr.flow_control.num_instructions)); | ||||||
|  | @ -727,11 +735,14 @@ void JitShader::Compile_LOOP(Instruction instr) { | ||||||
|     Label l_loop_start; |     Label l_loop_start; | ||||||
|     L(l_loop_start); |     L(l_loop_start); | ||||||
| 
 | 
 | ||||||
|  |     loop_break_label = Xbyak::Label(); | ||||||
|     Compile_Block(instr.flow_control.dest_offset + 1); |     Compile_Block(instr.flow_control.dest_offset + 1); | ||||||
| 
 | 
 | ||||||
|     add(LOOPCOUNT_REG, LOOPINC); // Increment LOOPCOUNT_REG by Z-component
 |     add(LOOPCOUNT_REG, LOOPINC); // Increment LOOPCOUNT_REG by Z-component
 | ||||||
|     sub(LOOPCOUNT, 1);           // Increment loop count by 1
 |     sub(LOOPCOUNT, 1);           // Increment loop count by 1
 | ||||||
|     jnz(l_loop_start);           // Loop if not equal
 |     jnz(l_loop_start);           // Loop if not equal
 | ||||||
|  |     L(*loop_break_label); | ||||||
|  |     loop_break_label = boost::none; | ||||||
| 
 | 
 | ||||||
|     looping = false; |     looping = false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| #include <cstddef> | #include <cstddef> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <boost/optional.hpp> | ||||||
| #include <nihstro/shader_bytecode.h> | #include <nihstro/shader_bytecode.h> | ||||||
| #include <xbyak.h> | #include <xbyak.h> | ||||||
| #include "common/bit_set.h" | #include "common/bit_set.h" | ||||||
|  | @ -58,6 +59,7 @@ public: | ||||||
|     void Compile_MOV(Instruction instr); |     void Compile_MOV(Instruction instr); | ||||||
|     void Compile_NOP(Instruction instr); |     void Compile_NOP(Instruction instr); | ||||||
|     void Compile_END(Instruction instr); |     void Compile_END(Instruction instr); | ||||||
|  |     void Compile_BREAKC(Instruction instr); | ||||||
|     void Compile_CALL(Instruction instr); |     void Compile_CALL(Instruction instr); | ||||||
|     void Compile_CALLC(Instruction instr); |     void Compile_CALLC(Instruction instr); | ||||||
|     void Compile_CALLU(Instruction instr); |     void Compile_CALLU(Instruction instr); | ||||||
|  | @ -119,6 +121,10 @@ private: | ||||||
|     /// Mapping of Pica VS instructions to pointers in the emitted code
 |     /// Mapping of Pica VS instructions to pointers in the emitted code
 | ||||||
|     std::array<Xbyak::Label, MAX_PROGRAM_CODE_LENGTH> instruction_labels; |     std::array<Xbyak::Label, MAX_PROGRAM_CODE_LENGTH> instruction_labels; | ||||||
| 
 | 
 | ||||||
|  |     /// Label pointing to the end of the current LOOP block. Used by the BREAKC instruction to break
 | ||||||
|  |     /// out of the loop.
 | ||||||
|  |     boost::optional<Xbyak::Label> loop_break_label; | ||||||
|  | 
 | ||||||
|     /// Offsets in code where a return needs to be inserted
 |     /// Offsets in code where a return needs to be inserted
 | ||||||
|     std::vector<unsigned> return_offsets; |     std::vector<unsigned> return_offsets; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue