|
|
@@ -293,6 +293,25 @@ private:
|
|
|
declr_predicates.insert(std::move(variable));
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Returns the condition to use in the 'if' for a predicated instruction.
|
|
|
+ * @param instr Instruction to generate the if condition for.
|
|
|
+ * @returns string containing the predicate condition.
|
|
|
+ */
|
|
|
+ std::string GetPredicateCondition(Instruction instr) const {
|
|
|
+ using Tegra::Shader::Pred;
|
|
|
+ ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex));
|
|
|
+
|
|
|
+ std::string variable =
|
|
|
+ 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value()));
|
|
|
+
|
|
|
+ if (instr.negate_pred) {
|
|
|
+ return "!(" + variable + ')';
|
|
|
+ }
|
|
|
+
|
|
|
+ return variable;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Returns whether the instruction at the specified offset is a 'sched' instruction.
|
|
|
* Sched instructions always appear before a sequence of 3 instructions.
|
|
|
@@ -320,6 +339,16 @@ private:
|
|
|
|
|
|
shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name);
|
|
|
|
|
|
+ using Tegra::Shader::Pred;
|
|
|
+ ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
|
|
|
+ "NeverExecute predicate not implemented");
|
|
|
+
|
|
|
+ if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
|
|
|
+ shader.AddLine("if (" + GetPredicateCondition(instr) + ')');
|
|
|
+ shader.AddLine('{');
|
|
|
+ ++shader.scope;
|
|
|
+ }
|
|
|
+
|
|
|
switch (OpCode::GetInfo(instr.opcode).type) {
|
|
|
case OpCode::Type::Arithmetic: {
|
|
|
std::string dest = GetRegister(instr.gpr0);
|
|
|
@@ -559,6 +588,12 @@ private:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Close the predicate condition scope.
|
|
|
+ if (instr.pred != Pred::UnusedIndex) {
|
|
|
+ --shader.scope;
|
|
|
+ shader.AddLine('}');
|
|
|
+ }
|
|
|
+
|
|
|
return offset + 1;
|
|
|
}
|
|
|
|