Browse Source

[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.
xbzk/hb-tico-support-part-2
xbzk 6 days ago
parent
commit
8ab9521cea
  1. 24
      src/video_core/macro.cpp

24
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);

Loading…
Cancel
Save