From 8ab9521ceafecd98062113b7f142390eb7513e00 Mon Sep 17 00:00:00 2001 From: xbzk Date: Mon, 27 Jul 2026 21:54:45 -0300 Subject: [PATCH] [video_core] Restrict macro JIT zero-register skips Only apply the zero-register ALU skip when the operation is safe to elide without changing carry/result semantics. This avoids invalid-instruction floods seen with Macro JIT enabled while keeping the optimization for operations where a zero source is harmless. --- src/video_core/macro.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/video_core/macro.cpp b/src/video_core/macro.cpp index 3d7ac04851..5123962e37 100644 --- a/src/video_core/macro.cpp +++ b/src/video_core/macro.cpp @@ -782,13 +782,17 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { const bool valid_operation = !is_a_zero && !is_b_zero; [[maybe_unused]] const bool is_move_operation = !is_a_zero && is_b_zero; const bool has_zero_register = is_a_zero || is_b_zero; - const bool no_zero_reg_skip = opcode.alu_operation == Macro::ALUOperation::AddWithCarry || - opcode.alu_operation == Macro::ALUOperation::SubtractWithBorrow; + const bool zero_reg_skip = + optimizer.zero_reg_skip && !is_a_zero && is_b_zero && + (opcode.alu_operation == Macro::ALUOperation::Xor || + opcode.alu_operation == Macro::ALUOperation::Or || + (optimizer.can_skip_carry && (opcode.alu_operation == Macro::ALUOperation::Add || + opcode.alu_operation == Macro::ALUOperation::Subtract))); Xbyak::Reg32 src_a; Xbyak::Reg32 src_b; - if (!optimizer.zero_reg_skip || no_zero_reg_skip) { + if (!zero_reg_skip) { src_a = Compile_GetRegister(opcode.src_a, RESULT); src_b = Compile_GetRegister(opcode.src_b, eax); } else { @@ -804,7 +808,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { switch (opcode.alu_operation) { case Macro::ALUOperation::Add: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (valid_operation) { add(src_a, src_b); } @@ -822,7 +826,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { setc(byte[STATE + offsetof(JITState, carry_flag)]); break; case Macro::ALUOperation::Subtract: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (valid_operation) { sub(src_a, src_b); has_emitted = true; @@ -841,7 +845,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { setc(byte[STATE + offsetof(JITState, carry_flag)]); break; case Macro::ALUOperation::Xor: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (valid_operation) { xor_(src_a, src_b); } @@ -850,7 +854,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { } break; case Macro::ALUOperation::Or: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (valid_operation) { or_(src_a, src_b); } @@ -859,7 +863,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { } break; case Macro::ALUOperation::And: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (!has_zero_register) { and_(src_a, src_b); } @@ -868,7 +872,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { } break; case Macro::ALUOperation::AndNot: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (!is_a_zero) { not_(src_b); and_(src_a, src_b); @@ -879,7 +883,7 @@ void MacroJITx64Impl::Compile_ALU(Core::System& system, Macro::Opcode opcode) { } break; case Macro::ALUOperation::Nand: - if (optimizer.zero_reg_skip) { + if (zero_reg_skip) { if (!is_a_zero) { and_(src_a, src_b); not_(src_a);