summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/translate/impl
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp16
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp27
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h2
3 files changed, 24 insertions, 21 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
index bece191d7..3db09d0c2 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_add.cpp
@@ -22,19 +22,11 @@ void DADD(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
22 BitField<48, 1, u64> neg_a; 22 BitField<48, 1, u64> neg_a;
23 BitField<49, 1, u64> abs_b; 23 BitField<49, 1, u64> abs_b;
24 } const dadd{insn}; 24 } const dadd{insn};
25
26 if (!IR::IsAligned(dadd.dest_reg, 2)) {
27 throw NotImplementedException("Unaligned destination register {}", dadd.dest_reg.Value());
28 }
29 if (!IR::IsAligned(dadd.src_a_reg, 2)) {
30 throw NotImplementedException("Unaligned destination register {}", dadd.src_a_reg.Value());
31 }
32 if (dadd.cc != 0) { 25 if (dadd.cc != 0) {
33 throw NotImplementedException("DADD CC"); 26 throw NotImplementedException("DADD CC");
34 } 27 }
35 28
36 const IR::Reg reg_a{dadd.src_a_reg}; 29 const IR::F64 src_a{v.D(dadd.src_a_reg)};
37 const IR::F64 src_a{v.ir.PackDouble2x32(v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1)))};
38 const IR::F64 op_a{v.ir.FPAbsNeg(src_a, dadd.abs_a != 0, dadd.neg_a != 0)}; 30 const IR::F64 op_a{v.ir.FPAbsNeg(src_a, dadd.abs_a != 0, dadd.neg_a != 0)};
39 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dadd.abs_b != 0, dadd.neg_b != 0)}; 31 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dadd.abs_b != 0, dadd.neg_b != 0)};
40 32
@@ -43,12 +35,8 @@ void DADD(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
43 .rounding{CastFpRounding(dadd.fp_rounding)}, 35 .rounding{CastFpRounding(dadd.fp_rounding)},
44 .fmz_mode{IR::FmzMode::None}, 36 .fmz_mode{IR::FmzMode::None},
45 }; 37 };
46 const IR::F64 value{v.ir.FPAdd(op_a, op_b, control)};
47 const IR::Value result{v.ir.UnpackDouble2x32(value)};
48 38
49 for (int i = 0; i < 2; i++) { 39 v.D(dadd.dest_reg, v.ir.FPAdd(op_a, op_b, control));
50 v.X(dadd.dest_reg + i, IR::U32{v.ir.CompositeExtract(result, i)});
51 }
52} 40}
53} // Anonymous namespace 41} // Anonymous namespace
54 42
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index c9af83010..2d2f6f9c6 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -25,6 +25,13 @@ IR::F32 TranslatorVisitor::F(IR::Reg reg) {
25 return ir.BitCast<IR::F32>(X(reg)); 25 return ir.BitCast<IR::F32>(X(reg));
26} 26}
27 27
28IR::F64 TranslatorVisitor::D(IR::Reg reg) {
29 if (!IR::IsAligned(reg, 2)) {
30 throw NotImplementedException("Unaligned source register {}", reg);
31 }
32 return IR::F64{ir.PackDouble2x32(ir.CompositeConstruct(X(reg), X(reg + 1)))};
33}
34
28void TranslatorVisitor::X(IR::Reg dest_reg, const IR::U32& value) { 35void TranslatorVisitor::X(IR::Reg dest_reg, const IR::U32& value) {
29 ir.SetReg(dest_reg, value); 36 ir.SetReg(dest_reg, value);
30} 37}
@@ -33,6 +40,16 @@ void TranslatorVisitor::F(IR::Reg dest_reg, const IR::F32& value) {
33 X(dest_reg, ir.BitCast<IR::U32>(value)); 40 X(dest_reg, ir.BitCast<IR::U32>(value));
34} 41}
35 42
43void TranslatorVisitor::D(IR::Reg dest_reg, const IR::F64& value) {
44 if (!IR::IsAligned(dest_reg, 2)) {
45 throw NotImplementedException("Unaligned destination register {}", dest_reg);
46 }
47 const IR::Value result{ir.UnpackDouble2x32(value)};
48 for (int i = 0; i < 2; i++) {
49 X(dest_reg + i, IR::U32{ir.CompositeExtract(result, i)});
50 }
51}
52
36IR::U32 TranslatorVisitor::GetReg8(u64 insn) { 53IR::U32 TranslatorVisitor::GetReg8(u64 insn) {
37 union { 54 union {
38 u64 raw; 55 u64 raw;
@@ -68,13 +85,9 @@ IR::F32 TranslatorVisitor::GetFloatReg39(u64 insn) {
68IR::F64 TranslatorVisitor::GetDoubleReg20(u64 insn) { 85IR::F64 TranslatorVisitor::GetDoubleReg20(u64 insn) {
69 union { 86 union {
70 u64 raw; 87 u64 raw;
71 BitField<20, 8, IR::Reg> src; 88 BitField<20, 8, IR::Reg> index;
72 } const index{insn}; 89 } const reg{insn};
73 const IR::Reg reg{index.src}; 90 return D(reg.index);
74 if (!IR::IsAligned(reg, 2)) {
75 throw NotImplementedException("Unaligned source register {}", reg);
76 }
77 return ir.PackDouble2x32(ir.CompositeConstruct(X(reg), X(reg + 1)));
78} 91}
79 92
80static std::pair<IR::U32, IR::U32> CbufAddr(u64 insn) { 93static std::pair<IR::U32, IR::U32> CbufAddr(u64 insn) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index cb66cca25..1a1073fa7 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -342,9 +342,11 @@ public:
342 342
343 [[nodiscard]] IR::U32 X(IR::Reg reg); 343 [[nodiscard]] IR::U32 X(IR::Reg reg);
344 [[nodiscard]] IR::F32 F(IR::Reg reg); 344 [[nodiscard]] IR::F32 F(IR::Reg reg);
345 [[nodiscard]] IR::F64 D(IR::Reg reg);
345 346
346 void X(IR::Reg dest_reg, const IR::U32& value); 347 void X(IR::Reg dest_reg, const IR::U32& value);
347 void F(IR::Reg dest_reg, const IR::F32& value); 348 void F(IR::Reg dest_reg, const IR::F32& value);
349 void D(IR::Reg dest_reg, const IR::F64& value);
348 350
349 [[nodiscard]] IR::U32 GetReg8(u64 insn); 351 [[nodiscard]] IR::U32 GetReg8(u64 insn);
350 [[nodiscard]] IR::U32 GetReg20(u64 insn); 352 [[nodiscard]] IR::U32 GetReg20(u64 insn);