summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp24
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
45void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 op_c) { 47void 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
89void TranslatorVisitor::IADD3_reg(u64 insn) { 91void 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
102void TranslatorVisitor::IADD3_cbuf(u64 insn) { 106void TranslatorVisitor::IADD3_cbuf(u64 insn) {