diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
index c22a282dc..c837632ec 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
@@ -43,9 +43,13 @@ namespace Ryujinx.Graphics.Gal.Shader
         public const string FlipUniformName = "flip";
         public const string InstanceUniformName = "instance";
 
-        public const string ProgramName  = "program";
-        public const string ProgramAName = ProgramName + "_a";
-        public const string ProgramBName = ProgramName + "_b";
+        public const string BasicBlockName  = "bb";
+        public const string BasicBlockAName = BasicBlockName + "_a";
+        public const string BasicBlockBName = BasicBlockName + "_b";
+
+        public const int SsyStackSize = 16;
+        public const string SsyStackName = "ssy_stack";
+        public const string SsyCursorName = "ssy_cursor";
 
         private string[] StagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" };
 
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
index 984684f16..104fd7235 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
@@ -155,18 +155,19 @@ namespace Ryujinx.Graphics.Gal.Shader
             PrintDeclOutAttributes();
             PrintDeclGprs();
             PrintDeclPreds();
+            PrintDeclSsy();
 
             if (BlocksB != null)
             {
-                PrintBlockScope(Blocks[0],  null, null, "void " + GlslDecl.ProgramAName + "()", IdentationStr);
+                PrintBlockScope(Blocks, GlslDecl.BasicBlockAName);
 
                 SB.AppendLine();
 
-                PrintBlockScope(BlocksB[0], null, null, "void " + GlslDecl.ProgramBName + "()", IdentationStr);
+                PrintBlockScope(BlocksB, GlslDecl.BasicBlockBName);
             }
             else
             {
-                PrintBlockScope(Blocks[0],  null, null, "void " + GlslDecl.ProgramName + "()", IdentationStr);
+                PrintBlockScope(Blocks, GlslDecl.BasicBlockName);
             }
 
             SB.AppendLine();
@@ -357,6 +358,13 @@ namespace Ryujinx.Graphics.Gal.Shader
             PrintDecls(Decl.Preds, "bool");
         }
 
+        private void PrintDeclSsy()
+        {
+            SB.AppendLine("uint " + GlslDecl.SsyCursorName + ";");
+
+            SB.AppendLine("uint " + GlslDecl.SsyStackName + "[" + GlslDecl.SsyStackSize + "];" + Environment.NewLine);
+        }
+
         private void PrintDecls(IReadOnlyDictionary<int, ShaderDeclInfo> Dict, string CustomType = null, string Suffix = "")
         {
             foreach (ShaderDeclInfo DeclInfo in Dict.Values.OrderBy(DeclKeySelector))
@@ -432,14 +440,16 @@ namespace Ryujinx.Graphics.Gal.Shader
                 }
             }
 
+            SB.AppendLine(IdentationStr + "uint pc;");
+
             if (BlocksB != null)
             {
-                SB.AppendLine(IdentationStr + GlslDecl.ProgramAName + "();");
-                SB.AppendLine(IdentationStr + GlslDecl.ProgramBName + "();");
+                PrintProgram(Blocks,  GlslDecl.BasicBlockAName);
+                PrintProgram(BlocksB, GlslDecl.BasicBlockBName);
             }
             else
             {
-                SB.AppendLine(IdentationStr + GlslDecl.ProgramName + "();");
+                PrintProgram(Blocks, GlslDecl.BasicBlockName);
             }
 
             if (Decl.ShaderType != GalShaderType.Geometry)
@@ -477,6 +487,32 @@ namespace Ryujinx.Graphics.Gal.Shader
             SB.AppendLine("}");
         }
 
+        private void PrintProgram(ShaderIrBlock[] Blocks, string Name)
+        {
+            const string Ident1 = IdentationStr;
+            const string Ident2 = Ident1 + IdentationStr;
+            const string Ident3 = Ident2 + IdentationStr;
+            const string Ident4 = Ident3 + IdentationStr;
+
+            SB.AppendLine(Ident1 + "pc = " + GetBlockPosition(Blocks[0]) + ";");
+            SB.AppendLine(Ident1 + "do {");
+            SB.AppendLine(Ident2 + "switch (pc) {");
+
+            foreach (ShaderIrBlock Block in Blocks)
+            {
+                string FunctionName = Block.Position.ToString("x8");
+
+                SB.AppendLine(Ident3 + "case 0x" + FunctionName + ": pc = " + Name + "_" + FunctionName + "(); break;");
+            }
+
+            SB.AppendLine(Ident3 + "default:");
+            SB.AppendLine(Ident4 + "pc = 0;");
+            SB.AppendLine(Ident4 + "break;");
+
+            SB.AppendLine(Ident2 + "}");
+            SB.AppendLine(Ident1 + "} while (pc != 0);");
+        }
+
         private void PrintAttrToOutput(string Identation = IdentationStr)
         {
             foreach (KeyValuePair<int, ShaderDeclInfo> KV in Decl.OutAttributes)
@@ -510,193 +546,145 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        private void PrintBlockScope(
-            ShaderIrBlock Block,
-            ShaderIrBlock EndBlock,
-            ShaderIrBlock LoopBlock,
-            string        ScopeName,
-            string        Identation,
-            bool          IsDoWhile = false)
+        private void PrintBlockScope(ShaderIrBlock[] Blocks, string Name)
         {
-            string UpIdent = Identation.Substring(0, Identation.Length - IdentationStr.Length);
+            foreach (ShaderIrBlock Block in Blocks)
+            {
+                SB.AppendLine("uint " + Name + "_" + Block.Position.ToString("x8") + "() {");
 
-            if (IsDoWhile)
-            {
-                SB.AppendLine(UpIdent + "do {");
-            }
-            else
-            {
-                SB.AppendLine(UpIdent + ScopeName + " {");
-            }
+                PrintNodes(Block, Block.GetNodes());
 
-            while (Block != null && Block != EndBlock)
-            {
-                ShaderIrNode[] Nodes = Block.GetNodes();
-
-                Block = PrintNodes(Block, EndBlock, LoopBlock, Identation, Nodes);
-            }
-
-            if (IsDoWhile)
-            {
-                SB.AppendLine(UpIdent + "} " + ScopeName + ";");
-            }
-            else
-            {
-                SB.AppendLine(UpIdent + "}");
+                SB.AppendLine("}" + Environment.NewLine);
             }
         }
 
-        private ShaderIrBlock PrintNodes(
-            ShaderIrBlock         Block,
-            ShaderIrBlock         EndBlock,
-            ShaderIrBlock         LoopBlock,
-            string                Identation,
-            params ShaderIrNode[] Nodes)
+        private void PrintNode(ShaderIrBlock Block, ShaderIrNode Node, string Identation)
         {
-            /*
-             * Notes about control flow and if-else/loop generation:
-             * The code assumes that the program has sane control flow,
-             * that is, there's no jumps to a location after another jump or
-             * jump target (except for the end of an if-else block), and backwards
-             * jumps to a location before the last loop dominator.
-             * Such cases needs to be transformed on a step before the GLSL code
-             * generation to ensure that we have sane graphs to work with.
-             * TODO: Such transformation is not yet implemented.
-             */
-            string NewIdent = Identation + IdentationStr;
-
-            ShaderIrBlock LoopTail = GetLoopTailBlock(Block);
-
-            if (LoopTail != null && LoopBlock != Block)
+            if (Node is ShaderIrCond Cond)
             {
-                //Shoock! kuma shock! We have a loop here!
-                //The entire sequence needs to be inside a do-while block.
-                ShaderIrBlock LoopEnd = GetDownBlock(LoopTail);
+                string IfExpr = GetSrcExpr(Cond.Pred, true);
 
-                PrintBlockScope(Block, LoopEnd, Block, "while (false)", NewIdent, IsDoWhile: true);
+                if (Cond.Not)
+                {
+                    IfExpr = "!(" + IfExpr + ")";
+                }
 
-                return LoopEnd;
+                SB.AppendLine(Identation + "if (" + IfExpr + ") {");
+
+                if (Cond.Child is ShaderIrOp Op && Op.Inst == ShaderIrInst.Bra)
+                {
+                    SB.AppendLine(Identation + IdentationStr + "return " + GetBlockPosition(Block.Branch) + ";");
+                }
+                else
+                {
+                    PrintNode(Block, Cond.Child, Identation + IdentationStr);
+                }
+
+                SB.AppendLine(Identation + "}");
             }
-
-            foreach (ShaderIrNode Node in Nodes)
+            else if (Node is ShaderIrAsg Asg)
             {
-                if (Node is ShaderIrCond Cond)
+                if (IsValidOutOper(Asg.Dst))
                 {
-                    string IfExpr = GetSrcExpr(Cond.Pred, true);
+                    string Expr = GetSrcExpr(Asg.Src, true);
 
-                    if (Cond.Not)
-                    {
-                        IfExpr = "!(" + IfExpr + ")";
-                    }
+                    Expr = GetExprWithCast(Asg.Dst, Asg.Src, Expr);
 
-                    if (Cond.Child is ShaderIrOp Op && Op.Inst == ShaderIrInst.Bra)
-                    {
-                        //Branch is a loop branch and would result in infinite recursion.
-                        if (Block.Branch.Position <= Block.Position)
-                        {
-                            SB.AppendLine(Identation + "if (" + IfExpr + ") {");
-
-                            SB.AppendLine(Identation + IdentationStr + "continue;");
-
-                            SB.AppendLine(Identation + "}");
-
-                            continue;
-                        }
-
-                        string SubScopeName = "if (!" + IfExpr + ")";
-
-                        PrintBlockScope(Block.Next, Block.Branch, LoopBlock, SubScopeName, NewIdent);
-
-                        ShaderIrBlock IfElseEnd = GetUpBlock(Block.Branch).Branch;
-
-                        if (IfElseEnd?.Position > Block.Branch.Position)
-                        {
-                            PrintBlockScope(Block.Branch, IfElseEnd, LoopBlock, "else", NewIdent);
-
-                            return IfElseEnd;
-                        }
-
-                        return Block.Branch;
-                    }
-                    else
-                    {
-                        SB.AppendLine(Identation + "if (" + IfExpr + ") {");
-
-                        PrintNodes(Block, EndBlock, LoopBlock, NewIdent, Cond.Child);
-
-                        SB.AppendLine(Identation + "}");
-                    }
+                    SB.AppendLine(Identation + GetDstOperName(Asg.Dst) + " = " + Expr + ";");
                 }
-                else if (Node is ShaderIrAsg Asg)
+            }
+            else if (Node is ShaderIrOp Op)
+            {
+                switch (Op.Inst)
                 {
-                    if (IsValidOutOper(Asg.Dst))
+                    case ShaderIrInst.Bra:
                     {
-                        string Expr = GetSrcExpr(Asg.Src, true);
+                        SB.AppendLine(Identation + "return " + GetBlockPosition(Block.Branch) + ";");
 
-                        Expr = GetExprWithCast(Asg.Dst, Asg.Src, Expr);
+                        break;
+                    }
 
-                        SB.AppendLine(Identation + GetDstOperName(Asg.Dst) + " = " + Expr + ";");
-                    }
-                }
-                else if (Node is ShaderIrOp Op)
-                {
-                    if (Op.Inst == ShaderIrInst.Bra)
-                    {
-                        if (Block.Branch.Position <= Block.Position)
-                        {
-                            SB.AppendLine(Identation + "continue;");
-                        }
-                    }
-                    else if (Op.Inst == ShaderIrInst.Emit)
+                    case ShaderIrInst.Emit:
                     {
                         PrintAttrToOutput(Identation);
 
                         SB.AppendLine(Identation + "EmitVertex();");
+
+                        break;
                     }
-                    else
+
+                    case ShaderIrInst.Ssy:
                     {
+                        string StackIndex = GlslDecl.SsyStackName + "[" + GlslDecl.SsyCursorName + "]";
+
+                        int TargetPosition = (Op.OperandA as ShaderIrOperImm).Value;
+
+                        string Target = "0x" + TargetPosition.ToString("x8") + "u";
+
+                        SB.AppendLine(Identation + StackIndex + " = " + Target + ";");
+
+                        SB.AppendLine(Identation + GlslDecl.SsyCursorName + "++;");
+
+                        break;
+                    }
+
+                    case ShaderIrInst.Sync:
+                    {
+                        SB.AppendLine(Identation + GlslDecl.SsyCursorName + "--;");
+
+                        string Target = GlslDecl.SsyStackName + "[" + GlslDecl.SsyCursorName + "]";
+
+                        SB.AppendLine(Identation + "return " + Target + ";");
+
+                        break;
+                    }
+
+                    default:
                         SB.AppendLine(Identation + GetSrcExpr(Op, true) + ";");
-                    }
-                }
-                else if (Node is ShaderIrCmnt Cmnt)
-                {
-                    SB.AppendLine(Identation + "// " + Cmnt.Comment);
-                }
-                else
-                {
-                    throw new InvalidOperationException();
+                        break;
                 }
             }
-
-            return Block.Next;
-        }
-
-        private ShaderIrBlock GetUpBlock(ShaderIrBlock Block)
-        {
-            return Blocks.FirstOrDefault(x => x.EndPosition == Block.Position);
-        }
-
-        private ShaderIrBlock GetDownBlock(ShaderIrBlock Block)
-        {
-            return Blocks.FirstOrDefault(x => x.Position == Block.EndPosition);
-        }
-
-        private ShaderIrBlock GetLoopTailBlock(ShaderIrBlock LoopHead)
-        {
-            ShaderIrBlock Tail = null;
-
-            foreach (ShaderIrBlock Block in LoopHead.Sources)
+            else if (Node is ShaderIrCmnt Cmnt)
             {
-                if (Block.Position >= LoopHead.Position)
-                {
-                    if (Tail == null || Tail.Position < Block.Position)
-                    {
-                        Tail = Block;
-                    }
-                }
+                SB.AppendLine(Identation + "// " + Cmnt.Comment);
+            }
+            else
+            {
+                throw new InvalidOperationException();
+            }
+        }
+
+        private void PrintNodes(ShaderIrBlock Block, ShaderIrNode[] Nodes)
+        {
+            foreach (ShaderIrNode Node in Nodes)
+            {
+                PrintNode(Block, Node, IdentationStr);
             }
 
-            return Tail;
+            if (Nodes.Length > 0)
+            {
+                ShaderIrNode Last = Nodes[Nodes.Length - 1];
+
+                bool UnconditionalFlowChange = false;
+
+                if (Last is ShaderIrOp Op)
+                {
+                    switch (Op.Inst)
+                    {
+                        case ShaderIrInst.Bra:
+                        case ShaderIrInst.Exit:
+                        case ShaderIrInst.Kil:
+                        case ShaderIrInst.Sync:
+                            UnconditionalFlowChange = true;
+                            break;
+                    }
+                }
+
+                if (!UnconditionalFlowChange)
+                {
+                    SB.AppendLine(IdentationStr + "return " + GetBlockPosition(Block.Next) + ";");
+                }
+            }
         }
 
         private bool IsValidOutOper(ShaderIrNode Node)
@@ -1006,7 +994,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 
         private string GetCnumExpr(ShaderIrOp Op) => GetUnaryCall(Op, "!isnan");
 
-        private string GetExitExpr(ShaderIrOp Op) => "return";
+        private string GetExitExpr(ShaderIrOp Op) => "return 0u";
 
         private string GetFcosExpr(ShaderIrOp Op) => GetUnaryCall(Op, "cos");
 
@@ -1351,5 +1339,17 @@ namespace Ryujinx.Graphics.Gal.Shader
 
             throw new ArgumentException(nameof(Node));
         }
+
+        private static string GetBlockPosition(ShaderIrBlock Block)
+        {
+            if (Block != null)
+            {
+                return "0x" + Block.Position.ToString("x8") + "u";
+            }
+            else
+            {
+                return "0u";
+            }
+        }
     }
 }
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs
index ef0fd78bd..73625f65f 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs
@@ -1,4 +1,4 @@
 namespace Ryujinx.Graphics.Gal.Shader
 {
-    delegate void ShaderDecodeFunc(ShaderIrBlock Block, long OpCode);
+    delegate void ShaderDecodeFunc(ShaderIrBlock Block, long OpCode, long Position);
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
index b60da7c1c..5eb761dab 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
@@ -6,32 +6,32 @@ namespace Ryujinx.Graphics.Gal.Shader
 {
     static partial class ShaderDecode
     {
-        public static void Bfe_C(ShaderIrBlock Block, long OpCode)
+        public static void Bfe_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitBfe(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Bfe_I(ShaderIrBlock Block, long OpCode)
+        public static void Bfe_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitBfe(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Bfe_R(ShaderIrBlock Block, long OpCode)
+        public static void Bfe_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitBfe(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Fadd_C(ShaderIrBlock Block, long OpCode)
+        public static void Fadd_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFadd(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Fadd_I(ShaderIrBlock Block, long OpCode)
+        public static void Fadd_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFadd(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Fadd_I32(ShaderIrBlock Block, long OpCode)
+        public static void Fadd_I32(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperA = GetOperGpr8     (OpCode);
             ShaderIrNode OperB = GetOperImmf32_20(OpCode);
@@ -49,47 +49,47 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
-        public static void Fadd_R(ShaderIrBlock Block, long OpCode)
+        public static void Fadd_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFadd(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Ffma_CR(ShaderIrBlock Block, long OpCode)
+        public static void Ffma_CR(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFfma(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Ffma_I(ShaderIrBlock Block, long OpCode)
+        public static void Ffma_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFfma(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Ffma_RC(ShaderIrBlock Block, long OpCode)
+        public static void Ffma_RC(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFfma(Block, OpCode, ShaderOper.RC);
         }
 
-        public static void Ffma_RR(ShaderIrBlock Block, long OpCode)
+        public static void Ffma_RR(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFfma(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Fmnmx_C(ShaderIrBlock Block, long OpCode)
+        public static void Fmnmx_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmnmx(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Fmnmx_I(ShaderIrBlock Block, long OpCode)
+        public static void Fmnmx_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmnmx(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Fmnmx_R(ShaderIrBlock Block, long OpCode)
+        public static void Fmnmx_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmnmx(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Fmul_I32(ShaderIrBlock Block, long OpCode)
+        public static void Fmul_I32(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperA = GetOperGpr8     (OpCode);
             ShaderIrNode OperB = GetOperImmf32_20(OpCode);
@@ -99,62 +99,62 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
-        public static void Fmul_C(ShaderIrBlock Block, long OpCode)
+        public static void Fmul_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmul(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Fmul_I(ShaderIrBlock Block, long OpCode)
+        public static void Fmul_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmul(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Fmul_R(ShaderIrBlock Block, long OpCode)
+        public static void Fmul_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFmul(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Fset_C(ShaderIrBlock Block, long OpCode)
+        public static void Fset_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFset(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Fset_I(ShaderIrBlock Block, long OpCode)
+        public static void Fset_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFset(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Fset_R(ShaderIrBlock Block, long OpCode)
+        public static void Fset_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFset(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Fsetp_C(ShaderIrBlock Block, long OpCode)
+        public static void Fsetp_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFsetp(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Fsetp_I(ShaderIrBlock Block, long OpCode)
+        public static void Fsetp_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFsetp(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Fsetp_R(ShaderIrBlock Block, long OpCode)
+        public static void Fsetp_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitFsetp(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Iadd_C(ShaderIrBlock Block, long OpCode)
+        public static void Iadd_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Iadd_I(ShaderIrBlock Block, long OpCode)
+        public static void Iadd_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Iadd_I32(ShaderIrBlock Block, long OpCode)
+        public static void Iadd_I32(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperA = GetOperGpr8    (OpCode);
             ShaderIrNode OperB = GetOperImm32_20(OpCode);
@@ -168,42 +168,42 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
-        public static void Iadd_R(ShaderIrBlock Block, long OpCode)
+        public static void Iadd_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Iadd3_C(ShaderIrBlock Block, long OpCode)
+        public static void Iadd3_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd3(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Iadd3_I(ShaderIrBlock Block, long OpCode)
+        public static void Iadd3_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd3(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Iadd3_R(ShaderIrBlock Block, long OpCode)
+        public static void Iadd3_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIadd3(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Imnmx_C(ShaderIrBlock Block, long OpCode)
+        public static void Imnmx_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitImnmx(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Imnmx_I(ShaderIrBlock Block, long OpCode)
+        public static void Imnmx_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitImnmx(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Imnmx_R(ShaderIrBlock Block, long OpCode)
+        public static void Imnmx_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitImnmx(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Ipa(ShaderIrBlock Block, long OpCode)
+        public static void Ipa(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperA = GetOperAbuf28(OpCode);
             ShaderIrNode OperB = GetOperGpr20 (OpCode);
@@ -213,52 +213,52 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
-        public static void Iscadd_C(ShaderIrBlock Block, long OpCode)
+        public static void Iscadd_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIscadd(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Iscadd_I(ShaderIrBlock Block, long OpCode)
+        public static void Iscadd_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIscadd(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Iscadd_R(ShaderIrBlock Block, long OpCode)
+        public static void Iscadd_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIscadd(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Iset_C(ShaderIrBlock Block, long OpCode)
+        public static void Iset_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIset(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Iset_I(ShaderIrBlock Block, long OpCode)
+        public static void Iset_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIset(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Iset_R(ShaderIrBlock Block, long OpCode)
+        public static void Iset_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIset(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Isetp_C(ShaderIrBlock Block, long OpCode)
+        public static void Isetp_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIsetp(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Isetp_I(ShaderIrBlock Block, long OpCode)
+        public static void Isetp_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIsetp(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Isetp_R(ShaderIrBlock Block, long OpCode)
+        public static void Isetp_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitIsetp(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Lop_I32(ShaderIrBlock Block, long OpCode)
+        public static void Lop_I32(ShaderIrBlock Block, long OpCode, long Position)
         {
             int SubOp = (int)(OpCode >> 53) & 3;
 
@@ -292,22 +292,22 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        public static void Lop_C(ShaderIrBlock Block, long OpCode)
+        public static void Lop_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitLop(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Lop_I(ShaderIrBlock Block, long OpCode)
+        public static void Lop_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitLop(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Lop_R(ShaderIrBlock Block, long OpCode)
+        public static void Lop_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitLop(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Mufu(ShaderIrBlock Block, long OpCode)
+        public static void Mufu(ShaderIrBlock Block, long OpCode, long Position)
         {
             int SubOp = (int)(OpCode >> 20) & 0xf;
 
@@ -336,7 +336,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
-        public static void Psetp(ShaderIrBlock Block, long OpCode)
+        public static void Psetp(ShaderIrBlock Block, long OpCode, long Position)
         {
             bool NegA = ((OpCode >> 15) & 1) != 0;
             bool NegB = ((OpCode >> 32) & 1) != 0;
@@ -390,47 +390,47 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));
         }
 
-        public static void Rro_C(ShaderIrBlock Block, long OpCode)
+        public static void Rro_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitRro(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Rro_I(ShaderIrBlock Block, long OpCode)
+        public static void Rro_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitRro(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void Rro_R(ShaderIrBlock Block, long OpCode)
+        public static void Rro_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitRro(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Shl_C(ShaderIrBlock Block, long OpCode)
+        public static void Shl_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.CR, ShaderIrInst.Lsl);
         }
 
-        public static void Shl_I(ShaderIrBlock Block, long OpCode)
+        public static void Shl_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.Imm, ShaderIrInst.Lsl);
         }
 
-        public static void Shl_R(ShaderIrBlock Block, long OpCode)
+        public static void Shl_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Lsl);
         }
 
-        public static void Shr_C(ShaderIrBlock Block, long OpCode)
+        public static void Shr_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.CR, GetShrInst(OpCode));
         }
 
-        public static void Shr_I(ShaderIrBlock Block, long OpCode)
+        public static void Shr_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.Imm, GetShrInst(OpCode));
         }
 
-        public static void Shr_R(ShaderIrBlock Block, long OpCode)
+        public static void Shr_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitAluBinary(Block, OpCode, ShaderOper.RR, GetShrInst(OpCode));
         }
@@ -442,7 +442,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             return Signed ? ShaderIrInst.Asr : ShaderIrInst.Lsr;
         }
 
-        public static void Vmad(ShaderIrBlock Block, long OpCode)
+        public static void Vmad(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperA = GetOperGpr8(OpCode);
 
@@ -477,22 +477,22 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Final), OpCode));
         }
 
-        public static void Xmad_CR(ShaderIrBlock Block, long OpCode)
+        public static void Xmad_CR(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitXmad(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Xmad_I(ShaderIrBlock Block, long OpCode)
+        public static void Xmad_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitXmad(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Xmad_RC(ShaderIrBlock Block, long OpCode)
+        public static void Xmad_RC(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitXmad(Block, OpCode, ShaderOper.RC);
         }
 
-        public static void Xmad_RR(ShaderIrBlock Block, long OpCode)
+        public static void Xmad_RR(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitXmad(Block, OpCode, ShaderOper.RR);
         }
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs
index 8d0925a32..2c699a1b8 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs
@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 {
     static partial class ShaderDecode
     {
-        public static void Bra(ShaderIrBlock Block, long OpCode)
+        public static void Bra(ShaderIrBlock Block, long OpCode, long Position)
         {
             if ((OpCode & 0x20) != 0)
             {
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrOp(ShaderIrInst.Bra, Imm), OpCode));
         }
 
-        public static void Exit(ShaderIrBlock Block, long OpCode)
+        public static void Exit(ShaderIrBlock Block, long OpCode, long Position)
         {
             int CCode = (int)OpCode & 0x1f;
 
@@ -34,9 +34,34 @@ namespace Ryujinx.Graphics.Gal.Shader
 
         }
 
-        public static void Kil(ShaderIrBlock Block, long OpCode)
+        public static void Kil(ShaderIrBlock Block, long OpCode, long Position)
         {
             Block.AddNode(GetPredNode(new ShaderIrOp(ShaderIrInst.Kil), OpCode));
         }
+
+        public static void Ssy(ShaderIrBlock Block, long OpCode, long Position)
+        {
+            if ((OpCode & 0x20) != 0)
+            {
+                //This reads the target offset from the constant buffer.
+                //Almost impossible to support with GLSL.
+                throw new NotImplementedException();
+            }
+
+            int Offset = ((int)(OpCode >> 20) << 8) >> 8;
+
+            int Target = (int)(Position + Offset);
+
+            ShaderIrOperImm Imm = new ShaderIrOperImm(Target);
+
+            Block.AddNode(new ShaderIrOp(ShaderIrInst.Ssy, Imm));
+        }
+
+        public static void Sync(ShaderIrBlock Block, long OpCode, long Position)
+        {
+            //TODO: Implement Sync condition codes
+
+            Block.AddNode(GetPredNode(new ShaderIrOp(ShaderIrInst.Sync), OpCode));
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
index a183b0c69..2ae58bf89 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs
@@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
         };
 
-        public static void Ld_A(ShaderIrBlock Block, long OpCode)
+        public static void Ld_A(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
 
@@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        public static void Ld_C(ShaderIrBlock Block, long OpCode)
+        public static void Ld_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             int CbufPos   = (int)(OpCode >> 22) & 0x3fff;
             int CbufIndex = (int)(OpCode >> 36) & 0x1f;
@@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        public static void St_A(ShaderIrBlock Block, long OpCode)
+        public static void St_A(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
 
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        public static void Texq(ShaderIrBlock Block, long OpCode)
+        public static void Texq(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrNode OperD = GetOperGpr0(OpCode);
             ShaderIrNode OperA = GetOperGpr8(OpCode);
@@ -132,12 +132,12 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(OperA, Op1), OpCode)); //Is this right?
         }
 
-        public static void Tex(ShaderIrBlock Block, long OpCode)
+        public static void Tex(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitTex(Block, OpCode, GprHandle: false);
         }
 
-        public static void Tex_B(ShaderIrBlock Block, long OpCode)
+        public static void Tex_B(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitTex(Block, OpCode, GprHandle: true);
         }
@@ -202,12 +202,12 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
         }
 
-        public static void Texs(ShaderIrBlock Block, long OpCode)
+        public static void Texs(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitTexs(Block, OpCode, ShaderIrInst.Texs);
         }
 
-        public static void Tlds(ShaderIrBlock Block, long OpCode)
+        public static void Tlds(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitTexs(Block, OpCode, ShaderIrInst.Txlf);
         }
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
index c6b71fb01..aef92c5a9 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
@@ -25,67 +25,67 @@ namespace Ryujinx.Graphics.Gal.Shader
             F64 = 3
         }
 
-        public static void F2f_C(ShaderIrBlock Block, long OpCode)
+        public static void F2f_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2f(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void F2f_I(ShaderIrBlock Block, long OpCode)
+        public static void F2f_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2f(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void F2f_R(ShaderIrBlock Block, long OpCode)
+        public static void F2f_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2f(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void F2i_C(ShaderIrBlock Block, long OpCode)
+        public static void F2i_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2i(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void F2i_I(ShaderIrBlock Block, long OpCode)
+        public static void F2i_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2i(Block, OpCode, ShaderOper.Immf);
         }
 
-        public static void F2i_R(ShaderIrBlock Block, long OpCode)
+        public static void F2i_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitF2i(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void I2f_C(ShaderIrBlock Block, long OpCode)
+        public static void I2f_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2f(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void I2f_I(ShaderIrBlock Block, long OpCode)
+        public static void I2f_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2f(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void I2f_R(ShaderIrBlock Block, long OpCode)
+        public static void I2f_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2f(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void I2i_C(ShaderIrBlock Block, long OpCode)
+        public static void I2i_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2i(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void I2i_I(ShaderIrBlock Block, long OpCode)
+        public static void I2i_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2i(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void I2i_R(ShaderIrBlock Block, long OpCode)
+        public static void I2i_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitI2i(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Isberd(ShaderIrBlock Block, long OpCode)
+        public static void Isberd(ShaderIrBlock Block, long OpCode, long Position)
         {
             //This instruction seems to be used to translate from an address to a vertex index in a GS
             //Stub it as such
@@ -95,50 +95,50 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), GetOperGpr8(OpCode)), OpCode));
         }
 
-        public static void Mov_C(ShaderIrBlock Block, long OpCode)
+        public static void Mov_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrOperCbuf Cbuf = GetOperCbuf34(OpCode);
 
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Cbuf), OpCode));
         }
 
-        public static void Mov_I(ShaderIrBlock Block, long OpCode)
+        public static void Mov_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrOperImm Imm = GetOperImm19_20(OpCode);
 
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Imm), OpCode));
         }
 
-        public static void Mov_I32(ShaderIrBlock Block, long OpCode)
+        public static void Mov_I32(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrOperImm Imm = GetOperImm32_20(OpCode);
 
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Imm), OpCode));
         }
 
-        public static void Mov_R(ShaderIrBlock Block, long OpCode)
+        public static void Mov_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             ShaderIrOperGpr Gpr = GetOperGpr20(OpCode);
 
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Gpr), OpCode));
         }
 
-        public static void Sel_C(ShaderIrBlock Block, long OpCode)
+        public static void Sel_C(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitSel(Block, OpCode, ShaderOper.CR);
         }
 
-        public static void Sel_I(ShaderIrBlock Block, long OpCode)
+        public static void Sel_I(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitSel(Block, OpCode, ShaderOper.Imm);
         }
 
-        public static void Sel_R(ShaderIrBlock Block, long OpCode)
+        public static void Sel_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             EmitSel(Block, OpCode, ShaderOper.RR);
         }
 
-        public static void Mov_S(ShaderIrBlock Block, long OpCode)
+        public static void Mov_S(ShaderIrBlock Block, long OpCode, long Position)
         {
             Block.AddNode(new ShaderIrCmnt("Stubbed."));
 
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs
index f1be005f9..4300c32e3 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 {
     static partial class ShaderDecode
     {
-        public static void Out_R(ShaderIrBlock Block, long OpCode)
+        public static void Out_R(ShaderIrBlock Block, long OpCode, long Position)
         {
             //TODO: Those registers have to be used for something
             ShaderIrOperGpr Gpr0  = GetOperGpr0(OpCode);
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs
index 98f371b57..81d8f3126 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs
@@ -50,17 +50,29 @@ namespace Ryujinx.Graphics.Gal.Shader
                 {
                     ShaderIrNode LastNode = Current.GetLastNode();
 
-                    ShaderIrOp Op = GetInnermostOp(LastNode);
+                    ShaderIrOp InnerOp = GetInnermostOp(LastNode);
 
-                    if (Op?.Inst == ShaderIrInst.Bra)
+                    if (InnerOp?.Inst == ShaderIrInst.Bra)
                     {
-                        int Offset = ((ShaderIrOperImm)Op.OperandA).Value;
+                        int Offset = ((ShaderIrOperImm)InnerOp.OperandA).Value;
 
                         long Target = Current.EndPosition + Offset;
 
                         Current.Branch = Enqueue(Target, Current);
                     }
 
+                    foreach (ShaderIrNode Node in Current.Nodes)
+                    {
+                        if (Node is ShaderIrOp CurrOp && CurrOp.Inst == ShaderIrInst.Ssy)
+                        {
+                            int Offset = ((ShaderIrOperImm)CurrOp.OperandA).Value;
+
+                            long Target = Offset;
+
+                            Current.Branch = Enqueue(Target, Current);
+                        }
+                    }
+
                     if (NodeHasNext(LastNode))
                     {
                         Current.Next = Enqueue(Current.EndPosition);
@@ -157,7 +169,7 @@ namespace Ryujinx.Graphics.Gal.Shader
                     {
                         int Offset = ((int)(OpCode >> 20) << 8) >> 8;
 
-                        long Target = Position + Offset;
+                        long Target = Position + Offset - Beginning;
 
                         DbgOpCode += " (0x" + Target.ToString("x16") + ")";
                     }
@@ -170,7 +182,7 @@ namespace Ryujinx.Graphics.Gal.Shader
                     continue;
                 }
 
-                Decode(Block, OpCode);
+                Decode(Block, OpCode, Position);
             }
             while (!IsFlowChange(Block.GetLastNode()));
 
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs
index d197835a7..35dea6121 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderIrInst.cs
@@ -84,6 +84,8 @@ namespace Ryujinx.Graphics.Gal.Shader
         Bra,
         Exit,
         Kil,
+        Ssy,
+        Sync,
 
         Emit,
         Cut
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
index 95b8e467d..1e76eab16 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
@@ -112,7 +112,9 @@ namespace Ryujinx.Graphics.Gal.Shader
             Set("0100110000101x", ShaderDecode.Shr_C);
             Set("0011100x00101x", ShaderDecode.Shr_I);
             Set("0101110000101x", ShaderDecode.Shr_R);
+            Set("1110001010010x", ShaderDecode.Ssy);
             Set("1110111111110x", ShaderDecode.St_A);
+            Set("1111000011111x", ShaderDecode.Sync);
             Set("110000xxxx111x", ShaderDecode.Tex);
             Set("1101111010111x", ShaderDecode.Tex_B);
             Set("1101111101001x", ShaderDecode.Texq);