From 5440b9c634555c174a9eaf7fd6d308c4ab2cb3bb Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sat, 9 Jun 2018 00:01:17 -0400
Subject: [PATCH] gl_shader_decompiler: Implement SHR instruction.

---
 src/video_core/engines/shader_bytecode.h            |  4 ++++
 .../renderer_opengl/gl_shader_decompiler.cpp        | 13 +++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 32800392b9..a9ea550dcd 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -259,6 +259,10 @@ union Instruction {
         }
     } alu;
 
+    union {
+        BitField<48, 1, u64> is_signed;
+    } shift;
+
     union {
         BitField<39, 5, u64> shift_amount;
         BitField<48, 1, u64> negate_b;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 94c6bc4b25..fde19cb6b4 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -973,6 +973,19 @@ private:
             }
 
             switch (opcode->GetId()) {
+            case OpCode::Id::SHR_C:
+            case OpCode::Id::SHR_R:
+            case OpCode::Id::SHR_IMM: {
+                if (!instr.shift.is_signed) {
+                    // Logical shift right
+                    op_a = "uint(" + op_a + ')';
+                }
+
+                // Cast to int is superfluous for arithmetic shift, it's only for a logical shift
+                regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')',
+                                          1, 1);
+                break;
+            }
             case OpCode::Id::SHL_C:
             case OpCode::Id::SHL_R:
             case OpCode::Id::SHL_IMM: