From 9f851e3832fb85c20f406eacfadd12a8bb7d982d Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Sun, 9 May 2021 04:18:37 -0300
Subject: [PATCH] glasm: Implement GLASM fp16 packing and move bitwise insns

---
 .../backend/glasm/emit_glasm.cpp              | 40 ----------
 .../glasm/emit_glasm_bitwise_conversion.cpp   | 75 +++++++++++++++++++
 .../backend/glasm/emit_glasm_instructions.h   |  4 +-
 .../glasm/emit_glasm_not_implemented.cpp      | 24 ------
 4 files changed, 77 insertions(+), 66 deletions(-)

diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 8981cf3000..842ec157dc 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -139,18 +139,6 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) {
     }
     throw LogicError("Invalid opcode {}", inst->GetOpcode());
 }
-
-void Alias(IR::Inst& inst, const IR::Value& value) {
-    if (value.IsImmediate()) {
-        return;
-    }
-    IR::Inst* const value_inst{value.InstRecursive()};
-    if (inst.GetOpcode() == IR::Opcode::Identity) {
-        value_inst->DestructiveAddUsage(inst.UseCount());
-        value_inst->DestructiveRemoveUsage();
-    }
-    inst.SetDefinition(value_inst->Definition<Id>());
-}
 } // Anonymous namespace
 
 std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) {
@@ -183,32 +171,4 @@ std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) {
     return ctx.code;
 }
 
-void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastU32F32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastU64F64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastF16U16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastF32U32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
-void EmitBitCastF64U64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
-    Alias(inst, value);
-}
-
 } // namespace Shader::Backend::GLASM
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
index e69de29bb2..918d823753 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
@@ -0,0 +1,75 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "shader_recompiler/backend/glasm/emit_context.h"
+#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
+#include "shader_recompiler/frontend/ir/value.h"
+
+namespace Shader::Backend::GLASM {
+
+static void Alias(IR::Inst& inst, const IR::Value& value) {
+    if (value.IsImmediate()) {
+        return;
+    }
+    IR::Inst* const value_inst{value.InstRecursive()};
+    if (inst.GetOpcode() == IR::Opcode::Identity) {
+        value_inst->DestructiveAddUsage(inst.UseCount());
+        value_inst->DestructiveRemoveUsage();
+    }
+    inst.SetDefinition(value_inst->Definition<Id>());
+}
+
+void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastU16F16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastU32F32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastU64F64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastF16U16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastF32U32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitBitCastF64U64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+    Alias(inst, value);
+}
+
+void EmitPackUint2x32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
+    throw NotImplementedException("GLASM instruction");
+}
+
+void EmitUnpackUint2x32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
+    throw NotImplementedException("GLASM instruction");
+}
+
+void EmitPackFloat2x16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
+    throw NotImplementedException("GLASM instruction");
+}
+
+void EmitUnpackFloat2x16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
+    throw NotImplementedException("GLASM instruction");
+}
+
+void EmitPackHalf2x16(EmitContext& ctx, IR::Inst& inst, Register value) {
+    ctx.Add("PK2H {}.x,{};", inst, value);
+}
+
+void EmitUnpackHalf2x16(EmitContext& ctx, IR::Inst& inst, Register value) {
+    ctx.Add("UP2H {}.xy,{}.x;", inst, value);
+}
+
+} // namespace Shader::Backend::GLASM
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 42de6716a4..cb1067dc9e 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -200,8 +200,8 @@ void EmitPackUint2x32(EmitContext& ctx, Register value);
 void EmitUnpackUint2x32(EmitContext& ctx, Register value);
 void EmitPackFloat2x16(EmitContext& ctx, Register value);
 void EmitUnpackFloat2x16(EmitContext& ctx, Register value);
-void EmitPackHalf2x16(EmitContext& ctx, Register value);
-void EmitUnpackHalf2x16(EmitContext& ctx, Register value);
+void EmitPackHalf2x16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitUnpackHalf2x16(EmitContext& ctx, IR::Inst& inst, Register value);
 void EmitPackDouble2x32(EmitContext& ctx, Register value);
 void EmitUnpackDouble2x32(EmitContext& ctx, Register value);
 void EmitGetZeroFromOp(EmitContext& ctx);
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
index 5729b27a7a..03464524e0 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
@@ -281,30 +281,6 @@ void EmitSelectF64(EmitContext& ctx, ScalarS32 cond, Register true_value, Regist
     NotImplemented();
 }
 
-void EmitPackUint2x32(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
-void EmitUnpackUint2x32(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
-void EmitPackFloat2x16(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
-void EmitUnpackFloat2x16(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
-void EmitPackHalf2x16(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
-void EmitUnpackHalf2x16(EmitContext& ctx, Register value) {
-    NotImplemented();
-}
-
 void EmitPackDouble2x32(EmitContext& ctx, Register value) {
     NotImplemented();
 }