diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/integer_scaled_add.cpp | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_scaled_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_scaled_add.cpp index 7aef37f54..93cc2c0b1 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_scaled_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_scaled_add.cpp | |||
| @@ -30,23 +30,24 @@ void ISCADD(TranslatorVisitor& v, u64 insn, IR::U32 op_b) { | |||
| 30 | if (iscadd.neg_b != 0) { | 30 | if (iscadd.neg_b != 0) { |
| 31 | op_b = v.ir.INeg(op_b); | 31 | op_b = v.ir.INeg(op_b); |
| 32 | } | 32 | } |
| 33 | } else { | ||
| 34 | // When PO is present, add one | ||
| 35 | op_b = v.ir.IAdd(op_b, v.ir.Imm32(1)); | ||
| 33 | } | 36 | } |
| 34 | // With the operands already processed, scale A | 37 | // With the operands already processed, scale A |
| 35 | const IR::U32 scale{v.ir.Imm32(static_cast<u32>(iscadd.scale))}; | 38 | const IR::U32 scale{v.ir.Imm32(static_cast<u32>(iscadd.scale))}; |
| 36 | const IR::U32 scaled_a{v.ir.ShiftLeftLogical(op_a, scale)}; | 39 | const IR::U32 scaled_a{v.ir.ShiftLeftLogical(op_a, scale)}; |
| 37 | 40 | ||
| 38 | IR::U32 result{v.ir.IAdd(scaled_a, op_b)}; | 41 | const IR::U32 result{v.ir.IAdd(scaled_a, op_b)}; |
| 39 | if (po) { | ||
| 40 | // .PO adds one to the final result | ||
| 41 | result = v.ir.IAdd(result, v.ir.Imm32(1)); | ||
| 42 | } | ||
| 43 | v.X(iscadd.dest_reg, result); | 42 | v.X(iscadd.dest_reg, result); |
| 44 | 43 | ||
| 45 | if (iscadd.cc != 0) { | 44 | if (iscadd.cc != 0) { |
| 46 | v.SetZFlag(v.ir.GetZeroFromOp(result)); | 45 | v.SetZFlag(v.ir.GetZeroFromOp(result)); |
| 47 | v.SetSFlag(v.ir.GetSignFromOp(result)); | 46 | v.SetSFlag(v.ir.GetSignFromOp(result)); |
| 48 | v.SetCFlag(v.ir.GetCarryFromOp(result)); | 47 | const IR::U1 carry{v.ir.GetCarryFromOp(result)}; |
| 49 | v.SetOFlag(v.ir.GetOverflowFromOp(result)); | 48 | const IR::U1 overflow{v.ir.GetOverflowFromOp(result)}; |
| 49 | v.SetCFlag(po ? v.ir.LogicalOr(carry, v.ir.GetCarryFromOp(op_b)) : carry); | ||
| 50 | v.SetOFlag(po ? v.ir.LogicalOr(overflow, v.ir.GetOverflowFromOp(op_b)) : overflow); | ||
| 50 | } | 51 | } |
| 51 | } | 52 | } |
| 52 | 53 | ||