From 057dee48562b0cce69b1fa8bdb02bc0367852b4d Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Fri, 14 May 2021 21:18:53 -0400
Subject: [PATCH] glasm: Implement local memory for glasm

---
 src/shader_recompiler/backend/glasm/emit_glasm.cpp        | 3 +++
 .../backend/glasm/emit_glasm_context_get_set.cpp          | 8 ++++++++
 .../backend/glasm/emit_glasm_instructions.h               | 2 +-
 .../backend/glasm/emit_glasm_not_implemented.cpp          | 8 --------
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 775dd9e7e6..0b70bf3f6f 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -306,6 +306,9 @@ std::string EmitGLASM(const Profile&, IR::Program& program, Bindings&) {
     for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) {
         header += fmt::format("R{},", index);
     }
+    if (program.local_memory_size > 0) {
+        header += fmt::format("lmem[{}],", program.local_memory_size);
+    }
     header += "RC;"
               "LONG TEMP ";
     for (size_t index = 0; index < ctx.reg_alloc.NumUsedLongRegisters(); ++index) {
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index fed79e381b..de0be7aed2 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -113,4 +113,12 @@ void EmitSetFragDepth([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Scalar
     throw NotImplementedException("GLASM instruction");
 }
 
+void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset) {
+    ctx.Add("MOV.U {},lmem[{}].x;", inst, word_offset);
+}
+
+void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value) {
+    ctx.Add("MOV.U lmem[{}].x,{};", word_offset, 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 a74e422d6f..e7af8fa88d 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -71,7 +71,7 @@ void EmitInvocationId(EmitContext& ctx);
 void EmitSampleId(EmitContext& ctx);
 void EmitIsHelperInvocation(EmitContext& ctx);
 void EmitYDirection(EmitContext& ctx);
-void EmitLoadLocal(EmitContext& ctx, ScalarU32 word_offset);
+void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset);
 void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value);
 void EmitUndefU1(EmitContext& ctx);
 void EmitUndefU8(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 969b91a810..ae1735c8f2 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
@@ -168,14 +168,6 @@ void EmitYDirection(EmitContext& ctx) {
     NotImplemented();
 }
 
-void EmitLoadLocal(EmitContext& ctx, ScalarU32 word_offset) {
-    NotImplemented();
-}
-
-void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value) {
-    NotImplemented();
-}
-
 void EmitUndefU1(EmitContext& ctx) {
     NotImplemented();
 }