summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp54
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h7
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp64
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set.cpp41
9 files changed, 88 insertions, 101 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 035fd34e2..057857299 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -89,6 +89,7 @@ add_library(shader_recompiler STATIC
89 frontend/maxwell/translate/impl/move_register.cpp 89 frontend/maxwell/translate/impl/move_register.cpp
90 frontend/maxwell/translate/impl/move_special_register.cpp 90 frontend/maxwell/translate/impl/move_special_register.cpp
91 frontend/maxwell/translate/impl/not_implemented.cpp 91 frontend/maxwell/translate/impl/not_implemented.cpp
92 frontend/maxwell/translate/impl/predicate_set.cpp
92 frontend/maxwell/translate/impl/select_source_with_predicate.cpp 93 frontend/maxwell/translate/impl/select_source_with_predicate.cpp
93 frontend/maxwell/translate/translate.cpp 94 frontend/maxwell/translate/translate.cpp
94 frontend/maxwell/translate/translate.h 95 frontend/maxwell/translate/translate.h
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 3ec146b1a..62f825a92 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
@@ -5,42 +5,42 @@
5#include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h" 5#include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h"
6 6
7namespace Shader::Maxwell { 7namespace Shader::Maxwell {
8[[nodiscard]] IR::U1 IntegerCompare(TranslatorVisitor& v, const IR::U32& operand_1, 8[[nodiscard]] IR::U1 IntegerCompare(IR::IREmitter& ir, const IR::U32& operand_1,
9 const IR::U32& operand_2, ComparisonOp compare_op, 9 const IR::U32& operand_2, CompareOp compare_op,
10 bool is_signed) { 10 bool is_signed) {
11 switch (compare_op) { 11 switch (compare_op) {
12 case ComparisonOp::False: 12 case CompareOp::False:
13 return v.ir.Imm1(false); 13 return ir.Imm1(false);
14 case ComparisonOp::LessThan: 14 case CompareOp::LessThan:
15 return v.ir.ILessThan(operand_1, operand_2, is_signed); 15 return ir.ILessThan(operand_1, operand_2, is_signed);
16 case ComparisonOp::Equal: 16 case CompareOp::Equal:
17 return v.ir.IEqual(operand_1, operand_2); 17 return ir.IEqual(operand_1, operand_2);
18 case ComparisonOp::LessThanEqual: 18 case CompareOp::LessThanEqual:
19 return v.ir.ILessThanEqual(operand_1, operand_2, is_signed); 19 return ir.ILessThanEqual(operand_1, operand_2, is_signed);
20 case ComparisonOp::GreaterThan: 20 case CompareOp::GreaterThan:
21 return v.ir.IGreaterThan(operand_1, operand_2, is_signed); 21 return ir.IGreaterThan(operand_1, operand_2, is_signed);
22 case ComparisonOp::NotEqual: 22 case CompareOp::NotEqual:
23 return v.ir.INotEqual(operand_1, operand_2); 23 return ir.INotEqual(operand_1, operand_2);
24 case ComparisonOp::GreaterThanEqual: 24 case CompareOp::GreaterThanEqual:
25 return v.ir.IGreaterThanEqual(operand_1, operand_2, is_signed); 25 return ir.IGreaterThanEqual(operand_1, operand_2, is_signed);
26 case ComparisonOp::True: 26 case CompareOp::True:
27 return v.ir.Imm1(true); 27 return ir.Imm1(true);
28 default: 28 default:
29 throw NotImplementedException("CMP"); 29 throw NotImplementedException("Invalid compare op {}", compare_op);
30 } 30 }
31} 31}
32 32
33[[nodiscard]] IR::U1 PredicateCombine(TranslatorVisitor& v, const IR::U1& predicate_1, 33[[nodiscard]] IR::U1 PredicateCombine(IR::IREmitter& ir, const IR::U1& predicate_1,
34 const IR::U1& predicate_2, BooleanOp bop) { 34 const IR::U1& predicate_2, BooleanOp bop) {
35 switch (bop) { 35 switch (bop) {
36 case BooleanOp::And: 36 case BooleanOp::AND:
37 return v.ir.LogicalAnd(predicate_1, predicate_2); 37 return ir.LogicalAnd(predicate_1, predicate_2);
38 case BooleanOp::Or: 38 case BooleanOp::OR:
39 return v.ir.LogicalOr(predicate_1, predicate_2); 39 return ir.LogicalOr(predicate_1, predicate_2);
40 case BooleanOp::Xor: 40 case BooleanOp::XOR:
41 return v.ir.LogicalXor(predicate_1, predicate_2); 41 return ir.LogicalXor(predicate_1, predicate_2);
42 default: 42 default:
43 throw NotImplementedException("BOP"); 43 throw NotImplementedException("Invalid bop {}", bop);
44 } 44 }
45} 45}
46} // namespace Shader::Maxwell 46} // 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 293fcce2e..61e13fa18 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
@@ -8,10 +8,9 @@
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" 8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9 9
10namespace Shader::Maxwell { 10namespace Shader::Maxwell {
11[[nodiscard]] IR::U1 IntegerCompare(TranslatorVisitor& v, const IR::U32& operand_1, 11[[nodiscard]] IR::U1 IntegerCompare(IR::IREmitter& ir, const IR::U32& operand_1,
12 const IR::U32& operand_2, ComparisonOp compare_op, 12 const IR::U32& operand_2, CompareOp compare_op, bool is_signed);
13 bool is_signed);
14 13
15[[nodiscard]] IR::U1 PredicateCombine(TranslatorVisitor& v, const IR::U1& predicate_1, 14[[nodiscard]] IR::U1 PredicateCombine(IR::IREmitter& ir, const IR::U1& predicate_1,
16 const IR::U1& predicate_2, BooleanOp bop); 15 const IR::U1& predicate_2, BooleanOp bop);
17} // namespace Shader::Maxwell 16} // 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 232f8c894..ad09ade7c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -11,7 +11,7 @@
11 11
12namespace Shader::Maxwell { 12namespace Shader::Maxwell {
13 13
14enum class ComparisonOp : u64 { 14enum class CompareOp : u64 {
15 False, 15 False,
16 LessThan, 16 LessThan,
17 Equal, 17 Equal,
@@ -23,9 +23,9 @@ enum class ComparisonOp : u64 {
23}; 23};
24 24
25enum class BooleanOp : u64 { 25enum class BooleanOp : u64 {
26 And, 26 AND,
27 Or, 27 OR,
28 Xor, 28 XOR,
29}; 29};
30 30
31class TranslatorVisitor { 31class TranslatorVisitor {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp
index d844974d8..ba6e01926 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp
@@ -15,12 +15,12 @@ void ICMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& o
15 BitField<0, 8, IR::Reg> dest_reg; 15 BitField<0, 8, IR::Reg> dest_reg;
16 BitField<8, 8, IR::Reg> src_reg; 16 BitField<8, 8, IR::Reg> src_reg;
17 BitField<48, 1, u64> is_signed; 17 BitField<48, 1, u64> is_signed;
18 BitField<49, 3, ComparisonOp> compare_op; 18 BitField<49, 3, CompareOp> compare_op;
19 } const icmp{insn}; 19 } const icmp{insn};
20 20
21 const IR::U32 zero{v.ir.Imm32(0)}; 21 const IR::U32 zero{v.ir.Imm32(0)};
22 const bool is_signed{icmp.is_signed != 0}; 22 const bool is_signed{icmp.is_signed != 0};
23 const IR::U1 cmp_result{IntegerCompare(v, operand, zero, icmp.compare_op, is_signed)}; 23 const IR::U1 cmp_result{IntegerCompare(v.ir, operand, zero, icmp.compare_op, is_signed)};
24 24
25 const IR::U32 src_reg{v.X(icmp.src_reg)}; 25 const IR::U32 src_reg{v.X(icmp.src_reg)};
26 const IR::U32 result{v.ir.Select(cmp_result, src_reg, src_a)}; 26 const IR::U32 result{v.ir.Select(cmp_result, src_reg, src_a)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp
index b6a7b593d..914af010f 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp
@@ -20,7 +20,7 @@ void ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
20 BitField<44, 1, u64> bf; 20 BitField<44, 1, u64> bf;
21 BitField<45, 2, BooleanOp> bop; 21 BitField<45, 2, BooleanOp> bop;
22 BitField<48, 1, u64> is_signed; 22 BitField<48, 1, u64> is_signed;
23 BitField<49, 3, ComparisonOp> compare_op; 23 BitField<49, 3, CompareOp> compare_op;
24 } const iset{insn}; 24 } const iset{insn};
25 25
26 if (iset.x != 0) { 26 if (iset.x != 0) {
@@ -33,8 +33,8 @@ void ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
33 if (iset.neg_pred != 0) { 33 if (iset.neg_pred != 0) {
34 pred = v.ir.LogicalNot(pred); 34 pred = v.ir.LogicalNot(pred);
35 } 35 }
36 const IR::U1 cmp_result{IntegerCompare(v, src_reg, src_a, iset.compare_op, is_signed)}; 36 const IR::U1 cmp_result{IntegerCompare(v.ir, src_reg, src_a, iset.compare_op, is_signed)};
37 const IR::U1 bop_result{PredicateCombine(v, cmp_result, pred, iset.bop)}; 37 const IR::U1 bop_result{PredicateCombine(v.ir, cmp_result, pred, iset.bop)};
38 38
39 const IR::U32 one_mask{v.ir.Imm32(-1)}; 39 const IR::U32 one_mask{v.ir.Imm32(-1)};
40 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)}; 40 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
index 1bc9ef363..7743701d0 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
@@ -4,62 +4,11 @@
4 4
5#include "common/bit_field.h" 5#include "common/bit_field.h"
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" 8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
8 9
9namespace Shader::Maxwell { 10namespace Shader::Maxwell {
10namespace { 11namespace {
11enum class CompareOp : u64 {
12 F, // Always false
13 LT, // Less than
14 EQ, // Equal
15 LE, // Less than or equal
16 GT, // Greater than
17 NE, // Not equal
18 GE, // Greater than or equal
19 T, // Always true
20};
21
22enum class Bop : u64 {
23 AND,
24 OR,
25 XOR,
26};
27
28IR::U1 Compare(IR::IREmitter& ir, CompareOp op, const IR::U32& lhs, const IR::U32& rhs,
29 bool is_signed) {
30 switch (op) {
31 case CompareOp::F:
32 return ir.Imm1(false);
33 case CompareOp::LT:
34 return ir.ILessThan(lhs, rhs, is_signed);
35 case CompareOp::EQ:
36 return ir.IEqual(lhs, rhs);
37 case CompareOp::LE:
38 return ir.ILessThanEqual(lhs, rhs, is_signed);
39 case CompareOp::GT:
40 return ir.IGreaterThan(lhs, rhs, is_signed);
41 case CompareOp::NE:
42 return ir.INotEqual(lhs, rhs);
43 case CompareOp::GE:
44 return ir.IGreaterThanEqual(lhs, rhs, is_signed);
45 case CompareOp::T:
46 return ir.Imm1(true);
47 }
48 throw NotImplementedException("Invalid ISETP compare op {}", op);
49}
50
51IR::U1 Combine(IR::IREmitter& ir, Bop bop, const IR::U1& comparison, const IR::U1& bop_pred) {
52 switch (bop) {
53 case Bop::AND:
54 return ir.LogicalAnd(comparison, bop_pred);
55 case Bop::OR:
56 return ir.LogicalOr(comparison, bop_pred);
57 case Bop::XOR:
58 return ir.LogicalXor(comparison, bop_pred);
59 }
60 throw NotImplementedException("Invalid ISETP bop {}", bop);
61}
62
63void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) { 12void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
64 union { 13 union {
65 u64 raw; 14 u64 raw;
@@ -68,17 +17,18 @@ void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
68 BitField<8, 8, IR::Reg> src_reg_a; 17 BitField<8, 8, IR::Reg> src_reg_a;
69 BitField<39, 3, IR::Pred> bop_pred; 18 BitField<39, 3, IR::Pred> bop_pred;
70 BitField<42, 1, u64> neg_bop_pred; 19 BitField<42, 1, u64> neg_bop_pred;
71 BitField<45, 2, Bop> bop; 20 BitField<45, 2, BooleanOp> bop;
72 BitField<48, 1, u64> is_signed; 21 BitField<48, 1, u64> is_signed;
73 BitField<49, 3, CompareOp> compare_op; 22 BitField<49, 3, CompareOp> compare_op;
74 } const isetp{insn}; 23 } const isetp{insn};
75 24
76 const Bop bop{isetp.bop}; 25 const BooleanOp bop{isetp.bop};
26 const CompareOp compare_op{isetp.compare_op};
77 const IR::U32 op_a{v.X(isetp.src_reg_a)}; 27 const IR::U32 op_a{v.X(isetp.src_reg_a)};
78 const IR::U1 comparison{Compare(v.ir, isetp.compare_op, op_a, op_b, isetp.is_signed != 0)}; 28 const IR::U1 comparison{IntegerCompare(v.ir, op_a, op_b, compare_op, isetp.is_signed != 0)};
79 const IR::U1 bop_pred{v.ir.GetPred(isetp.bop_pred, isetp.neg_bop_pred != 0)}; 29 const IR::U1 bop_pred{v.ir.GetPred(isetp.bop_pred, isetp.neg_bop_pred != 0)};
80 const IR::U1 result_a{Combine(v.ir, bop, comparison, bop_pred)}; 30 const IR::U1 result_a{PredicateCombine(v.ir, comparison, bop_pred, bop)};
81 const IR::U1 result_b{Combine(v.ir, bop, v.ir.LogicalNot(comparison), bop_pred)}; 31 const IR::U1 result_b{PredicateCombine(v.ir, v.ir.LogicalNot(comparison), bop_pred, bop)};
82 v.ir.SetPred(isetp.dest_pred_a, result_a); 32 v.ir.SetPred(isetp.dest_pred_a, result_a);
83 v.ir.SetPred(isetp.dest_pred_b, result_b); 33 v.ir.SetPred(isetp.dest_pred_b, result_b);
84} 34}
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 2da0b87c4..291d7a4bc 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -593,10 +593,6 @@ void TranslatorVisitor::PRMT_imm(u64) {
593 ThrowNotImplemented(Opcode::PRMT_imm); 593 ThrowNotImplemented(Opcode::PRMT_imm);
594} 594}
595 595
596void TranslatorVisitor::PSET(u64) {
597 ThrowNotImplemented(Opcode::PSET);
598}
599
600void TranslatorVisitor::PSETP(u64) { 596void TranslatorVisitor::PSETP(u64) {
601 ThrowNotImplemented(Opcode::PSETP); 597 ThrowNotImplemented(Opcode::PSETP);
602} 598}
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set.cpp
new file mode 100644
index 000000000..6c15963fa
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set.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/common_funcs.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9
10namespace Shader::Maxwell {
11void TranslatorVisitor::PSET(u64 insn) {
12 union {
13 u64 raw;
14 BitField<0, 8, IR::Reg> dest_reg;
15 BitField<12, 3, IR::Pred> pred_a;
16 BitField<15, 1, u64> neg_pred_a;
17 BitField<24, 2, BooleanOp> bop_1;
18 BitField<29, 3, IR::Pred> pred_b;
19 BitField<32, 1, u64> neg_pred_b;
20 BitField<39, 3, IR::Pred> pred_c;
21 BitField<42, 1, u64> neg_pred_c;
22 BitField<44, 1, u64> bf;
23 BitField<45, 2, BooleanOp> bop_2;
24 } const pset{insn};
25
26 const IR::U1 pred_a{ir.GetPred(pset.pred_a, pset.neg_pred_a != 0)};
27 const IR::U1 pred_b{ir.GetPred(pset.pred_b, pset.neg_pred_b != 0)};
28 const IR::U1 pred_c{ir.GetPred(pset.pred_c, pset.neg_pred_c != 0)};
29
30 const IR::U1 res_1{PredicateCombine(ir, pred_a, pred_b, pset.bop_1)};
31 const IR::U1 res_2{PredicateCombine(ir, res_1, pred_c, pset.bop_2)};
32
33 const IR::U32 true_result{pset.bf != 0 ? ir.Imm32(0x3f800000) : ir.Imm32(-1)};
34 const IR::U32 false_result{ir.Imm32(0)};
35
36 const IR::U32 result{ir.Select(res_2, true_result, false_result)};
37
38 X(pset.dest_reg, result);
39}
40
41} // namespace Shader::Maxwell