1
0
Fork 0
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:
Wunkolo 2024-08-17 11:48:17 -07:00
parent 2cff4c9c34
commit e99f7da24e

View file

@ -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();