summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp48
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp68
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp65
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp60
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h19
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp24
7 files changed, 198 insertions, 92 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
index 9d4ac2e36..af9a8f82c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
@@ -58,4 +58,52 @@ IR::U1 PredicateOperation(IR::IREmitter& ir, const IR::U32& result, PredicateOp
58 } 58 }
59} 59}
60 60
61bool IsCompareOpOrdered(FPCompareOp op) {
62 switch (op) {
63 case FPCompareOp::LTU:
64 case FPCompareOp::EQU:
65 case FPCompareOp::LEU:
66 case FPCompareOp::GTU:
67 case FPCompareOp::NEU:
68 case FPCompareOp::GEU:
69 return false;
70 default:
71 return true;
72 }
73}
74
75IR::U1 FloatingPointCompare(IR::IREmitter& ir, const IR::F32& operand_1, const IR::F32& operand_2,
76 FPCompareOp compare_op, IR::FpControl control) {
77 const bool ordered{IsCompareOpOrdered(compare_op)};
78 switch (compare_op) {
79 case FPCompareOp::F:
80 return ir.Imm1(false);
81 case FPCompareOp::LT:
82 case FPCompareOp::LTU:
83 return ir.FPLessThan(operand_1, operand_2, control, ordered);
84 case FPCompareOp::EQ:
85 case FPCompareOp::EQU:
86 return ir.FPEqual(operand_1, operand_2, control, ordered);
87 case FPCompareOp::LE:
88 case FPCompareOp::LEU:
89 return ir.FPLessThanEqual(operand_1, operand_2, control, ordered);
90 case FPCompareOp::GT:
91 case FPCompareOp::GTU:
92 return ir.FPGreaterThan(operand_1, operand_2, control, ordered);
93 case FPCompareOp::NE:
94 case FPCompareOp::NEU:
95 return ir.FPNotEqual(operand_1, operand_2, control, ordered);
96 case FPCompareOp::GE:
97 case FPCompareOp::GEU:
98 return ir.FPGreaterThanEqual(operand_1, operand_2, control, ordered);
99 case FPCompareOp::NUM:
100 return ir.FPOrdered(operand_1, operand_2);
101 case FPCompareOp::Nan:
102 return ir.FPUnordered(operand_1, operand_2);
103 case FPCompareOp::T:
104 return ir.Imm1(true);
105 default:
106 throw NotImplementedException("Invalid FP compare op {}", compare_op);
107 }
108}
61} // namespace Shader::Maxwell 109} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
index c9ae5c500..f8add3c34 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
@@ -15,4 +15,10 @@ namespace Shader::Maxwell {
15 const IR::U1& predicate_2, BooleanOp bop); 15 const IR::U1& predicate_2, BooleanOp bop);
16 16
17[[nodiscard]] IR::U1 PredicateOperation(IR::IREmitter& ir, const IR::U32& result, PredicateOp op); 17[[nodiscard]] IR::U1 PredicateOperation(IR::IREmitter& ir, const IR::U32& result, PredicateOp op);
18
19[[nodiscard]] bool IsCompareOpOrdered(FPCompareOp op);
20
21[[nodiscard]] IR::U1 FloatingPointCompare(IR::IREmitter& ir, const IR::F32& operand_1,
22 const IR::F32& operand_2, FPCompareOp compare_op,
23 IR::FpControl control = {});
18} // namespace Shader::Maxwell 24} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
index f254ecb3a..e78e9c4e1 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare.cpp
@@ -9,74 +9,6 @@
9 9
10namespace Shader::Maxwell { 10namespace Shader::Maxwell {
11namespace { 11namespace {
12enum class FPCompareOp : u64 {
13 F,
14 LT,
15 EQ,
16 LE,
17 GT,
18 NE,
19 GE,
20 NUM,
21 Nan,
22 LTU,
23 EQU,
24 LEU,
25 GTU,
26 NEU,
27 GEU,
28 T,
29};
30
31bool IsCompareOpOrdered(FPCompareOp op) {
32 switch (op) {
33 case FPCompareOp::LTU:
34 case FPCompareOp::EQU:
35 case FPCompareOp::LEU:
36 case FPCompareOp::GTU:
37 case FPCompareOp::NEU:
38 case FPCompareOp::GEU:
39 return false;
40 default:
41 return true;
42 }
43}
44
45IR::U1 FloatingPointCompare(IR::IREmitter& ir, const IR::F32& operand_1, const IR::F32& operand_2,
46 FPCompareOp compare_op, IR::FpControl control) {
47 const bool ordered{IsCompareOpOrdered(compare_op)};
48 switch (compare_op) {
49 case FPCompareOp::F:
50 return ir.Imm1(false);
51 case FPCompareOp::LT:
52 case FPCompareOp::LTU:
53 return ir.FPLessThan(operand_1, operand_2, control, ordered);
54 case FPCompareOp::EQ:
55 case FPCompareOp::EQU:
56 return ir.FPEqual(operand_1, operand_2, control, ordered);
57 case FPCompareOp::LE:
58 case FPCompareOp::LEU:
59 return ir.FPLessThanEqual(operand_1, operand_2, control, ordered);
60 case FPCompareOp::GT:
61 case FPCompareOp::GTU:
62 return ir.FPGreaterThan(operand_1, operand_2, control, ordered);
63 case FPCompareOp::NE:
64 case FPCompareOp::NEU:
65 return ir.FPNotEqual(operand_1, operand_2, control, ordered);
66 case FPCompareOp::GE:
67 case FPCompareOp::GEU:
68 return ir.FPGreaterThanEqual(operand_1, operand_2, control, ordered);
69 case FPCompareOp::NUM:
70 return ir.FPOrdered(operand_1, operand_2);
71 case FPCompareOp::Nan:
72 return ir.FPUnordered(operand_1, operand_2);
73 case FPCompareOp::T:
74 return ir.Imm1(true);
75 default:
76 throw NotImplementedException("Invalid compare op {}", compare_op);
77 }
78}
79
80void FCMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::F32& operand) { 12void FCMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::F32& operand) {
81 union { 13 union {
82 u64 insn; 14 u64 insn;
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp
new file mode 100644
index 000000000..c5417775e
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp
@@ -0,0 +1,65 @@
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/common_funcs.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9
10namespace Shader::Maxwell {
11namespace {
12void FSET(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
13 union {
14 u64 insn;
15 BitField<0, 8, IR::Reg> dest_reg;
16 BitField<8, 8, IR::Reg> src_a_reg;
17 BitField<39, 3, IR::Pred> pred;
18 BitField<42, 1, u64> neg_pred;
19 BitField<43, 1, u64> negate_a;
20 BitField<44, 1, u64> abs_b;
21 BitField<45, 2, BooleanOp> bop;
22 BitField<48, 4, FPCompareOp> compare_op;
23 BitField<52, 1, u64> bf;
24 BitField<53, 1, u64> negate_b;
25 BitField<54, 1, u64> abs_a;
26 BitField<55, 1, u64> ftz;
27 } const fset{insn};
28
29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fset.src_a_reg), fset.abs_a != 0, fset.negate_a != 0)};
30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fset.abs_b != 0, fset.negate_b != 0);
31 const IR::FpControl control{
32 .no_contraction{false},
33 .rounding{IR::FpRounding::DontCare},
34 .fmz_mode{fset.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None},
35 };
36
37 IR::U1 pred{v.ir.GetPred(fset.pred)};
38 if (fset.neg_pred != 0) {
39 pred = v.ir.LogicalNot(pred);
40 }
41 const IR::U1 cmp_result{FloatingPointCompare(v.ir, op_a, op_b, fset.compare_op, control)};
42 const IR::U1 bop_result{PredicateCombine(v.ir, cmp_result, pred, fset.bop)};
43
44 const IR::U32 one_mask{v.ir.Imm32(-1)};
45 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
46 const IR::U32 fail_result{v.ir.Imm32(0)};
47 const IR::U32 pass_result{fset.bf == 0 ? one_mask : fp_one};
48
49 v.X(fset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)});
50}
51} // Anonymous namespace
52
53void TranslatorVisitor::FSET_reg(u64 insn) {
54 FSET(*this, insn, GetFloatReg20(insn));
55}
56
57void TranslatorVisitor::FSET_cbuf(u64 insn) {
58 FSET(*this, insn, GetFloatCbuf(insn));
59}
60
61void TranslatorVisitor::FSET_imm(u64 insn) {
62 FSET(*this, insn, GetFloatImm20(insn));
63}
64
65} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
new file mode 100644
index 000000000..8ff9db843
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_set_predicate.cpp
@@ -0,0 +1,60 @@
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/common_funcs.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9
10namespace Shader::Maxwell {
11namespace {
12void FSETP(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
13 union {
14 u64 insn;
15 BitField<0, 3, IR::Pred> dest_pred_b;
16 BitField<3, 3, IR::Pred> dest_pred_a;
17 BitField<6, 1, u64> negate_b;
18 BitField<7, 1, u64> abs_a;
19 BitField<8, 8, IR::Reg> src_a_reg;
20 BitField<39, 3, IR::Pred> bop_pred;
21 BitField<42, 1, u64> neg_bop_pred;
22 BitField<43, 1, u64> negate_a;
23 BitField<44, 1, u64> abs_b;
24 BitField<45, 2, BooleanOp> bop;
25 BitField<47, 1, u64> ftz;
26 BitField<48, 4, FPCompareOp> compare_op;
27 } const fsetp{insn};
28
29 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fsetp.src_a_reg), fsetp.abs_a != 0, fsetp.negate_a != 0)};
30 const IR::F32 op_b = v.ir.FPAbsNeg(src_b, fsetp.abs_b != 0, fsetp.negate_b != 0);
31 const IR::FpControl control{
32 .no_contraction{false},
33 .rounding{IR::FpRounding::DontCare},
34 .fmz_mode{fsetp.ftz != 0 ? IR::FmzMode::FTZ : IR::FmzMode::None},
35 };
36
37 const BooleanOp bop{fsetp.bop};
38 const FPCompareOp compare_op{fsetp.compare_op};
39 const IR::U1 comparison{FloatingPointCompare(v.ir, op_a, op_b, compare_op, control)};
40 const IR::U1 bop_pred{v.ir.GetPred(fsetp.bop_pred, fsetp.neg_bop_pred != 0)};
41 const IR::U1 result_a{PredicateCombine(v.ir, comparison, bop_pred, bop)};
42 const IR::U1 result_b{PredicateCombine(v.ir, v.ir.LogicalNot(comparison), bop_pred, bop)};
43 v.ir.SetPred(fsetp.dest_pred_a, result_a);
44 v.ir.SetPred(fsetp.dest_pred_b, result_b);
45}
46} // Anonymous namespace
47
48void TranslatorVisitor::FSETP_reg(u64 insn) {
49 FSETP(*this, insn, GetFloatReg20(insn));
50}
51
52void TranslatorVisitor::FSETP_cbuf(u64 insn) {
53 FSETP(*this, insn, GetFloatCbuf(insn));
54}
55
56void TranslatorVisitor::FSETP_imm(u64 insn) {
57 FSETP(*this, insn, GetFloatImm20(insn));
58}
59
60} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
index 45d6f5e06..761b64666 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -35,6 +35,25 @@ enum class PredicateOp : u64 {
35 NonZero, 35 NonZero,
36}; 36};
37 37
38enum class FPCompareOp : u64 {
39 F,
40 LT,
41 EQ,
42 LE,
43 GT,
44 NE,
45 GE,
46 NUM,
47 Nan,
48 LTU,
49 EQU,
50 LEU,
51 GTU,
52 NEU,
53 GEU,
54 T,
55};
56
38class TranslatorVisitor { 57class TranslatorVisitor {
39public: 58public:
40 explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {} 59 explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {}
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 9aa7b836c..b31928370 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -201,30 +201,6 @@ void TranslatorVisitor::FCHK_imm(u64) {
201 ThrowNotImplemented(Opcode::FCHK_imm); 201 ThrowNotImplemented(Opcode::FCHK_imm);
202} 202}
203 203
204void TranslatorVisitor::FSET_reg(u64) {
205 ThrowNotImplemented(Opcode::FSET_reg);
206}
207
208void TranslatorVisitor::FSET_cbuf(u64) {
209 ThrowNotImplemented(Opcode::FSET_cbuf);
210}
211
212void TranslatorVisitor::FSET_imm(u64) {
213 ThrowNotImplemented(Opcode::FSET_imm);
214}
215
216void TranslatorVisitor::FSETP_reg(u64) {
217 ThrowNotImplemented(Opcode::FSETP_reg);
218}
219
220void TranslatorVisitor::FSETP_cbuf(u64) {
221 ThrowNotImplemented(Opcode::FSETP_cbuf);
222}
223
224void TranslatorVisitor::FSETP_imm(u64) {
225 ThrowNotImplemented(Opcode::FSETP_imm);
226}
227
228void TranslatorVisitor::FSWZADD(u64) { 204void TranslatorVisitor::FSWZADD(u64) {
229 ThrowNotImplemented(Opcode::FSWZADD); 205 ThrowNotImplemented(Opcode::FSWZADD);
230} 206}