From 833d0806f92b893220cf43d63c223a7cd9af9022 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 20 Dec 2018 22:56:08 -0300
Subject: [PATCH] shader_ir: Add float helpers

---
 src/video_core/shader/shader_ir.cpp | 19 +++++++++++++++++++
 src/video_core/shader/shader_ir.h   |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 48046d9670..af95e54ef0 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -121,6 +121,25 @@ Node ShaderIR::GetLocalMemory(Node address) {
     return StoreNode(LmemNode(address));
 }
 
+Node ShaderIR::GetOperandAbsNegFloat(Node value, bool absolute, bool negate) {
+    if (absolute) {
+        value = Operation(OperationCode::FAbsolute, NO_PRECISE, value);
+    }
+    if (negate) {
+        value = Operation(OperationCode::FNegate, NO_PRECISE, value);
+    }
+    return value;
+}
+
+Node ShaderIR::GetSaturatedFloat(Node value, bool saturate) {
+    if (!saturate) {
+        return value;
+    }
+    const Node positive_zero = Immediate(std::copysignf(0, 1));
+    const Node positive_one = Immediate(1.0f);
+    return Operation(OperationCode::FClamp, NO_PRECISE, value, positive_zero, positive_one);
+}
+
 void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
     bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
 }
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 192b18ac74..93455412fd 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -643,6 +643,11 @@ private:
     /// Sets a local memory address. address and value must be a number-evaluated node
     void SetLocalMemory(BasicBlock& bb, Node address, Node value);
 
+    /// Conditionally absolute/negated float. Absolute is applied first
+    Node GetOperandAbsNegFloat(Node value, bool absolute, bool negate);
+    /// Conditionally saturates a float
+    Node GetSaturatedFloat(Node value, bool saturate = true);
+
     template <typename... T>
     inline Node Operation(OperationCode code, const T*... operands) {
         return StoreNode(OperationNode(code, operands...));