diff options
| author | 2020-04-25 22:53:54 -0300 | |
|---|---|---|
| committer | 2020-04-25 22:58:33 -0300 | |
| commit | e895a4e2d7ebf29fbafda7d950301cd7d03efdbb (patch) | |
| tree | 57dc090aaf66908e213b10cd64fc184b286b4c8a /src | |
| parent | shader/arithmetic_integer: Change IAdd to UAdd to avoid signed overflow (diff) | |
| download | yuzu-e895a4e2d7ebf29fbafda7d950301cd7d03efdbb.tar.gz yuzu-e895a4e2d7ebf29fbafda7d950301cd7d03efdbb.tar.xz yuzu-e895a4e2d7ebf29fbafda7d950301cd7d03efdbb.zip | |
shader/arithmetic_integer: Fix edge case and mark IADD.X Rd.CC as unimplemented
IADD.X Rd.CC requires some extra logic that is not currently
implemented. Abort when this is hit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index addd7f533..ced5c3dc1 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp | |||
| @@ -35,7 +35,8 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) { | |||
| 35 | case OpCode::Id::IADD_C: | 35 | case OpCode::Id::IADD_C: |
| 36 | case OpCode::Id::IADD_R: | 36 | case OpCode::Id::IADD_R: |
| 37 | case OpCode::Id::IADD_IMM: { | 37 | case OpCode::Id::IADD_IMM: { |
| 38 | UNIMPLEMENTED_IF_MSG(instr.alu.saturate_d, "IADD saturation not implemented"); | 38 | UNIMPLEMENTED_IF_MSG(instr.alu.saturate_d, "IADD.SAT"); |
| 39 | UNIMPLEMENTED_IF_MSG(instr.iadd.x && instr.generates_cc, "IADD.X Rd.CC"); | ||
| 39 | 40 | ||
| 40 | op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true); | 41 | op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true); |
| 41 | op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true); | 42 | op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true); |
| @@ -49,6 +50,10 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) { | |||
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | if (instr.generates_cc) { | 52 | if (instr.generates_cc) { |
| 53 | // Avoid changing result's carry flag | ||
| 54 | SetTemporary(bb, 0, std::move(value)); | ||
| 55 | value = GetTemporary(0); | ||
| 56 | |||
| 52 | const Node i0 = Immediate(0); | 57 | const Node i0 = Immediate(0); |
| 53 | 58 | ||
| 54 | Node zero = Operation(OperationCode::LogicalIEqual, value, i0); | 59 | Node zero = Operation(OperationCode::LogicalIEqual, value, i0); |