|
|
@@ -212,6 +212,103 @@ Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
+Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
|
|
|
+ static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
|
|
+ {PredCondition::LessThan, OperationCode::LogicalFLessThan},
|
|
|
+ {PredCondition::Equal, OperationCode::LogicalFEqual},
|
|
|
+ {PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
|
|
|
+ {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
|
|
|
+ {PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
|
|
|
+ {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
|
|
|
+ {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
|
|
|
+ {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
|
|
|
+ {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
|
|
|
+ {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
|
|
|
+ {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}};
|
|
|
+
|
|
|
+ const auto comparison{PredicateComparisonTable.find(condition)};
|
|
|
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
|
|
+ "Unknown predicate comparison operation");
|
|
|
+
|
|
|
+ Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
|
|
|
+
|
|
|
+ if (condition == PredCondition::LessThanWithNan ||
|
|
|
+ condition == PredCondition::NotEqualWithNan ||
|
|
|
+ condition == PredCondition::LessEqualWithNan ||
|
|
|
+ condition == PredCondition::GreaterThanWithNan ||
|
|
|
+ condition == PredCondition::GreaterEqualWithNan) {
|
|
|
+
|
|
|
+ predicate = Operation(OperationCode::LogicalOr, predicate,
|
|
|
+ Operation(OperationCode::LogicalFIsNan, op_a));
|
|
|
+ predicate = Operation(OperationCode::LogicalOr, predicate,
|
|
|
+ Operation(OperationCode::LogicalFIsNan, op_b));
|
|
|
+ }
|
|
|
+
|
|
|
+ return predicate;
|
|
|
+}
|
|
|
+
|
|
|
+Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
|
|
|
+ Node op_b) {
|
|
|
+ static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
|
|
+ {PredCondition::LessThan, OperationCode::LogicalILessThan},
|
|
|
+ {PredCondition::Equal, OperationCode::LogicalIEqual},
|
|
|
+ {PredCondition::LessEqual, OperationCode::LogicalILessEqual},
|
|
|
+ {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
|
|
|
+ {PredCondition::NotEqual, OperationCode::LogicalINotEqual},
|
|
|
+ {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
|
|
|
+ {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
|
|
|
+ {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
|
|
|
+ {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
|
|
|
+ {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
|
|
|
+ {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}};
|
|
|
+
|
|
|
+ const auto comparison{PredicateComparisonTable.find(condition)};
|
|
|
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
|
|
+ "Unknown predicate comparison operation");
|
|
|
+
|
|
|
+ Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b);
|
|
|
+
|
|
|
+ UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
|
|
|
+ condition == PredCondition::NotEqualWithNan ||
|
|
|
+ condition == PredCondition::LessEqualWithNan ||
|
|
|
+ condition == PredCondition::GreaterThanWithNan ||
|
|
|
+ condition == PredCondition::GreaterEqualWithNan,
|
|
|
+ "NaN comparisons for integers are not implemented");
|
|
|
+ return predicate;
|
|
|
+}
|
|
|
+
|
|
|
+Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
|
|
|
+ const MetaHalfArithmetic& meta, Node op_a, Node op_b) {
|
|
|
+
|
|
|
+ UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
|
|
|
+ condition == PredCondition::NotEqualWithNan ||
|
|
|
+ condition == PredCondition::LessEqualWithNan ||
|
|
|
+ condition == PredCondition::GreaterThanWithNan ||
|
|
|
+ condition == PredCondition::GreaterEqualWithNan,
|
|
|
+ "Unimplemented NaN comparison for half floats");
|
|
|
+
|
|
|
+ static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
|
|
+ {PredCondition::LessThan, OperationCode::LogicalHLessThan},
|
|
|
+ {PredCondition::Equal, OperationCode::LogicalHEqual},
|
|
|
+ {PredCondition::LessEqual, OperationCode::LogicalHLessEqual},
|
|
|
+ {PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan},
|
|
|
+ {PredCondition::NotEqual, OperationCode::LogicalHNotEqual},
|
|
|
+ {PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual},
|
|
|
+ {PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan},
|
|
|
+ {PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual},
|
|
|
+ {PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual},
|
|
|
+ {PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan},
|
|
|
+ {PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}};
|
|
|
+
|
|
|
+ const auto comparison{PredicateComparisonTable.find(condition)};
|
|
|
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
|
|
+ "Unknown predicate comparison operation");
|
|
|
+
|
|
|
+ const Node predicate = Operation(comparison->second, meta, op_a, op_b);
|
|
|
+
|
|
|
+ return predicate;
|
|
|
+}
|
|
|
+
|
|
|
void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
|
|
|
bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
|
|
|
}
|