gl_shader_decompiler: Implement HSET2_R

master
ReinUsesLisp 2018-10-15 02:10:15 +07:00
parent 4fc8ad67bf
commit 6312eec5ef
2 changed files with 62 additions and 0 deletions

@ -831,6 +831,21 @@ union Instruction {
BitField<56, 1, u64> neg_imm; BitField<56, 1, u64> neg_imm;
} fset; } fset;
union {
BitField<49, 1, u64> bf;
BitField<35, 3, PredCondition> cond;
BitField<50, 1, u64> ftz;
BitField<45, 2, PredOperation> op;
BitField<43, 1, u64> negate_a;
BitField<44, 1, u64> abs_a;
BitField<47, 2, HalfType> type_a;
BitField<31, 1, u64> negate_b;
BitField<30, 1, u64> abs_b;
BitField<28, 2, HalfType> type_b;
BitField<42, 1, u64> neg_pred;
BitField<39, 3, u64> pred39;
} hset2;
union { union {
BitField<39, 3, u64> pred39; BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred; BitField<42, 1, u64> neg_pred;
@ -1257,6 +1272,7 @@ public:
HFMA2_RR, HFMA2_RR,
HFMA2_IMM_R, HFMA2_IMM_R,
HSETP2_R, HSETP2_R,
HSET2_R,
POPC_C, POPC_C,
POPC_R, POPC_R,
POPC_IMM, POPC_IMM,
@ -1343,6 +1359,7 @@ public:
FloatSetPredicate, FloatSetPredicate,
IntegerSet, IntegerSet,
IntegerSetPredicate, IntegerSetPredicate,
HalfSet,
HalfSetPredicate, HalfSetPredicate,
PredicateSetPredicate, PredicateSetPredicate,
PredicateSetRegister, PredicateSetRegister,
@ -1516,6 +1533,7 @@ private:
INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"), INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"),
INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"), INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"),
INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP_R"), INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP_R"),
INST("0101110100011---", Id::HSET2_R, Type::HalfSet, "HSET2_R"),
INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),

@ -2996,6 +2996,50 @@ private:
} }
break; break;
} }
case OpCode::Type::HalfSet: {
ASSERT_MSG(instr.hset2.ftz == 0, "Unimplemented");
const std::string op_a =
GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hset2.type_a,
instr.hset2.abs_a != 0, instr.hset2.negate_a != 0);
const std::string op_b = [&]() {
switch (opcode->GetId()) {
case OpCode::Id::HSET2_R:
return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
instr.hset2.type_b, instr.hset2.abs_b != 0,
instr.hset2.negate_b != 0);
default:
UNREACHABLE();
return std::string("vec2(0)");
}
}();
const std::string second_pred =
GetPredicateCondition(instr.hset2.pred39, instr.hset2.neg_pred != 0);
const std::string combiner = GetPredicateCombiner(instr.hset2.op);
// HSET2 operates on each half float in the pack.
std::string result;
for (int i = 0; i < 2; ++i) {
const std::string float_value = i == 0 ? "0x00003c00" : "0x3c000000";
const std::string integer_value = i == 0 ? "0x0000ffff" : "0xffff0000";
const std::string value = instr.hset2.bf == 1 ? float_value : integer_value;
const std::string comp = std::string(".") + "xy"[i];
const std::string predicate =
"((" + GetPredicateComparison(instr.hset2.cond, op_a + comp, op_b + comp) +
") " + combiner + " (" + second_pred + "))";
result += '(' + predicate + " ? " + value + " : 0)";
if (i == 0) {
result += " | ";
}
}
regs.SetRegisterToInteger(instr.gpr0, false, 0, '(' + result + ')', 1, 1);
break;
}
case OpCode::Type::Xmad: { case OpCode::Type::Xmad: {
ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented"); ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented");
ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented"); ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented");