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
				
			
		|  | @ -33,70 +33,70 @@ namespace Shader { | ||||||
| typedef void (JitShader::*JitFunction)(Instruction instr); | typedef void (JitShader::*JitFunction)(Instruction instr); | ||||||
| 
 | 
 | ||||||
| const JitFunction instr_table[64] = { | const JitFunction instr_table[64] = { | ||||||
|     &JitShader::Compile_ADD,   // add
 |     &JitShader::Compile_ADD,    // add
 | ||||||
|     &JitShader::Compile_DP3,   // dp3
 |     &JitShader::Compile_DP3,    // dp3
 | ||||||
|     &JitShader::Compile_DP4,   // dp4
 |     &JitShader::Compile_DP4,    // dp4
 | ||||||
|     &JitShader::Compile_DPH,   // dph
 |     &JitShader::Compile_DPH,    // dph
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_EX2,   // ex2
 |     &JitShader::Compile_EX2,    // ex2
 | ||||||
|     &JitShader::Compile_LG2,   // lg2
 |     &JitShader::Compile_LG2,    // lg2
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_MUL,   // mul
 |     &JitShader::Compile_MUL,    // mul
 | ||||||
|     &JitShader::Compile_SGE,   // sge
 |     &JitShader::Compile_SGE,    // sge
 | ||||||
|     &JitShader::Compile_SLT,   // slt
 |     &JitShader::Compile_SLT,    // slt
 | ||||||
|     &JitShader::Compile_FLR,   // flr
 |     &JitShader::Compile_FLR,    // flr
 | ||||||
|     &JitShader::Compile_MAX,   // max
 |     &JitShader::Compile_MAX,    // max
 | ||||||
|     &JitShader::Compile_MIN,   // min
 |     &JitShader::Compile_MIN,    // min
 | ||||||
|     &JitShader::Compile_RCP,   // rcp
 |     &JitShader::Compile_RCP,    // rcp
 | ||||||
|     &JitShader::Compile_RSQ,   // rsq
 |     &JitShader::Compile_RSQ,    // rsq
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_MOVA,  // mova
 |     &JitShader::Compile_MOVA,   // mova
 | ||||||
|     &JitShader::Compile_MOV,   // mov
 |     &JitShader::Compile_MOV,    // mov
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_DPH,   // dphi
 |     &JitShader::Compile_DPH,    // dphi
 | ||||||
|     nullptr,                   // unknown
 |     nullptr,                    // unknown
 | ||||||
|     &JitShader::Compile_SGE,   // sgei
 |     &JitShader::Compile_SGE,    // sgei
 | ||||||
|     &JitShader::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
 | ||||||
|     &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
 | ||||||
|     &JitShader::Compile_IF,    // ifu
 |     &JitShader::Compile_IF,     // ifu
 | ||||||
|     &JitShader::Compile_IF,    // ifc
 |     &JitShader::Compile_IF,     // ifc
 | ||||||
|     &JitShader::Compile_LOOP,  // loop
 |     &JitShader::Compile_LOOP,   // loop
 | ||||||
|     &JitShader::Compile_EMIT,  // emit
 |     &JitShader::Compile_EMIT,   // emit
 | ||||||
|     &JitShader::Compile_SETE,  // sete
 |     &JitShader::Compile_SETE,   // sete
 | ||||||
|     &JitShader::Compile_JMP,   // jmpc
 |     &JitShader::Compile_JMP,    // jmpc
 | ||||||
|     &JitShader::Compile_JMP,   // jmpu
 |     &JitShader::Compile_JMP,    // jmpu
 | ||||||
|     &JitShader::Compile_CMP,   // cmp
 |     &JitShader::Compile_CMP,    // cmp
 | ||||||
|     &JitShader::Compile_CMP,   // cmp
 |     &JitShader::Compile_CMP,    // cmp
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // madi
 |     &JitShader::Compile_MAD,    // madi
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::Compile_MAD,   // mad
 |     &JitShader::Compile_MAD,    // mad
 | ||||||
|     &JitShader::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
 | ||||||
|  | @ -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