فهرست منبع

shader: Fix IADD3.CC

ameerj 5 سال پیش
والد
کامیت
fb14820c86
1فایلهای تغییر یافته به همراه5 افزوده شده و 12 حذف شده
  1. 5 12
      src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp

+ 5 - 12
src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp

@@ -73,21 +73,13 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_b, IR::U32 op_c) {
         op_c = v.ir.INeg(op_c);
         op_c = v.ir.INeg(op_c);
     }
     }
 
 
-    IR::U32 lhs{v.ir.IAdd(op_a, op_b)};
-    IR::U1 of_1;
-    if (iadd3.cc != 0) {
-        of_1 = v.ir.GetOverflowFromOp(lhs);
-    }
+    IR::U32 lhs_1{v.ir.IAdd(op_a, op_b)};
     if (iadd3.x != 0) {
     if (iadd3.x != 0) {
         const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))};
         const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))};
-        lhs = v.ir.IAdd(lhs, carry);
-    }
-    if (iadd3.cc != 0 && iadd3.shift == Shift::Left) {
-        const IR::U32 high_bits{v.ir.ShiftRightLogical(lhs, v.ir.Imm32(16))};
-        of_1 = v.ir.LogicalOr(of_1, v.ir.INotEqual(v.ir.Imm32(0), high_bits));
+        lhs_1 = v.ir.IAdd(lhs_1, carry);
     }
     }
-    lhs = IntegerShift(v.ir, lhs, iadd3.shift);
-    const IR::U32 result{v.ir.IAdd(lhs, op_c)};
+    const IR::U32 lhs_2{IntegerShift(v.ir, lhs_1, iadd3.shift)};
+    const IR::U32 result{v.ir.IAdd(lhs_2, op_c)};
 
 
     v.X(iadd3.dest_reg, result);
     v.X(iadd3.dest_reg, result);
     if (iadd3.cc != 0) {
     if (iadd3.cc != 0) {
@@ -98,6 +90,7 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_b, IR::U32 op_c) {
         v.SetZFlag(v.ir.GetZeroFromOp(result));
         v.SetZFlag(v.ir.GetZeroFromOp(result));
         v.SetSFlag(v.ir.GetSignFromOp(result));
         v.SetSFlag(v.ir.GetSignFromOp(result));
         v.SetCFlag(v.ir.GetCarryFromOp(result));
         v.SetCFlag(v.ir.GetCarryFromOp(result));
+        const IR::U1 of_1{v.ir.ILessThan(lhs_1, op_a, false)};
         v.SetOFlag(v.ir.LogicalOr(v.ir.GetOverflowFromOp(result), of_1));
         v.SetOFlag(v.ir.LogicalOr(v.ir.GetOverflowFromOp(result), of_1));
     }
     }
 }
 }