diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
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 | ||
| 34 | void TranslatorVisitor::CSETP(u64 insn) { | 46 | void 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) { | |||
| 62 | void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) { | 62 | void 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 |