|
@@ -4,62 +4,11 @@
|
|
|
|
|
|
|
|
#include "common/bit_field.h"
|
|
#include "common/bit_field.h"
|
|
|
#include "common/common_types.h"
|
|
#include "common/common_types.h"
|
|
|
|
|
+#include "shader_recompiler/frontend/maxwell/translate/impl/common_funcs.h"
|
|
|
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
|
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
|
|
|
|
|
|
|
namespace Shader::Maxwell {
|
|
namespace Shader::Maxwell {
|
|
|
namespace {
|
|
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) {
|
|
void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
|
|
|
union {
|
|
union {
|
|
|
u64 raw;
|
|
u64 raw;
|
|
@@ -68,17 +17,18 @@ void ISETP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
|
|
|
BitField<8, 8, IR::Reg> src_reg_a;
|
|
BitField<8, 8, IR::Reg> src_reg_a;
|
|
|
BitField<39, 3, IR::Pred> bop_pred;
|
|
BitField<39, 3, IR::Pred> bop_pred;
|
|
|
BitField<42, 1, u64> neg_bop_pred;
|
|
BitField<42, 1, u64> neg_bop_pred;
|
|
|
- BitField<45, 2, Bop> bop;
|
|
|
|
|
|
|
+ BitField<45, 2, BooleanOp> bop;
|
|
|
BitField<48, 1, u64> is_signed;
|
|
BitField<48, 1, u64> is_signed;
|
|
|
BitField<49, 3, CompareOp> compare_op;
|
|
BitField<49, 3, CompareOp> compare_op;
|
|
|
} const isetp{insn};
|
|
} const isetp{insn};
|
|
|
|
|
|
|
|
- const Bop bop{isetp.bop};
|
|
|
|
|
|
|
+ const BooleanOp bop{isetp.bop};
|
|
|
|
|
+ const CompareOp compare_op{isetp.compare_op};
|
|
|
const IR::U32 op_a{v.X(isetp.src_reg_a)};
|
|
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 comparison{IntegerCompare(v.ir, op_a, op_b, compare_op, isetp.is_signed != 0)};
|
|
|
const IR::U1 bop_pred{v.ir.GetPred(isetp.bop_pred, isetp.neg_bop_pred != 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)};
|
|
|
|
|
|
|
+ const IR::U1 result_a{PredicateCombine(v.ir, comparison, bop_pred, bop)};
|
|
|
|
|
+ const IR::U1 result_b{PredicateCombine(v.ir, v.ir.LogicalNot(comparison), bop_pred, bop)};
|
|
|
v.ir.SetPred(isetp.dest_pred_a, result_a);
|
|
v.ir.SetPred(isetp.dest_pred_a, result_a);
|
|
|
v.ir.SetPred(isetp.dest_pred_b, result_b);
|
|
v.ir.SetPred(isetp.dest_pred_b, result_b);
|
|
|
}
|
|
}
|