mirror of
https://github.com/PabloMK7/citra.git
synced 2025-07-04 06:25:15 +00:00
shader_jit_a64: Fix/optimize conditional evaluation
Fix some of the regressions introduced by the previous optimization. EOR does not support a constant of `0` in its immediate. In these cases the COND{0,1} registers can be utilized immediately.
This commit is contained in:
parent
2cff4c9c34
commit
e99f7da24e
1 changed files with 34 additions and 12 deletions
|
@ -386,28 +386,50 @@ void JitShader::Compile_SanitizedMul(QReg src1, QReg src2, QReg scratch0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitShader::Compile_EvaluateCondition(Instruction instr) {
|
void JitShader::Compile_EvaluateCondition(Instruction instr) {
|
||||||
const u8 refx = instr.flow_control.refx.Value();
|
const bool refx = instr.flow_control.refx.Value();
|
||||||
const u8 refy = instr.flow_control.refy.Value();
|
const bool refy = instr.flow_control.refy.Value();
|
||||||
|
|
||||||
switch (instr.flow_control.op) {
|
switch (instr.flow_control.op) {
|
||||||
// Note: NXOR is used below to check for equality
|
// Note: NXOR is used below to check for equality
|
||||||
case Instruction::FlowControlType::Or:
|
case Instruction::FlowControlType::Or: {
|
||||||
EOR(XSCRATCH0, COND0, refx ^ 1);
|
XReg OpX = XSCRATCH0;
|
||||||
EOR(XSCRATCH1, COND1, refy ^ 1);
|
if (!refx) {
|
||||||
ORR(XSCRATCH0, XSCRATCH0, XSCRATCH1);
|
EOR(OpX, COND0, u8(refx) ^ 1);
|
||||||
|
} else {
|
||||||
|
OpX = COND0;
|
||||||
|
}
|
||||||
|
XReg OpY = XSCRATCH1;
|
||||||
|
if (!refy) {
|
||||||
|
EOR(OpY, COND1, u8(refy) ^ 1);
|
||||||
|
} else {
|
||||||
|
OpY = COND1;
|
||||||
|
}
|
||||||
|
ORR(XSCRATCH0, OpX, OpY);
|
||||||
CMP(XSCRATCH0, 0);
|
CMP(XSCRATCH0, 0);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// Note: TST will AND two registers and set the EQ/NE flags on the result
|
// Note: TST will AND two registers and set the EQ/NE flags on the result
|
||||||
case Instruction::FlowControlType::And:
|
case Instruction::FlowControlType::And: {
|
||||||
EOR(XSCRATCH0, COND0, refx ^ 1);
|
XReg OpX = XSCRATCH0;
|
||||||
EOR(XSCRATCH1, COND1, refy ^ 1);
|
if (!refx) {
|
||||||
TST(XSCRATCH0, XSCRATCH1);
|
EOR(OpX, COND0, u8(refx) ^ 1);
|
||||||
|
} else {
|
||||||
|
OpX = COND0;
|
||||||
|
}
|
||||||
|
XReg OpY = XSCRATCH1;
|
||||||
|
if (!refy) {
|
||||||
|
EOR(OpY, COND1, u8(refy) ^ 1);
|
||||||
|
} else {
|
||||||
|
OpY = COND1;
|
||||||
|
}
|
||||||
|
TST(OpX, OpY);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Instruction::FlowControlType::JustX:
|
case Instruction::FlowControlType::JustX:
|
||||||
CMP(COND0, refx);
|
CMP(COND0, u8(refx) ^ 1);
|
||||||
break;
|
break;
|
||||||
case Instruction::FlowControlType::JustY:
|
case Instruction::FlowControlType::JustY:
|
||||||
CMP(COND1, refy);
|
CMP(COND1, u8(refy) ^ 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue