mirror of
https://git.h3cjp.net/H3cJP/yuzu.git
synced 2024-11-14 20:32:51 +00:00
Merge pull request #553 from Subv/iset
GPU: Implement the ISET family of shader instructions.
This commit is contained in:
commit
281fd881a0
|
@ -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;
|
||||||
|
@ -487,6 +496,9 @@ public:
|
||||||
ISETP_C,
|
ISETP_C,
|
||||||
ISETP_IMM,
|
ISETP_IMM,
|
||||||
ISETP_R,
|
ISETP_R,
|
||||||
|
ISET_R,
|
||||||
|
ISET_C,
|
||||||
|
ISET_IMM,
|
||||||
PSETP,
|
PSETP,
|
||||||
XMAD_IMM,
|
XMAD_IMM,
|
||||||
XMAD_CR,
|
XMAD_CR,
|
||||||
|
@ -506,6 +518,7 @@ public:
|
||||||
Memory,
|
Memory,
|
||||||
FloatSet,
|
FloatSet,
|
||||||
FloatSetPredicate,
|
FloatSetPredicate,
|
||||||
|
IntegerSet,
|
||||||
IntegerSetPredicate,
|
IntegerSetPredicate,
|
||||||
PredicateSetPredicate,
|
PredicateSetPredicate,
|
||||||
Conversion,
|
Conversion,
|
||||||
|
@ -677,6 +690,9 @@ private:
|
||||||
INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"),
|
INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"),
|
||||||
INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
|
INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"),
|
||||||
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
|
INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"),
|
||||||
|
INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"),
|
||||||
|
INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"),
|
||||||
|
INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
|
||||||
INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
|
INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
|
||||||
INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"),
|
INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"),
|
||||||
INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"),
|
INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"),
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
Loading…
Reference in a new issue