1
0
Fork 0
mirror of https://github.com/PabloMK7/citra.git synced 2025-06-30 12:39:06 +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) {
const u8 refx = instr.flow_control.refx.Value();
const u8 refy = instr.flow_control.refy.Value();
const bool refx = instr.flow_control.refx.Value();
const bool refy = instr.flow_control.refy.Value();
switch (instr.flow_control.op) {
// Note: NXOR is used below to check for equality
case Instruction::FlowControlType::Or:
EOR(XSCRATCH0, COND0, refx ^ 1);
EOR(XSCRATCH1, COND1, refy ^ 1);
ORR(XSCRATCH0, XSCRATCH0, XSCRATCH1);
case Instruction::FlowControlType::Or: {
XReg OpX = XSCRATCH0;
if (!refx) {
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);
break;
}
// Note: TST will AND two registers and set the EQ/NE flags on the result
case Instruction::FlowControlType::And:
EOR(XSCRATCH0, COND0, refx ^ 1);
EOR(XSCRATCH1, COND1, refy ^ 1);
TST(XSCRATCH0, XSCRATCH1);
case Instruction::FlowControlType::And: {
XReg OpX = XSCRATCH0;
if (!refx) {
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;
}
case Instruction::FlowControlType::JustX:
CMP(COND0, refx);
CMP(COND0, u8(refx) ^ 1);
break;
case Instruction::FlowControlType::JustY:
CMP(COND1, refy);
CMP(COND1, u8(refy) ^ 1);
break;
default:
UNREACHABLE();