diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index f32a1705718a0e139efc2a5f2d194bff33e55c41..26c8913561cd3087781b934f238e006fd4f6a855 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -297,8 +297,10 @@ public:
         FMUL_R,
         FMUL_IMM,
         FMUL32_IMM,
-        MUFU, // Multi-Function Operator
-        RRO,  // Range Reduction Operator
+        MUFU,  // Multi-Function Operator
+        RRO_C, // Range Reduction Operator
+        RRO_R,
+        RRO_IMM,
         F2F_C,
         F2F_R,
         F2F_IMM,
@@ -459,7 +461,9 @@ private:
             INST("0011100-01101---", Id::FMUL_IMM, Type::Arithmetic, "FMUL_IMM"),
             INST("00011110--------", Id::FMUL32_IMM, Type::Arithmetic, "FMUL32_IMM"),
             INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
-            INST("0101110010010---", Id::RRO, Type::Arithmetic, "RRO"),
+            INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
+            INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
+            INST("0011100-10010---", Id::RRO_IMM, Type::Arithmetic, "RRO_IMM"),
             INST("0100110010101---", Id::F2F_C, Type::Conversion, "F2F_C"),
             INST("0101110010101---", Id::F2F_R, Type::Conversion, "F2F_R"),
             INST("0011100-10101---", Id::F2F_IMM, Type::Conversion, "F2F_IMM"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 68efe74b8a43ae30dba5ec6e7a6e2cd78bfa1c73..cb4b68b26029fff2b25f3ffafedc0f6914f1719e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -792,8 +792,13 @@ private:
                                         1, 1);
                 break;
             }
-            case OpCode::Id::RRO: {
-                NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction");
+            case OpCode::Id::RRO_C:
+            case OpCode::Id::RRO_R:
+            case OpCode::Id::RRO_IMM: {
+                // Currently RRO is only implemented as a register move.
+                // Usage of `abs_b` and `negate_b` here should also be correct.
+                regs.SetRegisterToFloat(instr.gpr0, 0, op_b, 1, 1);
+                NGLOG_WARNING(HW_GPU, "RRO instruction is incomplete");
                 break;
             }
             default: {
@@ -897,8 +902,8 @@ private:
                 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);
                 const std::string sampler = GetSampler(instr.sampler);
                 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
-                // Add an extra scope and declare the texture coords inside to prevent overwriting
-                // them in case they are used as outputs of the texs instruction.
+                // Add an extra scope and declare the texture coords inside to prevent
+                // overwriting them in case they are used as outputs of the texs instruction.
                 shader.AddLine("{");
                 ++shader.scope;
                 shader.AddLine(coord);
@@ -961,8 +966,8 @@ private:
                          '(' + predicate + ") " + combiner + " (" + second_pred + ')');
 
             if (instr.fsetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
-                // Set the secondary predicate to the result of !Predicate OP SecondPredicate, if
-                // enabled
+                // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
+                // if enabled
                 SetPredicate(instr.fsetp.pred0,
                              "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
             }