mirror of
https://github.com/citra-mirror/citra.git
synced 2024-08-20 02:13:23 +02:00
Shader JIT: Fix off-by-one error when compiling JMPs
There was a mistake in the JMP code which meant that one instruction at the destination would be skipped when the jump was taken. This commit also changes the meaning of the culprit parameter to make it less confusing and avoid similar mistakes in the future.
This commit is contained in:
parent
0b6cc0592d
commit
c1071c1ff7
@ -653,7 +653,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
|
||||
FixupBranch b = J_CC(CC_Z, true);
|
||||
|
||||
// Compile the code that corresponds to the condition evaluating as true
|
||||
Compile_Block(instr.flow_control.dest_offset - 1);
|
||||
Compile_Block(instr.flow_control.dest_offset);
|
||||
|
||||
// If there isn't an "ELSE" condition, we are done here
|
||||
if (instr.flow_control.num_instructions == 0) {
|
||||
@ -667,7 +667,7 @@ void JitCompiler::Compile_IF(Instruction instr) {
|
||||
|
||||
// This code corresponds to the "ELSE" condition
|
||||
// Comple the code that corresponds to the condition evaluating as false
|
||||
Compile_Block(instr.flow_control.dest_offset + instr.flow_control.num_instructions - 1);
|
||||
Compile_Block(instr.flow_control.dest_offset + instr.flow_control.num_instructions);
|
||||
|
||||
SetJumpTarget(b2);
|
||||
}
|
||||
@ -691,7 +691,7 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
|
||||
|
||||
auto loop_start = GetCodePtr();
|
||||
|
||||
Compile_Block(instr.flow_control.dest_offset);
|
||||
Compile_Block(instr.flow_control.dest_offset + 1);
|
||||
|
||||
ADD(32, R(LOOPCOUNT_REG), R(LOOPINC)); // Increment LOOPCOUNT_REG by Z-component
|
||||
SUB(32, R(LOOPCOUNT), Imm8(1)); // Increment loop count by 1
|
||||
@ -717,12 +717,12 @@ void JitCompiler::Compile_JMP(Instruction instr) {
|
||||
SetJumpTarget(b);
|
||||
}
|
||||
|
||||
void JitCompiler::Compile_Block(unsigned stop) {
|
||||
void JitCompiler::Compile_Block(unsigned end) {
|
||||
// Save current offset pointer
|
||||
unsigned* prev_offset_ptr = offset_ptr;
|
||||
unsigned offset = *prev_offset_ptr;
|
||||
|
||||
while (offset <= stop)
|
||||
while (offset < end)
|
||||
Compile_NextInstr(&offset);
|
||||
|
||||
// Restore current offset pointer
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
void Compile_MAD(Instruction instr);
|
||||
|
||||
private:
|
||||
void Compile_Block(unsigned stop);
|
||||
void Compile_Block(unsigned end);
|
||||
void Compile_NextInstr(unsigned* offset);
|
||||
|
||||
void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, Gen::X64Reg dest);
|
||||
|
Loading…
Reference in New Issue
Block a user