summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-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) {
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> offset_reg;
BitField<40, 1, u64> brev;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> is_signed;
} const bfe{insn};
+ if (bfe.cc != 0) {
+ throw NotImplementedException("BFE CC");
+ }
+
const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)};
const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)};
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
u64 insn;
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> insert_reg;
+ BitField<47, 1, u64> cc;
} const bfi{insn};
+ if (bfi.cc != 0) {
+ throw NotImplementedException("BFI CC");
+ }
+
const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)};
const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)};
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) {
BitField<42, 1, u64> neg_bop_pred;
BitField<44, 1, u64> bf;
BitField<45, 2, BooleanOp> bop;
+ BitField<47, 1, u64> cc;
} const cset{insn};
const IR::U32 one_mask{ir.Imm32(-1)};
const IR::U32 fp_one{ir.Imm32(0x3f800000)};
- const IR::U32 fail_result{ir.Imm32(0)};
+ const IR::U32 zero{ir.Imm32(0)};
const IR::U32 pass_result{cset.bf == 0 ? one_mask : fp_one};
const IR::U1 cc_test_result{ir.GetFlowTestResult(cset.cc_test)};
const IR::U1 bop_pred{ir.GetPred(cset.bop_pred, cset.neg_bop_pred != 0)};
const IR::U1 pred_result{PredicateCombine(ir, cc_test_result, bop_pred, cset.bop)};
- const IR::U32 result{ir.Select(pred_result, pass_result, fail_result)};
+ const IR::U32 result{ir.Select(pred_result, pass_result, zero)};
X(cset.dest_reg, result);
+ if (cset.cc != 0) {
+ const IR::U1 is_zero{ir.IEqual(result, zero)};
+ SetZFlag(is_zero);
+ if (cset.bf != 0) {
+ ResetSFlag();
+ } else {
+ SetSFlag(ir.LogicalNot(is_zero));
+ }
+ ResetOFlag();
+ ResetCFlag();
+ }
}
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) {
BitField<43, 1, u64> negate_a;
BitField<44, 1, u64> abs_b;
BitField<45, 2, BooleanOp> bop;
+ BitField<47, 1, u64> cc;
BitField<48, 4, FPCompareOp> compare_op;
BitField<52, 1, u64> bf;
BitField<53, 1, u64> negate_b;
@@ -37,10 +38,22 @@ void DSET(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) {
const IR::U32 one_mask{v.ir.Imm32(-1)};
const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
- const IR::U32 fail_result{v.ir.Imm32(0)};
+ const IR::U32 zero{v.ir.Imm32(0)};
const IR::U32 pass_result{dset.bf == 0 ? one_mask : fp_one};
+ const IR::U32 result{v.ir.Select(bop_result, pass_result, zero)};
- v.X(dset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)});
+ v.X(dset.dest_reg, result);
+ if (dset.cc != 0) {
+ const IR::U1 is_zero{v.ir.IEqual(result, zero)};
+ v.SetZFlag(is_zero);
+ if (dset.bf != 0) {
+ v.ResetSFlag();
+ } else {
+ v.SetSFlag(v.ir.LogicalNot(is_zero));
+ }
+ v.ResetCFlag();
+ v.ResetOFlag();
+ }
}
} // Anonymous namespace
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
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> src_a_reg;
BitField<50, 2, FpRounding> fp_rounding;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> neg_b;
BitField<49, 1, u64> neg_c;
} const dfma{insn};
+ if (dfma.cc != 0) {
+ throw NotImplementedException("DFMA CC");
+ }
+
const IR::F64 src_a{v.D(dfma.src_a_reg)};
const IR::F64 op_b{v.ir.FPAbsNeg(src_b, false, dfma.neg_b != 0)};
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) {
BitField<42, 1, u64> neg_pred;
BitField<45, 1, u64> negate_b;
BitField<46, 1, u64> abs_a;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> negate_a;
BitField<49, 1, u64> abs_b;
} const dmnmx{insn};
+ if (dmnmx.cc != 0) {
+ throw NotImplementedException("DMNMX CC");
+ }
+
const IR::U1 pred{v.ir.GetPred(dmnmx.pred)};
const IR::F64 op_a{v.ir.FPAbsNeg(v.D(dmnmx.src_a_reg), dmnmx.abs_a != 0, dmnmx.negate_a != 0)};
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) {
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> src_a_reg;
BitField<39, 2, FpRounding> fp_rounding;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> neg;
} const dmul{insn};
+ if (dmul.cc != 0) {
+ throw NotImplementedException("DMUL CC");
+ }
+
const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)};
const IR::FpControl control{
.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) {
BitField<43, 1, u64> negate_a;
BitField<44, 1, u64> abs_b;
BitField<45, 2, BooleanOp> bop;
+ BitField<47, 1, u64> cc;
BitField<48, 4, FPCompareOp> compare_op;
BitField<52, 1, u64> bf;
BitField<53, 1, u64> negate_b;
@@ -43,10 +44,22 @@ void FSET(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) {
const IR::U32 one_mask{v.ir.Imm32(-1)};
const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
- const IR::U32 fail_result{v.ir.Imm32(0)};
+ const IR::U32 zero{v.ir.Imm32(0)};
const IR::U32 pass_result{fset.bf == 0 ? one_mask : fp_one};
+ const IR::U32 result{v.ir.Select(bop_result, pass_result, zero)};
- v.X(fset.dest_reg, IR::U32{v.ir.Select(bop_result, pass_result, fail_result)});
+ v.X(fset.dest_reg, result);
+ if (fset.cc != 0) {
+ const IR::U1 is_zero{v.ir.IEqual(result, zero)};
+ v.SetZFlag(is_zero);
+ if (fset.bf != 0) {
+ v.ResetSFlag();
+ } else {
+ v.SetSFlag(v.ir.LogicalNot(is_zero));
+ }
+ v.ResetCFlag();
+ v.ResetOFlag();
+ }
}
} // Anonymous namespace
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) {
BitField<0, 8, IR::Reg> dest_reg;
BitField<44, 1, u64> ftz;
BitField<45, 1, u64> neg;
+ BitField<47, 1, u64> cc;
BitField<50, 1, u64> sat;
BitField<39, 4, u64> rounding_op;
BitField<39, 2, FpRounding> rounding;
@@ -53,6 +54,10 @@ void F2F(TranslatorVisitor& v, u64 insn, const IR::F16F32F64& src_a, bool abs) {
}
} const f2f{insn};
+ if (f2f.cc != 0) {
+ throw NotImplementedException("F2F CC");
+ }
+
IR::F16F32F64 input{v.ir.FPAbsNeg(src_a, abs, f2f.neg != 0)};
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) {
BitField<44, 1, u64> ftz;
BitField<45, 1, u64> negate_b;
BitField<46, 1, u64> abs_a;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> negate_a;
BitField<49, 1, u64> abs_b;
} const fmnmx{insn};
+ if (fmnmx.cc) {
+ throw NotImplementedException("FMNMX CC");
+ }
+
const IR::U1 pred{v.ir.GetPred(fmnmx.pred)};
const IR::F32 op_a{v.ir.FPAbsNeg(v.F(fmnmx.src_a_reg), fmnmx.abs_a != 0, fmnmx.negate_a != 0)};
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) {
BitField<43, 1, u64> x;
BitField<44, 1, u64> bf;
BitField<45, 2, BooleanOp> bop;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> is_signed;
BitField<49, 3, CompareOp> compare_op;
} const iset{insn};
@@ -38,12 +39,22 @@ void ISET(TranslatorVisitor& v, u64 insn, const IR::U32& src_a) {
const IR::U32 one_mask{v.ir.Imm32(-1)};
const IR::U32 fp_one{v.ir.Imm32(0x3f800000)};
- const IR::U32 fail_result{v.ir.Imm32(0)};
+ const IR::U32 zero{v.ir.Imm32(0)};
const IR::U32 pass_result{iset.bf == 0 ? one_mask : fp_one};
-
- const IR::U32 result{v.ir.Select(bop_result, pass_result, fail_result)};
+ const IR::U32 result{v.ir.Select(bop_result, pass_result, zero)};
v.X(iset.dest_reg, result);
+ if (iset.cc != 0) {
+ const IR::U1 is_zero{v.ir.IEqual(result, zero)};
+ v.SetZFlag(is_zero);
+ if (iset.bf != 0) {
+ v.ResetSFlag();
+ } else {
+ v.SetSFlag(v.ir.LogicalNot(is_zero));
+ }
+ v.ResetCFlag();
+ v.ResetOFlag();
+ }
}
} // Anonymous namespace
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) {
void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) {
const Encoding i2f{insn};
if (i2f.cc != 0) {
- throw NotImplementedException("CC");
+ throw NotImplementedException("I2F CC");
}
const bool is_signed{i2f.is_signed != 0};
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
BitField<0, 8, IR::Reg> dest_reg;
BitField<0, 8, IR::Reg> lo_bits_reg;
BitField<37, 2, MaxShift> max_shift;
+ BitField<47, 1, u64> cc;
BitField<48, 2, u64> x_mode;
BitField<50, 1, u64> wrap;
} const shf{insn};
+
+ if (shf.cc != 0) {
+ throw NotImplementedException("SHF CC");
+ }
if (shf.x_mode != 0) {
throw NotImplementedException("SHF X Mode");
}
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) {
BitField<39, 3, IR::Pred> pred;
BitField<42, 1, u64> neg_pred;
BitField<43, 2, u64> mode;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> is_signed;
} const imnmx{insn};
+ if (imnmx.cc != 0) {
+ throw NotImplementedException("IMNMX CC");
+ }
+
if (imnmx.mode != 0) {
throw NotImplementedException("IMNMX.MODE");
}
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) {
BitField<39, 1, u64> is_wrapped;
BitField<40, 1, u64> brev;
BitField<43, 1, u64> xmode;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> is_signed;
} const shr{insn};
if (shr.xmode != 0) {
throw NotImplementedException("SHR.XMODE");
}
+ if (shr.cc != 0) {
+ throw NotImplementedException("SHR.CC");
+ }
IR::U32 base{v.X(shr.src_reg_a)};
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_
u64 insn;
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> offset_lo_reg;
+ BitField<47, 1, u64> cc;
BitField<48, 3, IR::Pred> pred;
} const lea{insn};
@@ -21,7 +22,10 @@ void LEA_hi(TranslatorVisitor& v, u64 insn, const IR::U32& base, IR::U32 offset_
throw NotImplementedException("LEA.HI X");
}
if (lea.pred != IR::Pred::PT) {
- throw NotImplementedException("LEA.LO Pred");
+ throw NotImplementedException("LEA.HI Pred");
+ }
+ if (lea.cc != 0) {
+ throw NotImplementedException("LEA.HI CC");
}
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) {
BitField<39, 5, u64> scale;
BitField<45, 1, u64> neg;
BitField<46, 1, u64> x;
+ BitField<47, 1, u64> cc;
BitField<48, 3, IR::Pred> pred;
} const lea{insn};
if (lea.x != 0) {
@@ -52,6 +57,9 @@ void LEA_lo(TranslatorVisitor& v, u64 insn, const IR::U32& base) {
if (lea.pred != IR::Pred::PT) {
throw NotImplementedException("LEA.LO Pred");
}
+ if (lea.cc != 0) {
+ throw NotImplementedException("LEA.LO CC");
+ }
const IR::U32 offset_lo{v.X(lea.offset_lo_reg)};
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&
u64 insn;
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> src_reg;
+ BitField<47, 1, u64> cc;
} const lop3{insn};
+ if (lop3.cc != 0) {
+ throw NotImplementedException("LOP3 CC");
+ }
+
const IR::U32 op_a{v.X(lop3.src_reg)};
const IR::U32 result{ApplyLUT(v.ir, op_a, op_b, op_c, lut)};
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) {
BitField<42, 1, u64> neg_pred_c;
BitField<44, 1, u64> bf;
BitField<45, 2, BooleanOp> bop_2;
+ BitField<47, 1, u64> cc;
} const pset{insn};
const IR::U1 pred_a{ir.GetPred(pset.pred_a, pset.neg_pred_a != 0)};
@@ -31,11 +32,22 @@ void TranslatorVisitor::PSET(u64 insn) {
const IR::U1 res_2{PredicateCombine(ir, res_1, pred_c, pset.bop_2)};
const IR::U32 true_result{pset.bf != 0 ? ir.Imm32(0x3f800000) : ir.Imm32(-1)};
- const IR::U32 false_result{ir.Imm32(0)};
+ const IR::U32 zero{ir.Imm32(0)};
- const IR::U32 result{ir.Select(res_2, true_result, false_result)};
+ const IR::U32 result{ir.Select(res_2, true_result, zero)};
X(pset.dest_reg, result);
+ if (pset.cc != 0) {
+ const IR::U1 is_zero{ir.IEqual(result, zero)};
+ SetZFlag(is_zero);
+ if (pset.bf != 0) {
+ ResetSFlag();
+ } else {
+ SetSFlag(ir.LogicalNot(is_zero));
+ }
+ ResetOFlag();
+ ResetCFlag();
+ }
}
} // namespace Shader::Maxwell