diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
index 2e022fbd44..a44073513c 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs
@@ -144,6 +144,50 @@ namespace Ryujinx.Graphics.Gal.Shader
             EmitFsetp(Block, OpCode, ShaderOper.RR);
         }
 
+        public static void Iadd_C(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd(Block, OpCode, ShaderOper.CR);
+        }
+
+        public static void Iadd_I(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd(Block, OpCode, ShaderOper.Imm);
+        }
+
+        public static void Iadd_I32(ShaderIrBlock Block, long OpCode)
+        {
+            ShaderIrNode OperA = GetOperGpr8    (OpCode);
+            ShaderIrNode OperB = GetOperImm32_20(OpCode);
+
+            bool NegA = ((OpCode >> 56) & 1) != 0;
+
+            OperA = GetAluIneg(OperA, NegA);
+
+            ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Add, OperA, OperB);
+
+            Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
+        }
+
+        public static void Iadd_R(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd(Block, OpCode, ShaderOper.RR);
+        }
+
+        public static void Iadd3_C(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd3(Block, OpCode, ShaderOper.CR);
+        }
+
+        public static void Iadd3_I(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd3(Block, OpCode, ShaderOper.Imm);
+        }
+
+        public static void Iadd3_R(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIadd3(Block, OpCode, ShaderOper.RR);
+        }
+
         public static void Imnmx_C(ShaderIrBlock Block, long OpCode)
         {
             EmitImnmx(Block, OpCode, ShaderOper.CR);
@@ -184,6 +228,21 @@ namespace Ryujinx.Graphics.Gal.Shader
             EmitIscadd(Block, OpCode, ShaderOper.RR);
         }
 
+        public static void Iset_C(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIset(Block, OpCode, ShaderOper.CR);
+        }
+
+        public static void Iset_I(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIset(Block, OpCode, ShaderOper.Imm);
+        }
+
+        public static void Iset_R(ShaderIrBlock Block, long OpCode)
+        {
+            EmitIset(Block, OpCode, ShaderOper.RR);
+        }
+
         public static void Isetp_C(ShaderIrBlock Block, long OpCode)
         {
             EmitIsetp(Block, OpCode, ShaderOper.CR);
@@ -215,13 +274,13 @@ namespace Ryujinx.Graphics.Gal.Shader
                 case 2: Inst = ShaderIrInst.Xor; break;
             }
 
-            ShaderIrNode OperA = GetAluNot(GetOperGpr8(OpCode), InvA);
+            ShaderIrNode OperB = GetAluNot(GetOperImm32_20(OpCode), InvB);
 
             //SubOp == 3 is pass, used by the not instruction
             //which just moves the inverted register value.
             if (SubOp < 3)
             {
-                ShaderIrNode OperB = GetAluNot(GetOperImm32_20(OpCode), InvB);
+                ShaderIrNode OperA = GetAluNot(GetOperGpr8(OpCode), InvA);
 
                 ShaderIrOp Op = new ShaderIrOp(Inst, OperA, OperB);
 
@@ -229,10 +288,25 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
             else
             {
-                Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperA), OpCode));
+                Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperB), OpCode));
             }
         }
 
+        public static void Lop_C(ShaderIrBlock Block, long OpCode)
+        {
+            EmitLop(Block, OpCode, ShaderOper.CR);
+        }
+
+        public static void Lop_I(ShaderIrBlock Block, long OpCode)
+        {
+            EmitLop(Block, OpCode, ShaderOper.Imm);
+        }
+
+        public static void Lop_R(ShaderIrBlock Block, long OpCode)
+        {
+            EmitLop(Block, OpCode, ShaderOper.RR);
+        }
+
         public static void Mufu(ShaderIrBlock Block, long OpCode)
         {
             int SubOp = (int)(OpCode >> 20) & 0xf;
@@ -533,6 +607,92 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
         }
 
+        private static void EmitIadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+        {
+            ShaderIrNode OperA = GetOperGpr8(OpCode);
+            ShaderIrNode OperB;
+
+            switch (Oper)
+            {
+                case ShaderOper.CR:  OperB = GetOperCbuf34  (OpCode); break;
+                case ShaderOper.Imm: OperB = GetOperImm19_20(OpCode); break;
+                case ShaderOper.RR:  OperB = GetOperGpr20   (OpCode); break;
+
+                default: throw new ArgumentException(nameof(Oper));
+            }
+
+            bool NegA = ((OpCode >> 49) & 1) != 0;
+            bool NegB = ((OpCode >> 48) & 1) != 0;
+
+            OperA = GetAluIneg(OperA, NegA);
+            OperB = GetAluIneg(OperB, NegB);
+
+            ShaderIrOp Op = new ShaderIrOp(ShaderIrInst.Add, OperA, OperB);
+
+            Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
+        }
+
+        private static void EmitIadd3(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+        {
+            int Mode = (int)((OpCode >> 37) & 3);
+
+            bool Neg1 = ((OpCode >> 51) & 1) != 0;
+            bool Neg2 = ((OpCode >> 50) & 1) != 0;
+            bool Neg3 = ((OpCode >> 49) & 1) != 0;
+
+            int Height1 = (int)((OpCode >> 35) & 3);
+            int Height2 = (int)((OpCode >> 33) & 3);
+            int Height3 = (int)((OpCode >> 31) & 3);
+
+            ShaderIrNode OperB;
+
+            switch (Oper)
+            {
+                case ShaderOper.CR:  OperB = GetOperCbuf34  (OpCode); break;
+                case ShaderOper.Imm: OperB = GetOperImm19_20(OpCode); break;
+                case ShaderOper.RR:  OperB = GetOperGpr20   (OpCode); break;
+
+                default: throw new ArgumentException(nameof(Oper));
+            }
+
+            ShaderIrNode ApplyHeight(ShaderIrNode Src, int Height)
+            {
+                if (Oper != ShaderOper.RR)
+                {
+                    return Src;
+                }
+
+                switch (Height)
+                {
+                    case 0: return Src;
+                    case 1: return new ShaderIrOp(ShaderIrInst.And, Src, new ShaderIrOperImm(0xffff));
+                    case 2: return new ShaderIrOp(ShaderIrInst.Lsr, Src, new ShaderIrOperImm(16));
+
+                    default: throw new InvalidOperationException();
+                }
+            }
+
+            ShaderIrNode Src1 = GetAluIneg(ApplyHeight(GetOperGpr8(OpCode),  Height1), Neg1);
+            ShaderIrNode Src2 = GetAluIneg(ApplyHeight(OperB,                Height2), Neg2);
+            ShaderIrNode Src3 = GetAluIneg(ApplyHeight(GetOperGpr39(OpCode), Height3), Neg3);
+
+            ShaderIrOp Sum = new ShaderIrOp(ShaderIrInst.Add, Src1, Src2);
+
+            if (Oper == ShaderOper.RR)
+            {
+                switch (Mode)
+                {
+                    case 1: Sum = new ShaderIrOp(ShaderIrInst.Lsr, Sum, new ShaderIrOperImm(16)); break;
+                    case 2: Sum = new ShaderIrOp(ShaderIrInst.Lsl, Sum, new ShaderIrOperImm(16)); break;
+                }
+            }
+
+            //Note: Here there should be a "+ 1" when carry flag is set
+            //but since carry is mostly ignored by other instructions, it's excluded for now
+
+            Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), new ShaderIrOp(ShaderIrInst.Add, Sum, Src3)), OpCode));
+        }
+
         private static void EmitIscadd(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
         {
             bool NegB = ((OpCode >> 48) & 1) != 0;
@@ -821,6 +981,54 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(P0Node, Op), OpCode));
         }
 
+        private static void EmitLop(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+        {
+            int SubOp = (int)(OpCode >> 41) & 3;
+
+            bool InvA = ((OpCode >> 39) & 1) != 0;
+            bool InvB = ((OpCode >> 40) & 1) != 0;
+
+            ShaderIrInst Inst = 0;
+
+            switch (SubOp)
+            {
+                case 0: Inst = ShaderIrInst.And; break;
+                case 1: Inst = ShaderIrInst.Or;  break;
+                case 2: Inst = ShaderIrInst.Xor; break;
+            }
+
+            ShaderIrNode OperA = GetAluNot(GetOperGpr8(OpCode), InvA);
+            ShaderIrNode OperB;
+
+            switch (Oper)
+            {
+                case ShaderOper.CR:  OperB = GetOperCbuf34  (OpCode); break;
+                case ShaderOper.Imm: OperB = GetOperImm19_20(OpCode); break;
+                case ShaderOper.RR:  OperB = GetOperGpr20   (OpCode); break;
+
+                default: throw new ArgumentException(nameof(Oper));
+            }
+
+            OperB = GetAluNot(OperB, InvB);
+
+            ShaderIrNode Op;
+
+            if (SubOp < 3)
+            {
+                Op = new ShaderIrOp(Inst, OperA, OperB);
+            }
+            else
+            {
+                Op = OperB;
+            }
+
+            ShaderIrNode Compare = new ShaderIrOp(ShaderIrInst.Cne, Op, new ShaderIrOperImm(0));
+
+            Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperPred48(OpCode), Compare), OpCode));
+
+            Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Op), OpCode));
+        }
+
         private static void EmitXmad(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
         {
             //TODO: Confirm SignAB/C, it is just a guess.
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
index a8ad5ec2ec..1f1b158ef8 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
@@ -156,6 +156,11 @@ namespace Ryujinx.Graphics.Gal.Shader
             return new ShaderIrOperPred((int)(OpCode >> 39) & 7);
         }
 
+        public static ShaderIrOperPred GetOperPred48(long OpCode)
+        {
+            return new ShaderIrOperPred((int)((OpCode >> 48) & 7));
+        }
+
         public static ShaderIrInst GetCmp(long OpCode)
         {
             switch ((int)(OpCode >> 49) & 7)
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
index dfcea905ad..4c9e59cf0c 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs
@@ -113,6 +113,21 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), Gpr), OpCode));
         }
 
