diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp index 33e2a51ae..b50017536 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp | |||
| @@ -22,31 +22,33 @@ enum class Half : u64 { | |||
| 22 | [[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) { | 22 | [[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) { |
| 23 | constexpr bool is_signed{false}; | 23 | constexpr bool is_signed{false}; |
| 24 | switch (half) { | 24 | switch (half) { |
| 25 | case Half::All: | ||
| 26 | return value; | ||
| 25 | case Half::Lower: | 27 | case Half::Lower: |
| 26 | return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed); | 28 | return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed); |
| 27 | case Half::Upper: | 29 | case Half::Upper: |
| 28 | return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed); | 30 | return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed); |
| 29 | default: | ||
| 30 | return value; | ||
| 31 | } | 31 | } |
| 32 | throw NotImplementedException("Invalid half"); | ||
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | [[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) { | 35 | [[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) { |
| 35 | switch (shift) { | 36 | switch (shift) { |
| 37 | case Shift::None: | ||
| 38 | return value; | ||
| 36 | case Shift::Right: | 39 | case Shift::Right: |
| 37 | return ir.ShiftRightLogical(value, ir.Imm32(16)); | 40 | return ir.ShiftRightLogical(value, ir.Imm32(16)); |
| 38 | case Shift::Left: | 41 | case Shift::Left: |
| 39 | return ir.ShiftLeftLogical(value, ir.Imm32(16)); | 42 | return ir.ShiftLeftLogical(value, ir.Imm32(16)); |
| 40 | default: | ||
| 41 | return value; | ||
| 42 | } | 43 | } |
| 44 | throw NotImplementedException("Invalid shift"); | ||
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 op_c) { | 47 | void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 op_c, |
| 48 | Shift shift = Shift::None) { | ||
| 46 | union { | 49 | union { |
| 47 | u64 insn; | 50 | u64 insn; |
| 48 | BitField<0, 8, IR::Reg> dest_reg; | 51 | BitField<0, 8, IR::Reg> dest_reg; |
| 49 | BitField<37, 2, Shift> shift; | ||
| 50 | BitField<47, 1, u64> cc; | 52 | BitField<47, 1, u64> cc; |
| 51 | BitField<48, 1, u64> x; | 53 | BitField<48, 1, u64> x; |
| 52 | BitField<49, 1, u64> neg_c; | 54 | BitField<49, 1, u64> neg_c; |
| @@ -68,7 +70,7 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 o | |||
| 68 | const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))}; | 70 | const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))}; |
| 69 | lhs_1 = v.ir.IAdd(lhs_1, carry); | 71 | lhs_1 = v.ir.IAdd(lhs_1, carry); |
| 70 | } | 72 | } |
| 71 | const IR::U32 lhs_2{IntegerShift(v.ir, lhs_1, iadd3.shift)}; | 73 | const IR::U32 lhs_2{IntegerShift(v.ir, lhs_1, shift)}; |
| 72 | const IR::U32 result{v.ir.IAdd(lhs_2, op_c)}; | 74 | const IR::U32 result{v.ir.IAdd(lhs_2, op_c)}; |
| 73 | 75 | ||
| 74 | v.X(iadd3.dest_reg, result); | 76 | v.X(iadd3.dest_reg, result); |
| @@ -89,14 +91,16 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 o | |||
| 89 | void TranslatorVisitor::IADD3_reg(u64 insn) { | 91 | void TranslatorVisitor::IADD3_reg(u64 insn) { |
| 90 | union { | 92 | union { |
| 91 | u64 insn; | 93 | u64 insn; |
| 94 | BitField<37, 2, Shift> shift; | ||
| 92 | BitField<35, 2, Half> half_a; | 95 | BitField<35, 2, Half> half_a; |
| 93 | BitField<31, 2, Half> half_c; | ||
| 94 | BitField<33, 2, Half> half_b; | 96 | BitField<33, 2, Half> half_b; |
| 95 | } iadd3{insn}; | 97 | BitField<31, 2, Half> half_c; |
| 98 | } const iadd3{insn}; | ||
| 99 | |||
| 96 | const auto op_a{IntegerHalf(ir, GetReg8(insn), iadd3.half_a)}; | 100 | const auto op_a{IntegerHalf(ir, GetReg8(insn), iadd3.half_a)}; |
| 97 | const auto op_b{IntegerHalf(ir, GetReg20(insn), iadd3.half_b)}; | 101 | const auto op_b{IntegerHalf(ir, GetReg20(insn), iadd3.half_b)}; |
| 98 | const auto op_c{IntegerHalf(ir, GetReg39(insn), iadd3.half_c)}; | 102 | const auto op_c{IntegerHalf(ir, GetReg39(insn), iadd3.half_c)}; |
| 99 | IADD3(*this, insn, op_a, op_b, op_c); | 103 | IADD3(*this, insn, op_a, op_b, op_c, iadd3.shift); |
| 100 | } | 104 | } |
| 101 | 105 | ||
| 102 | void TranslatorVisitor::IADD3_cbuf(u64 insn) { | 106 | void TranslatorVisitor::IADD3_cbuf(u64 insn) { |