summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-02-03 20:43:04 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:21 +0200
commitd24a16045f0f6b0b873d5e3b5bf187c1a8c4343f (patch)
tree0108a028b437bc59dfe7864f333cf4c50a46d3b5 /src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
parentshader: SSA and dominance (diff)
downloadyuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar.gz
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar.bz2
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar.lz
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar.xz
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.tar.zst
yuzu-d24a16045f0f6b0b873d5e3b5bf187c1a8c4343f.zip
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp99
1 files changed, 99 insertions, 0 deletions
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
new file mode 100644
index 000000000..76c6b5291
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_set_predicate.cpp
@@ -0,0 +1,99 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
+
+namespace Shader::Maxwell {
+namespace {
+enum class CompareOp : u64 {
+ F, // Always false
+ LT, // Less than
+ EQ, // Equal
+ LE, // Less than or equal
+ GT, // Greater than
+ NE, // Not equal
+ GE, // Greater than or equal
+ T, // Always true
+};
+
+enum class Bop : u64 {
+ AND,
+ OR,
+ XOR,
+};
+
+IR::U1 Compare(IR::IREmitter& ir, CompareOp op, const IR::U32& lhs, const IR::U32& rhs,
+ bool is_signed) {
+ switch (op) {
+ case CompareOp::F:
+ return ir.Imm1(false);
+ case CompareOp::LT:
+ return ir.ILessThan(lhs, rhs, is_signed);
+ case CompareOp::EQ:
+ return ir.IEqual(lhs, rhs);
+ case CompareOp::LE:
+ return ir.ILessThanEqual(lhs, rhs, is_signed);
+ case CompareOp::GT:
+ return ir.IGreaterThan(lhs, rhs, is_signed);
+ case CompareOp::NE:
+ return ir.INotEqual(lhs, rhs);
+ case CompareOp::GE:
+ return ir.IGreaterThanEqual(lhs, rhs, is_signed);
+ case CompareOp::T:
+ return ir.Imm1(true);
+ }
+ throw NotImplementedException("Invalid ISETP compare op {}", op);
+}
+
+IR::U1 Combine(IR::IREmitter& ir, Bop bop, const IR::U1& comparison, const IR::U1& bop_pred) {
+ switch (bop) {
+ case Bop::AND:
+ return ir.LogicalAnd(comparison, bop_pred);
+ case Bop::OR:
+ return ir.LogicalOr(comparison, bop_pred);
+ case Bop::XOR:
+ return ir.LogicalXor(comparison, bop_pred);
+ }
+ throw NotImplementedException("Invalid ISETP bop {}", bop);
+}
+
+void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
+ union {
+ u64 raw;
+ BitField<0, 3, IR::Pred> dest_pred_b;
+ BitField<3, 3, IR::Pred> dest_pred_a;
+ BitField<8, 8, IR::Reg> src_reg_a;
+ BitField<39, 3, IR::Pred> bop_pred;
+ BitField<42, 1, u64> neg_bop_pred;
+ BitField<45, 2, Bop> bop;
+ BitField<48, 1, u64> is_signed;
+ BitField<49, 3, CompareOp> compare_op;
+ } const isetp{insn};
+
+ const Bop bop{isetp.bop};
+ const IR::U32 op_a{v.X(isetp.src_reg_a)};
+ const IR::U1 comparison{Compare(v.ir, isetp.compare_op, op_a, op_b, isetp.is_signed != 0)};
+ const IR::U1 bop_pred{v.ir.GetPred(isetp.bop_pred, isetp.neg_bop_pred != 0)};
+ const IR::U1 result_a{Combine(v.ir, bop, comparison, bop_pred)};
+ const IR::U1 result_b{Combine(v.ir, bop, v.ir.LogicalNot(comparison), bop_pred)};
+ v.ir.SetPred(isetp.dest_pred_a, result_a);
+ v.ir.SetPred(isetp.dest_pred_b, result_b);
+}
+} // Anonymous namespace
+
+void TranslatorVisitor::ISETP_reg(u64 insn) {
+ ISETP(*this, insn, GetReg20(insn));
+}
+
+void TranslatorVisitor::ISETP_cbuf(u64 insn) {
+ ISETP(*this, insn, GetCbuf(insn));
+}
+
+void TranslatorVisitor::ISETP_imm(u64) {
+ throw NotImplementedException("ISETP_imm");
+}
+
+} // namespace Shader::Maxwell