+        public static void Sel_C(ShaderIrBlock Block, long OpCode)
+        {
+            EmitSel(Block, OpCode, ShaderOper.CR);
+        }
+
+        public static void Sel_I(ShaderIrBlock Block, long OpCode)
+        {
+            EmitSel(Block, OpCode, ShaderOper.Imm);
+        }
+
+        public static void Sel_R(ShaderIrBlock Block, long OpCode)
+        {
+            EmitSel(Block, OpCode, ShaderOper.RR);
+        }
+
         private static void EmitF2f(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
         {
             bool NegA = ((OpCode >> 45) & 1) != 0;
@@ -340,6 +355,28 @@ namespace Ryujinx.Graphics.Gal.Shader
             Block.AddNode(GetPredNode(new ShaderIrAsg(GetOperGpr0(OpCode), OperA), OpCode));
         }
 
+        private static void EmitSel(ShaderIrBlock Block, long OpCode, ShaderOper Oper)
+        {
+            ShaderIrOperGpr Dst  = GetOperGpr0   (OpCode);
+            ShaderIrNode    Pred = GetOperPred39N(OpCode);
+
+            ShaderIrNode ResultA = GetOperGpr8(OpCode);
+            ShaderIrNode ResultB;
+
+            switch (Oper)
+            {
+                case ShaderOper.CR:  ResultB = GetOperCbuf34  (OpCode); break;
+                case ShaderOper.Imm: ResultB = GetOperImm19_20(OpCode); break;
+                case ShaderOper.RR:  ResultB = GetOperGpr20   (OpCode); break;
+
+                default: throw new ArgumentException(nameof(Oper));
+            }
+
+            Block.AddNode(GetPredNode(new ShaderIrCond(Pred, new ShaderIrAsg(Dst, ResultA), false), OpCode));
+
+            Block.AddNode(GetPredNode(new ShaderIrCond(Pred, new ShaderIrAsg(Dst, ResultB), true),  OpCode));
+        }
+
         private static IntType GetIntType(long OpCode)
         {
             bool Signed = ((OpCode >> 13) & 1) != 0;
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
index b4f51e5084..1ac1178512 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderOpCodeTable.cs
@@ -64,6 +64,13 @@ namespace Ryujinx.Graphics.Gal.Shader
             Set("0100110011100x", ShaderDecode.I2i_C);
             Set("0011100x11100x", ShaderDecode.I2i_I);
             Set("0101110011100x", ShaderDecode.I2i_R);
+            Set("0100110000010x", ShaderDecode.Iadd_C);
+            Set("0011100000010x", ShaderDecode.Iadd_I);
+            Set("0001110x0xxxxx", ShaderDecode.Iadd_I32);
+            Set("0101110000010x", ShaderDecode.Iadd_R);
+            Set("010011001100xx", ShaderDecode.Iadd3_C);
+            Set("001110001100xx", ShaderDecode.Iadd3_I);
+            Set("010111001100xx", ShaderDecode.Iadd3_R);
             Set("0100110000100x", ShaderDecode.Imnmx_C);
             Set("0011100x00100x", ShaderDecode.Imnmx_I);
             Set("0101110000100x", ShaderDecode.Imnmx_R);
@@ -71,13 +78,19 @@ namespace Ryujinx.Graphics.Gal.Shader
             Set("0100110000011x", ShaderDecode.Iscadd_C);
             Set("0011100x00011x", ShaderDecode.Iscadd_I);
             Set("0101110000011x", ShaderDecode.Iscadd_R);
+            Set("010010110101xx", ShaderDecode.Iset_C);
+            Set("001101100101xx", ShaderDecode.Iset_I);
+            Set("010110110101xx", ShaderDecode.Iset_R);
             Set("010010110110xx", ShaderDecode.Isetp_C);
             Set("0011011x0110xx", ShaderDecode.Isetp_I);
             Set("010110110110xx", ShaderDecode.Isetp_R);
             Set("111000110011xx", ShaderDecode.Kil);
             Set("1110111111011x", ShaderDecode.Ld_A);
             Set("1110111110010x", ShaderDecode.Ld_C);
+            Set("0100110001000x", ShaderDecode.Lop_C);
+            Set("0011100001000x", ShaderDecode.Lop_I);
             Set("000001xxxxxxxx", ShaderDecode.Lop_I32);
+            Set("0101110001000x", ShaderDecode.Lop_R);
             Set("0100110010011x", ShaderDecode.Mov_C);
             Set("0011100x10011x", ShaderDecode.Mov_I);
             Set("000000010000xx", ShaderDecode.Mov_I32);
@@ -87,6 +100,9 @@ namespace Ryujinx.Graphics.Gal.Shader
             Set("0100110010010x", ShaderDecode.Rro_C);
             Set("0011100x10010x", ShaderDecode.Rro_I);
             Set("0101110010010x", ShaderDecode.Rro_R);
+            Set("0100110010100x", ShaderDecode.Sel_C);
+            Set("0011100010100x", ShaderDecode.Sel_I);
+            Set("0101110010100x", ShaderDecode.Sel_R);
             Set("0100110001001x", ShaderDecode.Shl_C);
             Set("0011100x01001x", ShaderDecode.Shl_I);
             Set("0101110001001x", ShaderDecode.Shl_R);