summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend
diff options
context:
space:
mode:
authorGravatar ameerj2021-03-01 01:30:09 -0500
committerGravatar ameerj2021-07-22 21:51:23 -0400
commite0389286165805258fa2e54014c2dc506ffb9f35 (patch)
treed7830153aac3a2ad93fd93f8b74516bbeb8f3718 /src/shader_recompiler/frontend
parentshader: Make IMNMX, SHR, SEL stylistically more consistent (diff)
downloadyuzu-e0389286165805258fa2e54014c2dc506ffb9f35.tar.gz
yuzu-e0389286165805258fa2e54014c2dc506ffb9f35.tar.xz
yuzu-e0389286165805258fa2e54014c2dc506ffb9f35.zip
shader: Implement ISET, add common_funcs
Diffstat (limited to 'src/shader_recompiler/frontend')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp46
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h17
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/impl.h19
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp39
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp62
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
7 files changed, 147 insertions, 50 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
new file mode 100644
index 000000000..3ec146b1a
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.cpp
@@ -0,0 +1,46 @@
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 "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h"
6
7namespace Shader::Maxwell {
8[[nodiscard]] IR::U1 IntegerCompare(TranslatorVisitor& v, const IR::U32& operand_1,
9 const IR::U32& operand_2, ComparisonOp compare_op,
10 bool is_signed) {
11 switch (compare_op) {
12 case ComparisonOp::False:
13 return v.ir.Imm1(false);
14 case ComparisonOp::LessThan:
15 return v.ir.ILessThan(operand_1, operand_2, is_signed);
16 case ComparisonOp::Equal:
17 return v.ir.IEqual(operand_1, operand_2);
18 case ComparisonOp::LessThanEqual:
19 return v.ir.ILessThanEqual(operand_1, operand_2, is_signed);
20 case ComparisonOp::GreaterThan:
21 return v.ir.IGreaterThan(operand_1, operand_2, is_signed);
22 case ComparisonOp::NotEqual:
23 return v.ir.INotEqual(operand_1, operand_2);
24 case ComparisonOp::GreaterThanEqual:
25 return v.ir.IGreaterThanEqual(operand_1, operand_2, is_signed);
26 case ComparisonOp::True:
27 return v.ir.Imm1(true);
28 default:
29 throw NotImplementedException("CMP");
30 }
31}
32
33[[nodiscard]] IR::U1 PredicateCombine(TranslatorVisitor& v, const IR::U1& predicate_1,
34 const IR::U1& predicate_2, BooleanOp bop) {
35 switch (bop) {
36 case BooleanOp::And:
37 return v.ir.LogicalAnd(predicate_1, predicate_2);
38 case BooleanOp::Or:
39 return v.ir.LogicalOr(predicate_1, predicate_2);
40 case BooleanOp::Xor:
41 return v.ir.LogicalXor(predicate_1, predicate_2);
42 default:
43 throw NotImplementedException("BOP");
44 }
45}
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
new file mode 100644
index 000000000..293fcce2e
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h
@@ -0,0 +1,17 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9
10namespace Shader::Maxwell {
11[[nodiscard]] IR::U1 IntegerCompare(TranslatorVisitor& v, const IR::U32& operand_1,
12 const IR::U32& operand_2, ComparisonOp compare_op,
13 bool is_signed);
14
15[[nodiscard]] IR::U1 PredicateCombine(TranslatorVisitor& v, const IR::U1& predicate_1,
16 const IR::U1& predicate_2, BooleanOp bop);
17} // 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 672e140b2..232f8c894 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once
6
5#include "shader_recompiler/environment.h" 7#include "shader_recompiler/environment.h"
6#include "shader_recompiler/frontend/ir/basic_block.h" 8#include "shader_recompiler/frontend/ir/basic_block.h"
7#include "shader_recompiler/frontend/ir/ir_emitter.h" 9#include "shader_recompiler/frontend/ir/ir_emitter.h"
@@ -9,6 +11,23 @@
9 11
10namespace Shader::Maxwell { 12namespace Shader::Maxwell {
11 13
14enum class ComparisonOp : u64 {
15 False,
16 LessThan,
17 Equal,
18 LessThanEqual,
19 GreaterThan,
20 NotEqual,
21 GreaterThanEqual,
22 True,
23};
24
25enum class BooleanOp : u64 {
26 And,
27 Or,
28 Xor,
29};
30
12class TranslatorVisitor { 31class TranslatorVisitor {
13public: 32public:
14 explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {} 33 explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {}
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 1f604b0ee..d844974d8 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare.cpp
@@ -4,46 +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 ComparisonOp : u64 {
12 False,
13 LessThan,
14 Equal,
15 LessThanEqual,
16 GreaterThan,
17 NotEqual,
18 GreaterThanEqual,
19 True,
20};
21
22[[nodiscard]] IR::U1 CompareToZero(TranslatorVisitor& v, const IR::U32& operand,
23 ComparisonOp compare_op, bool is_signed) {
24 const IR::U32 zero{v.ir.Imm32(0)};
25 switch (compare_op) {
26 case ComparisonOp::False:
27 return v.ir.Imm1(false);
28 case ComparisonOp::LessThan:
29 return v.ir.ILessThan(operand, zero, is_signed);
30 case ComparisonOp::Equal:
31 return v.ir.IEqual(operand, zero);
32 case ComparisonOp::LessThanEqual:
33 return v.ir.ILessThanEqual(operand, zero, is_signed);
34 case ComparisonOp::GreaterThan:
35 return v.ir.IGreaterThan(operand, zero, is_signed);
36 case ComparisonOp::NotEqual:
37 return v.ir.INotEqual(operand, zero);
38 case ComparisonOp::GreaterThanEqual:
39 return v.ir.IGreaterThanEqual(operand, zero, is_signed);
40 case ComparisonOp::True:
41 return v.ir.Imm1(true);
42 default:
43 throw NotImplementedException("ICMP.CMP");
44 }
45}
46
47void ICMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& operand) { 12void ICMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& operand) {
48 union { 13 union {
49 u64 insn; 14 u64 insn;
@@ -55,7 +20,7 @@ void ICMP(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& o
55 20
56 const IR::U32 zero{v.ir.Imm32(0)}; 21 const IR::U32 zero{v.ir.Imm32(0)};
57 const bool is_signed{icmp.is_signed != 0}; 22 const bool is_signed{icmp.is_signed != 0};
58 const IR::U1 cmp_result{CompareToZero(v, operand, icmp.compare_op, is_signed)}; 23 const IR::U1 cmp_result{IntegerCompare(v, operand, zero, icmp.compare_op, is_signed)};
59 24
60 const IR::U32 src_reg{v.X(icmp.src_reg)}; 25 const IR::U32 src_reg{v.X(icmp.src_reg)};
61 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
new file mode 100644
index 000000000..b6a7b593d
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp
@@ -0,0 +1,62 @@
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 ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
13 union {
14 u64 insn;
15 BitField<0, 8, IR::Reg> dest_reg;
16 BitField<8, 8, IR::Reg> src_reg;
17 BitField<39, 3, IR::Pred> pred;
18 BitField<42, 1, u64> neg_pred;
19 BitField<43, 1, u64> x;
20 BitField<44, 1, u64> bf;
21 BitField<45, 2, BooleanOp> bop;
22 BitField<48, 1, u64> is_signed;
23 BitField<49, 3, ComparisonOp> compare_op;
24 } const iset{insn};
25
26 if (iset.x != 0) {
27 throw NotImplementedException("ISET.X");
28 }
29
30 const IR::U32 src_reg{v.X(iset.src_reg)};
31 const bool is_signed{iset.is_signed != 0};
32 IR::U1 pred{v.ir.GetPred(iset.pred)};
33 if (iset.neg_pred != 0) {
34 pred = v.ir.LogicalNot(pred);
35 }
36 const IR::U1 cmp_result{IntegerCompare(v, src_reg, src_a, iset.compare_op, is_signed)};
37 const IR::U1 bop_result{PredicateCombine(v, cmp_result, pred, iset.bop)};
38
39 const IR::U32 one_mask{v.ir.Imm32(-1)};
40 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
41 const IR::U32 fail_result{v.ir.Imm32(0)};
42 const IR::U32 pass_result{iset.bf == 0 ? one_mask : fp_one};
43
44 const IR::U32 result{v.ir.Select(bop_result, pass_result, fail_result)};
45
46 v.X(iset.dest_reg, result);
47}
48} // Anonymous namespace
49
50void TranslatorVisitor::ISET_reg(u64 insn) {
51 ISET(*this, insn, GetReg20(insn));
52}
53
54void TranslatorVisitor::ISET_cbuf(u64 insn) {
55 ISET(*this, insn, GetCbuf(insn));
56}
57
58void TranslatorVisitor::ISET_imm(u64 insn) {
59 ISET(*this, insn, GetImm20(insn));
60}
61
62} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
index 5303db612..40f14ab8a 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
@@ -23,7 +23,7 @@ void IMNMX(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
23 throw NotImplementedException("IMNMX.MODE"); 23 throw NotImplementedException("IMNMX.MODE");
24 } 24 }
25 25
26 IR::U1 pred{v.ir.GetPred(imnmx.pred)}; 26 const IR::U1 pred{v.ir.GetPred(imnmx.pred)};
27 const IR::U32 op_a{v.X(imnmx.src_reg)}; 27 const IR::U32 op_a{v.X(imnmx.src_reg)};
28 IR::U32 min; 28 IR::U32 min;
29 IR::U32 max; 29 IR::U32 max;
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 8d4044ee8..f327e6fa5 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -457,18 +457,6 @@ void TranslatorVisitor::ISBERD(u64) {
457 ThrowNotImplemented(Opcode::ISBERD); 457 ThrowNotImplemented(Opcode::ISBERD);
458} 458}
459 459
460void TranslatorVisitor::ISET_reg(u64) {
461 ThrowNotImplemented(Opcode::ISET_reg);
462}
463
464void TranslatorVisitor::ISET_cbuf(u64) {
465 ThrowNotImplemented(Opcode::ISET_cbuf);
466}
467
468void TranslatorVisitor::ISET_imm(u64) {
469 ThrowNotImplemented(Opcode::ISET_imm);
470}
471
472void TranslatorVisitor::JCAL(u64) { 460void TranslatorVisitor::JCAL(u64) {
473 ThrowNotImplemented(Opcode::JCAL); 461 ThrowNotImplemented(Opcode::JCAL);
474} 462}