summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/translate
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h3
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp42
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp41
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp12
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
10 files changed, 93 insertions, 38 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
index 3da37a2bb..fd73f656c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h
@@ -46,7 +46,8 @@ inline IR::FmzMode CastFmzMode(FmzMode fmz_mode) {
46 case FmzMode::FTZ: 46 case FmzMode::FTZ:
47 return IR::FmzMode::FTZ; 47 return IR::FmzMode::FTZ;
48 case FmzMode::FMZ: 48 case FmzMode::FMZ:
49 return IR::FmzMode::FMZ; 49 // FMZ is manually handled in the instruction
50 return IR::FmzMode::FTZ;
50 case FmzMode::INVALIDFMZ3: 51 case FmzMode::INVALIDFMZ3:
51 break; 52 break;
52 } 53 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
index 219ffcc6a..76a807d4e 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp
@@ -53,7 +53,7 @@ void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
53} // Anonymous namespace 53} // Anonymous namespace
54 54
55void TranslatorVisitor::FADD_reg(u64 insn) { 55void TranslatorVisitor::FADD_reg(u64 insn) {
56 FADD(*this, insn, GetRegFloat20(insn)); 56 FADD(*this, insn, GetFloatReg20(insn));
57} 57}
58 58
59void TranslatorVisitor::FADD_cbuf(u64 insn) { 59void TranslatorVisitor::FADD_cbuf(u64 insn) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
index 758700d3c..c2ca0873b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp
@@ -51,7 +51,7 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s
51} // Anonymous namespace 51} // Anonymous namespace
52 52
53void TranslatorVisitor::FFMA_reg(u64 insn) { 53void TranslatorVisitor::FFMA_reg(u64 insn) {
54 FFMA(*this, insn, GetRegFloat20(insn), GetRegFloat39(insn)); 54 FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn));
55} 55}
56 56
57void TranslatorVisitor::FFMA_rc(u64) { 57void TranslatorVisitor::FFMA_rc(u64) {
@@ -59,7 +59,7 @@ void TranslatorVisitor::FFMA_rc(u64) {
59} 59}
60 60
61void TranslatorVisitor::FFMA_cr(u64 insn) { 61void TranslatorVisitor::FFMA_cr(u64 insn) {
62 FFMA(*this, insn, GetFloatCbuf(insn), GetRegFloat39(insn)); 62 FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn));
63} 63}
64 64
65void TranslatorVisitor::FFMA_imm(u64) { 65void TranslatorVisitor::FFMA_imm(u64) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
index ba005fbf4..2f8605619 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp
@@ -10,7 +10,7 @@
10 10
11namespace Shader::Maxwell { 11namespace Shader::Maxwell {
12namespace { 12namespace {
13enum class Operation { 13enum class Operation : u64 {
14 Cos = 0, 14 Cos = 0,
15 Sin = 1, 15 Sin = 1,
16 Ex2 = 2, // Base 2 exponent 16 Ex2 = 2, // Base 2 exponent
@@ -39,11 +39,11 @@ void TranslatorVisitor::MUFU(u64 insn) {
39 IR::F32 value{[&]() -> IR::F32 { 39 IR::F32 value{[&]() -> IR::F32 {
40 switch (mufu.operation) { 40 switch (mufu.operation) {
41 case Operation::Cos: 41 case Operation::Cos:
42 return ir.FPCosNotReduced(op_a); 42 return ir.FPCos(op_a);
43 case Operation::Sin: 43 case Operation::Sin:
44 return ir.FPSinNotReduced(op_a); 44 return ir.FPSin(op_a);
45 case Operation::Ex2: 45 case Operation::Ex2:
46 return ir.FPExp2NotReduced(op_a); 46 return ir.FPExp2(op_a);
47 case Operation::Lg2: 47 case Operation::Lg2:
48 return ir.FPLog2(op_a); 48 return ir.FPLog2(op_a);
49 case Operation::Rcp: 49 case Operation::Rcp:
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
index 5c38d3fc1..edf2cadae 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp
@@ -55,9 +55,6 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode
55 if (cc) { 55 if (cc) {
56 throw NotImplementedException("FMUL CC"); 56 throw NotImplementedException("FMUL CC");
57 } 57 }
58 if (sat) {
59 throw NotImplementedException("FMUL SAT");
60 }
61 IR::F32 op_a{v.F(fmul.src_a)}; 58 IR::F32 op_a{v.F(fmul.src_a)};
62 if (scale != Scale::None) { 59 if (scale != Scale::None) {
63 if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) { 60 if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) {
@@ -71,7 +68,20 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode
71 .rounding{CastFpRounding(fp_rounding)}, 68 .rounding{CastFpRounding(fp_rounding)},
72 .fmz_mode{CastFmzMode(fmz_mode)}, 69 .fmz_mode{CastFmzMode(fmz_mode)},
73 }; 70 };
74 v.F(fmul.dest_reg, v.ir.FPMul(op_a, op_b, fp_control)); 71 IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)};
72 if (fmz_mode == FmzMode::FMZ && !sat) {
73 // Do not implement FMZ if SAT is enabled, as it does the logic for us.
74 // On D3D9 mode, anything * 0 is zero, even NAN and infinity
75 const IR::F32 zero{v.ir.Imm32(0.0f)};
76 const IR::U1 zero_a{v.ir.FPEqual(op_a, zero)};
77 const IR::U1 zero_b{v.ir.FPEqual(op_b, zero)};
78 const IR::U1 any_zero{v.ir.LogicalOr(zero_a, zero_b)};
79 value = IR::F32{v.ir.Select(any_zero, zero, value)};
80 }
81 if (sat) {
82 value = v.ir.FPSaturate(value);
83 }
84 v.F(fmul.dest_reg, value);
75} 85}
76 86
77void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { 87void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
@@ -83,27 +93,33 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
83 BitField<47, 1, u64> cc; 93 BitField<47, 1, u64> cc;
84 BitField<48, 1, u64> neg_b; 94 BitField<48, 1, u64> neg_b;
85 BitField<50, 1, u64> sat; 95 BitField<50, 1, u64> sat;
86 } fmul{insn}; 96 } const fmul{insn};
87
88 FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0, 97 FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0,
89 fmul.neg_b != 0); 98 fmul.neg_b != 0);
90} 99}
91} // Anonymous namespace 100} // Anonymous namespace
92 101
93void TranslatorVisitor::FMUL_reg(u64 insn) { 102void TranslatorVisitor::FMUL_reg(u64 insn) {
94 return FMUL(*this, insn, GetRegFloat20(insn)); 103 return FMUL(*this, insn, GetFloatReg20(insn));
95} 104}
96 105
97void TranslatorVisitor::FMUL_cbuf(u64) { 106void TranslatorVisitor::FMUL_cbuf(u64 insn) {
98 throw NotImplementedException("FMUL (cbuf)"); 107 return FMUL(*this, insn, GetFloatCbuf(insn));
99} 108}
100 109
101void TranslatorVisitor::FMUL_imm(u64) { 110void TranslatorVisitor::FMUL_imm(u64 insn) {
102 throw NotImplementedException("FMUL (imm)"); 111 return FMUL(*this, insn, GetFloatImm20(insn));
103} 112}
104 113
105void TranslatorVisitor::FMUL32I(u64) { 114void TranslatorVisitor::FMUL32I(u64 insn) {
106 throw NotImplementedException("FMUL32I"); 115 union {
116 u64 raw;
117 BitField<52, 1, u64> cc;
118 BitField<53, 2, FmzMode> fmz;
119 BitField<55, 1, u64> sat;
120 } const fmul32i{insn};
121 FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None,
122 fmul32i.sat != 0, fmul32i.cc != 0, false);
107} 123}
108 124
109} // namespace Shader::Maxwell \ No newline at end of file 125} // namespace Shader::Maxwell \ No newline at end of file
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp
new file mode 100644
index 000000000..f91b93fad
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp
@@ -0,0 +1,41 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/bit_field.h"
6#include "common/common_types.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
8
9namespace Shader::Maxwell {
10namespace {
11enum class Mode : u64 {
12 SINCOS,
13 EX2,
14};
15
16void RRO(TranslatorVisitor& v, u64 insn, const IR::F32& src) {
17 union {
18 u64 raw;
19 BitField<0, 8, IR::Reg> dest_reg;
20 BitField<39, 1, Mode> mode;
21 BitField<45, 1, u64> neg;
22 BitField<49, 1, u64> abs;
23 } const rro{insn};
24
25 v.F(rro.dest_reg, v.ir.FPAbsNeg(src, rro.abs != 0, rro.neg != 0));
26}
27} // Anonymous namespace
28
29void TranslatorVisitor::RRO_reg(u64 insn) {
30 RRO(*this, insn, GetFloatReg20(insn));
31}
32
33void TranslatorVisitor::RRO_cbuf(u64 insn) {
34 RRO(*this, insn, GetFloatCbuf(insn));
35}
36
37void TranslatorVisitor::RRO_imm(u64) {
38 throw NotImplementedException("RRO (imm)");
39}
40
41} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
index 165d475b9..a5a0e1a9b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp
@@ -48,11 +48,11 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) {
48 return X(reg.index); 48 return X(reg.index);
49} 49}
50 50
51IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) { 51IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) {
52 return ir.BitCast<IR::F32>(GetReg20(insn)); 52 return ir.BitCast<IR::F32>(GetReg20(insn));
53} 53}
54 54
55IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) { 55IR::F32 TranslatorVisitor::GetFloatReg39(u64 insn) {
56 return ir.BitCast<IR::F32>(GetReg39(insn)); 56 return ir.BitCast<IR::F32>(GetReg39(insn));
57} 57}
58 58
@@ -110,6 +110,14 @@ IR::U32 TranslatorVisitor::GetImm32(u64 insn) {
110 return ir.Imm32(static_cast<u32>(imm.value)); 110 return ir.Imm32(static_cast<u32>(imm.value));
111} 111}
112 112
113IR::F32 TranslatorVisitor::GetFloatImm32(u64 insn) {
114 union {
115 u64 raw;
116 BitField<20, 32, u64> value;
117 } const imm{insn};
118 return ir.Imm32(Common::BitCast<f32>(static_cast<u32>(imm.value)));
119}
120
113void TranslatorVisitor::SetZFlag(const IR::U1& value) { 121void TranslatorVisitor::SetZFlag(const IR::U1& value) {
114 ir.SetZFlag(value); 122 ir.SetZFlag(value);
115} 123}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index 4d4cf2ebf..4e722e205 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -304,8 +304,8 @@ public:
304 [[nodiscard]] IR::U32 GetReg8(u64 insn); 304 [[nodiscard]] IR::U32 GetReg8(u64 insn);
305 [[nodiscard]] IR::U32 GetReg20(u64 insn); 305 [[nodiscard]] IR::U32 GetReg20(u64 insn);
306 [[nodiscard]] IR::U32 GetReg39(u64 insn); 306 [[nodiscard]] IR::U32 GetReg39(u64 insn);
307 [[nodiscard]] IR::F32 GetRegFloat20(u64 insn); 307 [[nodiscard]] IR::F32 GetFloatReg20(u64 insn);
308 [[nodiscard]] IR::F32 GetRegFloat39(u64 insn); 308 [[nodiscard]] IR::F32 GetFloatReg39(u64 insn);
309 309
310 [[nodiscard]] IR::U32 GetCbuf(u64 insn); 310 [[nodiscard]] IR::U32 GetCbuf(u64 insn);
311 [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn); 311 [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn);
@@ -314,6 +314,7 @@ public:
314 [[nodiscard]] IR::F32 GetFloatImm20(u64 insn); 314 [[nodiscard]] IR::F32 GetFloatImm20(u64 insn);
315 315
316 [[nodiscard]] IR::U32 GetImm32(u64 insn); 316 [[nodiscard]] IR::U32 GetImm32(u64 insn);
317 [[nodiscard]] IR::F32 GetFloatImm32(u64 insn);
317 318
318 void SetZFlag(const IR::U1& value); 319 void SetZFlag(const IR::U1& value);
319 void SetSFlag(const IR::U1& value); 320 void SetSFlag(const IR::U1& value);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
index d8a5158b5..20af68852 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp
@@ -50,7 +50,7 @@ void SHL(TranslatorVisitor& v, u64 insn, const IR::U32& unsafe_shift) {
50 // 50 //
51 const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)}; 51 const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)};
52 const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)}; 52 const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)};
53 result = v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0)); 53 result = IR::U32{v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0))};
54 } 54 }
55 v.X(shl.dest_reg, result); 55 v.X(shl.dest_reg, result);
56} 56}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
index 628cf1c14..4114e10be 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -721,18 +721,6 @@ void TranslatorVisitor::RET(u64) {
721 ThrowNotImplemented(Opcode::RET); 721 ThrowNotImplemented(Opcode::RET);
722} 722}
723 723
724void TranslatorVisitor::RRO_reg(u64) {
725 ThrowNotImplemented(Opcode::RRO_reg);
726}
727
728void TranslatorVisitor::RRO_cbuf(u64) {
729 ThrowNotImplemented(Opcode::RRO_cbuf);
730}
731
732void TranslatorVisitor::RRO_imm(u64) {
733 ThrowNotImplemented(Opcode::RRO_imm);
734}
735
736void TranslatorVisitor::RTT(u64) { 724void TranslatorVisitor::RTT(u64) {
737 ThrowNotImplemented(Opcode::RTT); 725 ThrowNotImplemented(Opcode::RTT);
738} 726}