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/bitfield_extract.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/condition_code_set.cpp16
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp17
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_compare_and_set.cpp17
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_compare_and_set.cpp17
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_minimum_maximum.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp4
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp10
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp5
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set_register.cpp16
18 files changed, 136 insertions, 13 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp
index 4a03e6939..0738ae7a6 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp
@@ -14,9 +14,14 @@ void BFE(TranslatorVisitor& v, u64 insn, const IR::U32& src) {
14 BitField<0, 8, IR::Reg> dest_reg; 14 BitField<0, 8, IR::Reg> dest_reg;
15 BitField<8, 8, IR::Reg> offset_reg; 15 BitField<8, 8, IR::Reg> offset_reg;
16 BitField<40, 1, u64> brev; 16 BitField<40, 1, u64> brev;
17 BitField<47, 1, u64> cc;
17 BitField<48, 1, u64> is_signed; 18 BitField<48, 1, u64> is_signed;
18 } const bfe{insn}; 19 } const bfe{insn};
19 20
21 if (bfe.cc != 0) {
22 throw NotImplementedException("BFE CC");
23 }
24
20 const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)}; 25 const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)};
21 const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)}; 26 const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)};
22 27
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp
index ee312c30d..fb7f821e6 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp
@@ -13,8 +13,13 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba
13 u64 insn; 13 u64 insn;
14 BitField<0, 8, IR::Reg> dest_reg; 14 BitField<0, 8, IR::Reg> dest_reg;
15 BitField<8, 8, IR::Reg> insert_reg; 15 BitField<8, 8, IR::Reg> insert_reg;
16 BitField<47, 1, u64> cc;
16 } const bfi{insn}; 17 } const bfi{insn};
17 18
19 if (bfi.cc != 0) {
20 throw NotImplementedException("BFI CC");
21 }
22
18 const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)}; 23 const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)};
19 const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; 24 const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)};
20 const IR::U32 max_size{v.ir.Imm32(32)}; 25 const IR::U32 max_size{v.ir.Imm32(32)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/condition_code_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/condition_code_set.cpp
index ea0c40a54..420f2fb94 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/condition_code_set.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/condition_code_set.cpp
@@ -18,17 +18,29 @@ void TranslatorVisitor::CSET(u64 insn) {
18 BitField<42, 1, u64> neg_bop_pred; 18 BitField<42, 1, u64> neg_bop_pred;
19 BitField<44, 1, u64> bf; 19 BitField<44, 1, u64> bf;
20 BitField<45, 2, BooleanOp> bop; 20 BitField<45, 2, BooleanOp> bop;
21 BitField<47, 1, u64> cc;
21 } const cset{insn}; 22 } const cset{insn};
22 23
23 const IR::U32 one_mask{ir.Imm32(-1)}; 24 const IR::U32 one_mask{ir.Imm32(-1)};
24 const IR::U32 fp_one{ir.Imm32(0x3f800000)}; 25 const IR::U32 fp_one{ir.Imm32(0x3f800000)};
25 const IR::U32 fail_result{ir.Imm32(0)}; 26 const IR::U32 zero{ir.Imm32(0)};
26 const IR::U32 pass_result{cset.bf == 0 ? one_mask : fp_one}; 27 const IR::U32 pass_result{cset.bf == 0 ? one_mask : fp_one};
27 const IR::U1 cc_test_result{ir.GetFlowTestResult(cset.cc_test)}; 28 const IR::U1 cc_test_result{ir.GetFlowTestResult(cset.cc_test)};
28 const IR::U1 bop_pred{ir.GetPred(cset.bop_pred, cset.neg_bop_pred != 0)}; 29 const IR::U1 bop_pred{ir.GetPred(cset.bop_pred, cset.neg_bop_pred != 0)};
29 const IR::U1 pred_result{PredicateCombine(ir, cc_test_result, bop_pred, cset.bop)}; 30 const IR::U1 pred_result{PredicateCombine(ir, cc_test_result, bop_pred, cset.bop)};
30 const IR::U32 result{ir.Select(pred_result, pass_result, fail_result)}; 31 const IR::U32 result{ir.Select(pred_result, pass_result, zero)};
31 X(cset.dest_reg, result); 32 X(cset.dest_reg, result);
33 if (cset.cc != 0) {
34 const IR::U1 is_zero{ir.IEqual(result, zero)};
35 SetZFlag(is_zero);
36 if (cset.bf != 0) {
37 ResetSFlag();
38 } else {
39 SetSFlag(ir.LogicalNot(is_zero));
40 }
41 ResetOFlag();
42 ResetCFlag();
43 }
32} 44}
33 45
34void TranslatorVisitor::CSETP(u64 insn) { 46void TranslatorVisitor::CSETP(u64 insn) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp
index e2ec852c9..1173192e4 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_compare_and_set.cpp
@@ -19,6 +19,7 @@ void DSET(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
19 BitField<43, 1, u64> negate_a; 19 BitField<43, 1, u64> negate_a;
20 BitField<44, 1, u64> abs_b; 20 BitField<44, 1, u64> abs_b;
21 BitField<45, 2, BooleanOp> bop; 21 BitField<45, 2, BooleanOp> bop;
22 BitField<47, 1, u64> cc;
22 BitField<48, 4, FPCompareOp> compare_op; 23 BitField<48, 4, FPCompareOp> compare_op;
23 BitField<52, 1, u64> bf; 24 BitField<52, 1, u64> bf;
24 BitField<53, 1, u64> negate_b; 25 BitField<53, 1, u64> negate_b;
@@ -37,10 +38,22 @@ void DSET(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
37 38
38 const IR::U32 one_mask{v.ir.Imm32(-1)}; 39 const IR::U32 one_mask{v.ir.Imm32(-1)};
39 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)}; 40 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
40 const IR::U32 fail_result{v.ir.Imm32(0)}; 41 const IR::U32 zero{v.ir.Imm32(0)};
41 const IR::U32 pass_result{dset.bf == 0 ? one_mask : fp_one}; 42 const IR::U32 pass_result{dset.bf == 0 ? one_mask : fp_one};
43 const IR::U32 result{v.ir.Select(bop_result, pass_result, zero)};
42 44
43 v.X(dset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)}); 45 v.X(dset.dest_reg, result);
46 if (dset.cc != 0) {
47 const IR::U1 is_zero{v.ir.IEqual(result, zero)};
48 v.SetZFlag(is_zero);
49 if (dset.bf != 0) {
50 v.ResetSFlag();
51 } else {
52 v.SetSFlag(v.ir.LogicalNot(is_zero));
53 }
54 v.ResetCFlag();
55 v.ResetOFlag();
56 }
44} 57}
45} // Anonymous namespace 58} // Anonymous namespace
46 59
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
index 723841496..f66097014 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_fused_multiply_add.cpp
@@ -16,10 +16,15 @@ void DFMA(TranslatorVisitor& v, u64 insn, const IR::F64& src_b, const IR::F64& s
16 BitField<0, 8, IR::Reg> dest_reg; 16 BitField<0, 8, IR::Reg> dest_reg;
17 BitField<8, 8, IR::Reg> src_a_reg; 17 BitField<8, 8, IR::Reg> src_a_reg;
18 BitField<50, 2, FpRounding> fp_rounding; 18 BitField<50, 2, FpRounding> fp_rounding;
19 BitField<47, 1, u64> cc;
19 BitField<48, 1, u64> neg_b; 20 BitField<48, 1, u64> neg_b;
20 BitField<49, 1, u64> neg_c; 21 BitField<49, 1, u64> neg_c;
21 } const dfma{insn}; 22 } const dfma{insn};
22 23
24 if (dfma.cc != 0) {
25 throw NotImplementedException("DFMA CC");
26 }
27
23 const IR::F64 src_a{v.D(dfma.src_a_reg)}; 28 const IR::F64 src_a{v.D(dfma.src_a_reg)};
24 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, false, dfma.neg_b != 0)}; 29 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, false, dfma.neg_b != 0)};
25 const IR::F64 op_c{v.ir.FPAbsNeg(src_c, false, dfma.neg_c != 0)}; 30 const IR::F64 op_c{v.ir.FPAbsNeg(src_c, false, dfma.neg_c != 0)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp
index 55a224db3..6b551847c 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_min_max.cpp
@@ -17,10 +17,15 @@ void DMNMX(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
17 BitField<42, 1, u64> neg_pred; 17 BitField<42, 1, u64> neg_pred;
18 BitField<45, 1, u64> negate_b; 18 BitField<45, 1, u64> negate_b;
19 BitField<46, 1, u64> abs_a; 19 BitField<46, 1, u64> abs_a;
20 BitField<47, 1, u64> cc;
20 BitField<48, 1, u64> negate_a; 21 BitField<48, 1, u64> negate_a;
21 BitField<49, 1, u64> abs_b; 22 BitField<49, 1, u64> abs_b;
22 } const dmnmx{insn}; 23 } const dmnmx{insn};
23 24
25 if (dmnmx.cc != 0) {
26 throw NotImplementedException("DMNMX CC");
27 }
28
24 const IR::U1 pred{v.ir.GetPred(dmnmx.pred)}; 29 const IR::U1 pred{v.ir.GetPred(dmnmx.pred)};
25 const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dmnmx.src_a_reg), dmnmx.abs_a != 0, dmnmx.negate_a != 0)}; 30 const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dmnmx.src_a_reg), dmnmx.abs_a != 0, dmnmx.negate_a != 0)};
26 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dmnmx.abs_b != 0, dmnmx.negate_b != 0)}; 31 const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dmnmx.abs_b != 0, dmnmx.negate_b != 0)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
index 4a49299a0..c0159fb65 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/double_multiply.cpp
@@ -16,9 +16,14 @@ void DMUL(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
16 BitField<0, 8, IR::Reg> dest_reg; 16 BitField<0, 8, IR::Reg> dest_reg;
17 BitField<8, 8, IR::Reg> src_a_reg; 17 BitField<8, 8, IR::Reg> src_a_reg;
18 BitField<39, 2, FpRounding> fp_rounding; 18 BitField<39, 2, FpRounding> fp_rounding;
19 BitField<47, 1, u64> cc;
19 BitField<48, 1, u64> neg; 20 BitField<48, 1, u64> neg;
20 } const dmul{insn}; 21 } const dmul{insn};
21 22
23 if (dmul.cc != 0) {
24 throw NotImplementedException("DMUL CC");
25 }
26
22 const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)}; 27 const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)};
23 const IR::FpControl control{ 28 const IR::FpControl control{
24 .no_contraction = true, 29 .no_contraction = true,
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
index b9f4ee0d9..eece4f28f 100644
--- 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
@@ -19,6 +19,7 @@ void FSET(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
19 BitField<43, 1, u64> negate_a; 19 BitField<43, 1, u64> negate_a;
20 BitField<44, 1, u64> abs_b; 20 BitField<44, 1, u64> abs_b;
21 BitField<45, 2, BooleanOp> bop; 21 BitField<45, 2, BooleanOp> bop;
22 BitField<47, 1, u64> cc;
22 BitField<48, 4, FPCompareOp> compare_op; 23 BitField<48, 4, FPCompareOp> compare_op;
23 BitField<52, 1, u64> bf; 24 BitField<52, 1, u64> bf;
24 BitField<53, 1, u64> negate_b; 25 BitField<53, 1, u64> negate_b;
@@ -43,10 +44,22 @@ void FSET(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
43 44
44 const IR::U32 one_mask{v.ir.Imm32(-1)}; 45 const IR::U32 one_mask{v.ir.Imm32(-1)};
45 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)}; 46 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
46 const IR::U32 fail_result{v.ir.Imm32(0)}; 47 const IR::U32 zero{v.ir.Imm32(0)};
47 const IR::U32 pass_result{fset.bf == 0 ? one_mask : fp_one}; 48 const IR::U32 pass_result{fset.bf == 0 ? one_mask : fp_one};
49 const IR::U32 result{v.ir.Select(bop_result, pass_result, zero)};
48 50
49 v.X(fset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)}); 51 v.X(fset.dest_reg, result);
52 if (fset.cc != 0) {
53 const IR::U1 is_zero{v.ir.IEqual(result, zero)};
54 v.SetZFlag(is_zero);
55 if (fset.bf != 0) {
56 v.ResetSFlag();
57 } else {
58 v.SetSFlag(v.ir.LogicalNot(is_zero));
59 }
60 v.ResetCFlag();
61 v.ResetOFlag();
62 }
50} 63}
51} // Anonymous namespace 64} // Anonymous namespace
52 65
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
index 035f8782a..ce2cf470d 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_conversion_floating_point.cpp
@@ -41,6 +41,7 @@ void F2F(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a, bool abs) {
41 BitField<0, 8, IR::Reg> dest_reg; 41 BitField<0, 8, IR::Reg> dest_reg;
42 BitField<44, 1, u64> ftz; 42 BitField<44, 1, u64> ftz;
43 BitField<45, 1, u64> neg; 43 BitField<45, 1, u64> neg;
44 BitField<47, 1, u64> cc;
44 BitField<50, 1, u64> sat; 45 BitField<50, 1, u64> sat;
45 BitField<39, 4, u64> rounding_op; 46 BitField<39, 4, u64> rounding_op;
46 BitField<39, 2, FpRounding> rounding; 47 BitField<39, 2, FpRounding> rounding;
@@ -53,6 +54,10 @@ void F2F(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a, bool abs) {
53 } 54 }
54 } const f2f{insn}; 55 } const f2f{insn};
55 56
57 if (f2f.cc != 0) {
58 throw NotImplementedException("F2F CC");
59 }
60
56 IR::F16F32F64 input{v.ir.FPAbsNeg(src_a, abs, f2f.neg != 0)}; 61 IR::F16F32F64 input{v.ir.FPAbsNeg(src_a, abs, f2f.neg != 0)};
57 62
58 const bool any_fp64{f2f.src_size == FloatFormat::F64 || f2f.dst_size == FloatFormat::F64}; 63 const bool any_fp64{f2f.src_size == FloatFormat::F64 || f2f.dst_size == FloatFormat::F64};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
index 8ae437528..c0d6ee5af 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_min_max.cpp
@@ -18,10 +18,15 @@ void FMNMX(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
18 BitField<44, 1, u64> ftz; 18 BitField<44, 1, u64> ftz;
19 BitField<45, 1, u64> negate_b; 19 BitField<45, 1, u64> negate_b;
20 BitField<46, 1, u64> abs_a; 20 BitField<46, 1, u64> abs_a;
21 BitField<47, 1, u64> cc;
21 BitField<48, 1, u64> negate_a; 22 BitField<48, 1, u64> negate_a;
22 BitField<49, 1, u64> abs_b; 23 BitField<49, 1, u64> abs_b;
23 } const fmnmx{insn}; 24 } const fmnmx{insn};
24 25
26 if (fmnmx.cc) {
27 throw NotImplementedException("FMNMX CC");
28 }
29
25 const IR::U1 pred{v.ir.GetPred(fmnmx.pred)}; 30 const IR::U1 pred{v.ir.GetPred(fmnmx.pred)};
26 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fmnmx.src_a_reg), fmnmx.abs_a != 0, fmnmx.negate_a != 0)}; 31 const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fmnmx.src_a_reg), fmnmx.abs_a != 0, fmnmx.negate_a != 0)};
27 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0)}; 32 const IR::F32 op_b{v.ir.FPAbsNeg(src_b, fmnmx.abs_b != 0, fmnmx.negate_b != 0)};
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 914af010f..a2cd8d7c6 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
@@ -19,6 +19,7 @@ void ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
19 BitField<43, 1, u64> x; 19 BitField<43, 1, u64> x;
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<47, 1, u64> cc;
22 BitField<48, 1, u64> is_signed; 23 BitField<48, 1, u64> is_signed;
23 BitField<49, 3, CompareOp> compare_op; 24 BitField<49, 3, CompareOp> compare_op;
24 } const iset{insn}; 25 } const iset{insn};
@@ -38,12 +39,22 @@ void ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
38 39
39 const IR::U32 one_mask{v.ir.Imm32(-1)}; 40 const IR::U32 one_mask{v.ir.Imm32(-1)};
40 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)}; 41 const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
41 const IR::U32 fail_result{v.ir.Imm32(0)}; 42 const IR::U32 zero{v.ir.Imm32(0)};
42 const IR::U32 pass_result{iset.bf == 0 ? one_mask : fp_one}; 43 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, zero)};
44 const IR::U32 result{v.ir.Select(bop_result, pass_result, fail_result)};
45 45
46 v.X(iset.dest_reg, result); 46 v.X(iset.dest_reg, result);
47 if (iset.cc != 0) {
48 const IR::U1 is_zero{v.ir.IEqual(result, zero)};
49 v.SetZFlag(is_zero);
50 if (iset.bf != 0) {
51 v.ResetSFlag();
52 } else {
53 v.SetSFlag(v.ir.LogicalNot(is_zero));
54 }
55 v.ResetCFlag();
56 v.ResetOFlag();
57 }
47} 58}
48} // Anonymous namespace 59} // Anonymous namespace
49 60
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
index 5a0fc36a0..3c233597f 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_floating_point_conversion.cpp
@@ -62,7 +62,7 @@ IR::U32 SmallAbs(TranslatorVisitor& v, const IR::U32& value, int bitsize) {
62void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) { 62void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) {
63 const Encoding i2f{insn}; 63 const Encoding i2f{insn};
64 if (i2f.cc != 0) { 64 if (i2f.cc != 0) {
65 throw NotImplementedException("CC"); 65 throw NotImplementedException("I2F CC");
66 } 66 }
67 const bool is_signed{i2f.is_signed != 0}; 67 const bool is_signed{i2f.is_signed != 0};
68 int src_bitsize{}; 68 int src_bitsize{};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
index d8d6c939e..5feefc0ce 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
@@ -33,9 +33,14 @@ void SHF(TranslatorVisitor& v, u64 insn, const IR::U32& shift, const IR::U32& hi
33 BitField<0, 8, IR::Reg> dest_reg; 33 BitField<0, 8, IR::Reg> dest_reg;
34 BitField<0, 8, IR::Reg> lo_bits_reg; 34 BitField<0, 8, IR::Reg> lo_bits_reg;
35 BitField<37, 2, MaxShift> max_shift; 35 BitField<37, 2, MaxShift> max_shift;
36 BitField<47, 1, u64> cc;
36 BitField<48, 2, u64> x_mode; 37 BitField<48, 2, u64> x_mode;
37 BitField<50, 1, u64> wrap; 38 BitField<50, 1, u64> wrap;
38 } const shf{insn}; 39 } const shf{insn};
40
41 if (shf.cc != 0) {
42 throw NotImplementedException("SHF CC");
43 }
39 if (shf.x_mode != 0) { 44 if (shf.x_mode != 0) {
40 throw NotImplementedException("SHF X Mode"); 45 throw NotImplementedException("SHF X Mode");
41 } 46 }
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 40f14ab8a..1badbacc4 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
@@ -16,9 +16,14 @@ void IMNMX(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) {
16 BitField<39, 3, IR::Pred> pred; 16 BitField<39, 3, IR::Pred> pred;
17 BitField<42, 1, u64> neg_pred; 17 BitField<42, 1, u64> neg_pred;
18 BitField<43, 2, u64> mode; 18 BitField<43, 2, u64> mode;
19 BitField<47, 1, u64> cc;
19 BitField<48, 1, u64> is_signed; 20 BitField<48, 1, u64> is_signed;
20 } const imnmx{insn}; 21 } const imnmx{insn};
21 22
23 if (imnmx.cc != 0) {
24 throw NotImplementedException("IMNMX CC");
25 }
26
22 if (imnmx.mode != 0) { 27 if (imnmx.mode != 0) {
23 throw NotImplementedException("IMNMX.MODE"); 28 throw NotImplementedException("IMNMX.MODE");
24 } 29 }
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
index 4025b1358..be00bb605 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_right.cpp
@@ -16,12 +16,16 @@ void SHR(TranslatorVisitor& v, u64 insn, const IR::U32& shift) {
16 BitField<39, 1, u64> is_wrapped; 16 BitField<39, 1, u64> is_wrapped;
17 BitField<40, 1, u64> brev; 17 BitField<40, 1, u64> brev;
18 BitField<43, 1, u64> xmode; 18 BitField<43, 1, u64> xmode;
19 BitField<47, 1, u64> cc;
19 BitField<48, 1, u64> is_signed; 20 BitField<48, 1, u64> is_signed;
20 } const shr{insn}; 21 } const shr{insn};
21 22
22 if (shr.xmode != 0) { 23 if (shr.xmode != 0) {
23 throw NotImplementedException("SHR.XMODE"); 24 throw NotImplementedException("SHR.XMODE");
24 } 25 }
26 if (shr.cc != 0) {
27 throw NotImplementedException("SHR.CC");
28 }
25 29
26 IR::U32 base{v.X(shr.src_reg_a)}; 30 IR::U32 base{v.X(shr.src_reg_a)};
27 if (shr.brev == 1) { 31 if (shr.brev == 1) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp
index 784588e83..4a0f04e47 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_effective_address.cpp
@@ -14,6 +14,7 @@ void LEA_hi(TranslatorVisitor& v, u64 insn, const IR::U32& base, IR::U32 offset_
14 u64 insn; 14 u64 insn;
15 BitField<0, 8, IR::Reg> dest_reg; 15 BitField<0, 8, IR::Reg> dest_reg;
16 BitField<8, 8, IR::Reg> offset_lo_reg; 16 BitField<8, 8, IR::Reg> offset_lo_reg;
17 BitField<47, 1, u64> cc;
17 BitField<48, 3, IR::Pred> pred; 18 BitField<48, 3, IR::Pred> pred;
18 } const lea{insn}; 19 } const lea{insn};
19 20
@@ -21,7 +22,10 @@ void LEA_hi(TranslatorVisitor& v, u64 insn, const IR::U32& base, IR::U32 offset_
21 throw NotImplementedException("LEA.HI X"); 22 throw NotImplementedException("LEA.HI X");
22 } 23 }
23 if (lea.pred != IR::Pred::PT) { 24 if (lea.pred != IR::Pred::PT) {
24 throw NotImplementedException("LEA.LO Pred"); 25 throw NotImplementedException("LEA.HI Pred");
26 }
27 if (lea.cc != 0) {
28 throw NotImplementedException("LEA.HI CC");
25 } 29 }
26 30
27 const IR::U32 offset_lo{v.X(lea.offset_lo_reg)}; 31 const IR::U32 offset_lo{v.X(lea.offset_lo_reg)};
@@ -44,6 +48,7 @@ void LEA_lo(TranslatorVisitor& v, u64 insn, const IR::U32& base) {
44 BitField<39, 5, u64> scale; 48 BitField<39, 5, u64> scale;
45 BitField<45, 1, u64> neg; 49 BitField<45, 1, u64> neg;
46 BitField<46, 1, u64> x; 50 BitField<46, 1, u64> x;
51 BitField<47, 1, u64> cc;
47 BitField<48, 3, IR::Pred> pred; 52 BitField<48, 3, IR::Pred> pred;
48 } const lea{insn}; 53 } const lea{insn};
49 if (lea.x != 0) { 54 if (lea.x != 0) {
@@ -52,6 +57,9 @@ void LEA_lo(TranslatorVisitor& v, u64 insn, const IR::U32& base) {
52 if (lea.pred != IR::Pred::PT) { 57 if (lea.pred != IR::Pred::PT) {
53 throw NotImplementedException("LEA.LO Pred"); 58 throw NotImplementedException("LEA.LO Pred");
54 } 59 }
60 if (lea.cc != 0) {
61 throw NotImplementedException("LEA.LO CC");
62 }
55 63
56 const IR::U32 offset_lo{v.X(lea.offset_lo_reg)}; 64 const IR::U32 offset_lo{v.X(lea.offset_lo_reg)};
57 const s32 scale{static_cast<s32>(lea.scale)}; 65 const s32 scale{static_cast<s32>(lea.scale)};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
index 256c47504..e0fe47912 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
@@ -73,8 +73,13 @@ IR::U32 LOP3(TranslatorVisitor& v, u64 insn, const IR::U32& op_b, const IR::U32&
73 u64 insn; 73 u64 insn;
74 BitField<0, 8, IR::Reg> dest_reg; 74 BitField<0, 8, IR::Reg> dest_reg;
75 BitField<8, 8, IR::Reg> src_reg; 75 BitField<8, 8, IR::Reg> src_reg;
76 BitField<47, 1, u64> cc;
76 } const lop3{insn}; 77 } const lop3{insn};
77 78
79 if (lop3.cc != 0) {
80 throw NotImplementedException("LOP3 CC");
81 }
82
78 const IR::U32 op_a{v.X(lop3.src_reg)}; 83 const IR::U32 op_a{v.X(lop3.src_reg)};
79 const IR::U32 result{ApplyLUT(v.ir, op_a, op_b, op_c, lut)}; 84 const IR::U32 result{ApplyLUT(v.ir, op_a, op_b, op_c, lut)};
80 v.X(lop3.dest_reg, result); 85 v.X(lop3.dest_reg, result);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set_register.cpp
index 6c15963fa..b02789874 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set_register.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/predicate_set_register.cpp
@@ -21,6 +21,7 @@ void TranslatorVisitor::PSET(u64 insn) {
21 BitField<42, 1, u64> neg_pred_c; 21 BitField<42, 1, u64> neg_pred_c;
22 BitField<44, 1, u64> bf; 22 BitField<44, 1, u64> bf;
23 BitField<45, 2, BooleanOp> bop_2; 23 BitField<45, 2, BooleanOp> bop_2;
24 BitField<47, 1, u64> cc;
24 } const pset{insn}; 25 } const pset{insn};
25 26
26 const IR::U1 pred_a{ir.GetPred(pset.pred_a, pset.neg_pred_a != 0)}; 27 const IR::U1 pred_a{ir.GetPred(pset.pred_a, pset.neg_pred_a != 0)};
@@ -31,11 +32,22 @@ void TranslatorVisitor::PSET(u64 insn) {
31 const IR::U1 res_2{PredicateCombine(ir, res_1, pred_c, pset.bop_2)}; 32 const IR::U1 res_2{PredicateCombine(ir, res_1, pred_c, pset.bop_2)};
32 33
33 const IR::U32 true_result{pset.bf != 0 ? ir.Imm32(0x3f800000) : ir.Imm32(-1)}; 34 const IR::U32 true_result{pset.bf != 0 ? ir.Imm32(0x3f800000) : ir.Imm32(-1)};
34 const IR::U32 false_result{ir.Imm32(0)}; 35 const IR::U32 zero{ir.Imm32(0)};
35 36
36 const IR::U32 result{ir.Select(res_2, true_result, false_result)}; 37 const IR::U32 result{ir.Select(res_2, true_result, zero)};
37 38
38 X(pset.dest_reg, result); 39 X(pset.dest_reg, result);
40 if (pset.cc != 0) {
41 const IR::U1 is_zero{ir.IEqual(result, zero)};
42 SetZFlag(is_zero);
43 if (pset.bf != 0) {
44 ResetSFlag();
45 } else {
46 SetSFlag(ir.LogicalNot(is_zero));
47 }
48 ResetOFlag();
49 ResetCFlag();
50 }
39} 51}
40 52
41} // namespace Shader::Maxwell 53} // namespace Shader::Maxwell