shader: Implement CC for ISET, FSET, PSET, CSET, and DSET

Throw when other instructions are missing CC.
This commit is contained in:
FernandoS27 2021-04-10 00:29:12 +02:00 committed by ameerj
parent 8cea39b5a6
commit 1be6705408
18 changed files with 136 additions and 13 deletions

View file

@ -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)};

View file

@ -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)};

View file

@ -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) {

View file

@ -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

View file

@ -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)};

View file

@ -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)};

View file

@ -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,

View file

@ -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

View file

@ -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};

View file

@ -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)};

View file

@ -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

View file

@ -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{};

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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) {

View file

@ -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)};

View file

@ -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);

View file

@ -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