Merge pull request #1760 from ReinUsesLisp/r2p

gl_shader_decompiler: Implement R2P_IMM
master
bunnei 2018-11-25 22:38:42 +07:00 committed by GitHub
commit d7d1ab15b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 0 deletions

@ -368,6 +368,11 @@ enum class HalfPrecision : u64 {
FMZ = 2,
};
enum class R2pMode : u64 {
Pr = 0,
Cc = 1,
};
enum class IpaInterpMode : u64 {
Linear = 0,
Perspective = 1,
@ -856,6 +861,12 @@ union Instruction {
BitField<39, 3, u64> pred39;
} hsetp2;
union {
BitField<40, 1, R2pMode> mode;
BitField<41, 2, u64> byte;
BitField<20, 7, u64> immediate_mask;
} r2p;
union {
BitField<39, 3, u64> pred39;
BitField<42, 1, u64> neg_pred;
@ -1383,6 +1394,7 @@ public:
PSETP,
PSET,
CSETP,
R2P_IMM,
XMAD_IMM,
XMAD_CR,
XMAD_RC,
@ -1412,6 +1424,7 @@ public:
HalfSetPredicate,
PredicateSetPredicate,
PredicateSetRegister,
RegisterSetPredicate,
Conversion,
Xmad,
Unknown,
@ -1649,6 +1662,7 @@ private:
INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"),
INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"),
INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"),

@ -3315,6 +3315,34 @@ private:
}
break;
}
case OpCode::Type::RegisterSetPredicate: {
UNIMPLEMENTED_IF(instr.r2p.mode != Tegra::Shader::R2pMode::Pr);
const std::string apply_mask = [&]() {
switch (opcode->get().GetId()) {
case OpCode::Id::R2P_IMM:
return std::to_string(instr.r2p.immediate_mask);
default:
UNREACHABLE();
}
}();
const std::string mask = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
" >> " + std::to_string(instr.r2p.byte) + ')';
constexpr u64 programmable_preds = 7;
for (u64 pred = 0; pred < programmable_preds; ++pred) {
const auto shift = std::to_string(1 << pred);
shader.AddLine("if ((" + apply_mask + " & " + shift + ") != 0) {");
++shader.scope;
SetPredicate(pred, '(' + mask + " & " + shift + ") != 0");
--shader.scope;
shader.AddLine('}');
}
break;
}
case OpCode::Type::FloatSet: {
const std::string op_a = GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8),
instr.fset.abs_a != 0, instr.fset.neg_a != 0);