GPU: Implement the iset family of shader instructions.

This commit is contained in:
Subv 2018-06-09 16:19:13 -05:00
parent 3cb753eeb1
commit b366b885a1
2 changed files with 46 additions and 2 deletions

View file

@ -329,6 +329,15 @@ union Instruction {
BitField<56, 1, u64> neg_imm; BitField<56, 1, u64> neg_imm;
} fset; } fset;
union {
BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred;
BitField<44, 1, u64> bf;
BitField<45, 2, PredOperation> op;
BitField<48, 1, u64> is_signed;
BitField<49, 3, PredCondition> cond;
} iset;
union { union {
BitField<10, 2, Register::Size> size; BitField<10, 2, Register::Size> size;
BitField<12, 1, u64> is_output_signed; BitField<12, 1, u64> is_output_signed;

View file

@ -1423,8 +1423,8 @@ private:
op_b = "abs(" + op_b + ')'; op_b = "abs(" + op_b + ')';
} }
// The fset instruction sets a register to 1.0 if the condition is true, and to 0 // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
// otherwise. // condition is true, and to 0 otherwise.
std::string second_pred = std::string second_pred =
GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
@ -1442,6 +1442,41 @@ private:
} }
break; break;
} }
case OpCode::Type::IntegerSet: {
std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed);
std::string op_b;
if (instr.is_b_imm) {
op_b = std::to_string(instr.alu.GetSignedImm20_20());
} else {
if (instr.is_b_gpr) {
op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, instr.iset.is_signed);
} else {
op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
GLSLRegister::Type::Integer);
}
}
// The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
// condition is true, and to 0 otherwise.
std::string second_pred =
GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0);
std::string comparator = GetPredicateComparison(instr.iset.cond);
std::string combiner = GetPredicateCombiner(instr.iset.op);
std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " +
combiner + " (" + second_pred + "))";
if (instr.iset.bf) {
regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
} else {
regs.SetRegisterToInteger(instr.gpr0, false, 0, predicate + " ? 0xFFFFFFFF : 0", 1,
1);
}
break;
}
default: { default: {
switch (opcode->GetId()) { switch (opcode->GetId()) {
case OpCode::Id::EXIT: { case OpCode::Id::EXIT: {