Implemented CSETP

This commit is contained in:
FernandoS27 2018-09-08 22:44:20 -04:00
parent aac77bbd18
commit e2ac8fb36d
2 changed files with 49 additions and 14 deletions

View file

@ -580,6 +580,15 @@ union Instruction {
BitField<45, 2, PredOperation> op; BitField<45, 2, PredOperation> op;
} pset; } pset;
union {
BitField<0, 3, u64> pred0;
BitField<3, 3, u64> pred3;
BitField<8, 5, ControlCode> cc; // flag in cc
BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred39;
BitField<45, 4, PredOperation> op; // op with pred39
} csetp;
union { union {
BitField<39, 3, u64> pred39; BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred; BitField<42, 1, u64> neg_pred;
@ -895,6 +904,7 @@ public:
ISET_IMM, ISET_IMM,
PSETP, PSETP,
PSET, PSET,
CSETP,
XMAD_IMM, XMAD_IMM,
XMAD_CR, XMAD_CR,
XMAD_RC, XMAD_RC,
@ -1131,6 +1141,7 @@ private:
INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
INST("010100001010----", Id::PSETP, Type::PredicateSetPredicate, "CSETP"),
INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"),

View file

@ -2267,13 +2267,15 @@ private:
break; break;
} }
case OpCode::Type::PredicateSetPredicate: { case OpCode::Type::PredicateSetPredicate: {
const std::string op_a = switch (opcode->GetId()) {
GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); case OpCode::Id::PSETP: {
const std::string op_b = const std::string op_a =
GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
const std::string op_b =
GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
// We can't use the constant predicate as destination. // We can't use the constant predicate as destination.
ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
const std::string second_pred = const std::string second_pred =
GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
@ -2283,15 +2285,37 @@ private:
const std::string predicate = const std::string predicate =
'(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')';
// Set the primary predicate to the result of Predicate OP SecondPredicate // Set the primary predicate to the result of Predicate OP SecondPredicate
SetPredicate(instr.psetp.pred3, SetPredicate(instr.psetp.pred3,
'(' + predicate + ") " + combiner + " (" + second_pred + ')'); '(' + predicate + ") " + combiner + " (" + second_pred + ')');
if (instr.psetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) { if (instr.psetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
// Set the secondary predicate to the result of !Predicate OP SecondPredicate, // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
// if enabled // if enabled
SetPredicate(instr.psetp.pred0, SetPredicate(instr.psetp.pred0,
"!(" + predicate + ") " + combiner + " (" + second_pred + ')'); "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
}
break;
}
case OpCode::Id::CSETP: {
std::string pred =
GetPredicateCondition(instr.csetp.pred39, instr.csetp.neg_pred39 != 0);
std::string combiner = GetPredicateCombiner(instr.csetp.op);
std::string controlCode = regs.GetControlCode(instr.csetp.cc);
if (instr.csetp.pred3 != static_cast<u64>(Pred::UnusedIndex)) {
SetPredicate(instr.csetp.pred3,
'(' + controlCode + ") " + combiner + " (" + pred + ')');
}
if (instr.csetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
SetPredicate(instr.csetp.pred0,
"!(" + controlCode + ") " + combiner + " (" + pred + ')');
}
break;
}
default: {
LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}", opcode->GetName());
UNREACHABLE();
}
} }
break; break;
} }