shader_ir: Add half float helpers

This commit is contained in:
ReinUsesLisp 2018-12-20 22:58:33 -03:00
parent e3c55e31d7
commit 60f044df56
2 changed files with 44 additions and 0 deletions

View File

@ -175,6 +175,43 @@ Node ShaderIR::GetOperandAbsNegInteger(Node value, bool absolute, bool negate, b
return value; return value;
} }
Node ShaderIR::UnpackHalfImmediate(Instruction instr, bool has_negation) {
const Node value = Immediate(instr.half_imm.PackImmediates());
if (!has_negation) {
return value;
}
const Node first_negate = GetPredicate(instr.half_imm.first_negate != 0);
const Node second_negate = GetPredicate(instr.half_imm.second_negate != 0);
return Operation(OperationCode::HNegate, HALF_NO_PRECISE, value, first_negate, second_negate);
}
Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) {
switch (merge) {
case Tegra::Shader::HalfMerge::H0_H1:
return src;
case Tegra::Shader::HalfMerge::F32:
return Operation(OperationCode::HMergeF32, src);
case Tegra::Shader::HalfMerge::Mrg_H0:
return Operation(OperationCode::HMergeH0, dest, src);
case Tegra::Shader::HalfMerge::Mrg_H1:
return Operation(OperationCode::HMergeH1, dest, src);
}
UNREACHABLE();
return src;
}
Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
if (absolute) {
value = Operation(OperationCode::HAbsolute, HALF_NO_PRECISE, value);
}
if (negate) {
value = Operation(OperationCode::HNegate, HALF_NO_PRECISE, value, GetPredicate(true),
GetPredicate(true));
}
return value;
}
void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) { void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
} }

View File

@ -653,6 +653,13 @@ private:
/// Conditionally absolute/negated integer. Absolute is applied first /// Conditionally absolute/negated integer. Absolute is applied first
Node GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed); Node GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed);
/// Unpacks a half immediate from an instruction
Node UnpackHalfImmediate(Tegra::Shader::Instruction instr, bool has_negation);
/// Merges a half pair into another value
Node HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge);
/// Conditionally absolute/negated half float pair. Absolute is applied first
Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate);
template <typename... T> template <typename... T>
inline Node Operation(OperationCode code, const T*... operands) { inline Node Operation(OperationCode code, const T*... operands) {
return StoreNode(OperationNode(code, operands...)); return StoreNode(OperationNode(code, operands...));