diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index 43a0e63b14..01134ee32f 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -47,6 +47,7 @@ namespace ChocolArm64
             Set("x1011010100xxxxxxxxx01xxxxxxxxxx", AInstEmit.Csneg,         typeof(AOpCodeCsel));
             Set("11010101000000110011xxxx10111111", AInstEmit.Dmb,           typeof(AOpCodeSystem));
             Set("11010101000000110011xxxx10011111", AInstEmit.Dsb,           typeof(AOpCodeSystem));
+            Set("x1001010xx1xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eon,           typeof(AOpCodeAluRs));
             Set("x10100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluImm));
             Set("x1001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluRs));
             Set("x00100111x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Extr,          typeof(AOpCodeAluRs));
@@ -147,6 +148,7 @@ namespace ChocolArm64
             Set("00011110xx1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S,        typeof(AOpCodeSimdReg));
             Set("0x0011100x1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V,        typeof(AOpCodeSimdReg));
             Set("00011110xx1xxxxxxxxx01xxxxx0xxxx", AInstEmit.Fccmp_S,       typeof(AOpCodeSimdFcond));
+            Set("00011110xx1xxxxxxxxx01xxxxx1xxxx", AInstEmit.Fccmpe_S,      typeof(AOpCodeSimdFcond));
             Set("00011110xx1xxxxx001000xxxxx0x000", AInstEmit.Fcmp_S,        typeof(AOpCodeSimdReg));
             Set("00011110xx1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S,       typeof(AOpCodeSimdReg));
             Set("00011110xx1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S,       typeof(AOpCodeSimdFcond));
@@ -183,6 +185,7 @@ namespace ChocolArm64
             Set("0x1011100x1xxxxx110111xxxxxxxxxx", AInstEmit.Fmul_V,        typeof(AOpCodeSimdReg));
             Set("0x0011111<<xxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Ve,       typeof(AOpCodeSimdRegElem));
             Set("00011110xx100001010000xxxxxxxxxx", AInstEmit.Fneg_S,        typeof(AOpCodeSimdReg));
+            Set("00011111xx1xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fnmsub_S,      typeof(AOpCodeSimdReg));
             Set("00011110xx1xxxxx100010xxxxxxxxxx", AInstEmit.Fnmul_S,       typeof(AOpCodeSimdReg));
             Set("00011110xx100110010000xxxxxxxxxx", AInstEmit.Frinta_S,      typeof(AOpCodeSimd));
             Set("00011110xx100101010000xxxxxxxxxx", AInstEmit.Frintm_S,      typeof(AOpCodeSimd));
@@ -225,6 +228,7 @@ namespace ChocolArm64
             Set("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V,        typeof(AOpCodeSimdShImm));
             Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V,        typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V,        typeof(AOpCodeSimdReg));
+            Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V,       typeof(AOpCodeSimdReg));
             Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V,        typeof(AOpCodeSimdReg));
             Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V,       typeof(AOpCodeSimdShImm));
             Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S,        typeof(AOpCodeSimdShImm));
@@ -251,6 +255,7 @@ namespace ChocolArm64
             Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S,        typeof(AOpCodeSimdIns));
             Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V,        typeof(AOpCodeSimdReg));
             Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V,       typeof(AOpCodeSimdShImm));
+            Set("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S,        typeof(AOpCodeSimdShImm));
             Set("0x1011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V,        typeof(AOpCodeSimdShImm));
             Set("0x1011110>>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V,        typeof(AOpCodeSimdShImm));
             Set("0x001110xx0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V,        typeof(AOpCodeSimdReg));
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
index 073a45e7ae..72903f5b32 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
@@ -107,6 +107,16 @@ namespace ChocolArm64.Instruction
             Context.EmitStintzr(Op.Rd);
         }
 
+        public static void Eon(AILEmitterCtx Context)
+        {
+            EmitDataLoadOpers(Context);
+
+            Context.Emit(OpCodes.Not);
+            Context.Emit(OpCodes.Xor);
+
+            EmitDataStore(Context);
+        }
+
         public static void Eor(AILEmitterCtx Context) => EmitDataOp(Context, OpCodes.Xor);
 
         public static void Extr(AILEmitterCtx Context)
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitAluHelper.cs b/Ryujinx/Cpu/Instruction/AInstEmitAluHelper.cs
index 57ec25dd0d..e848742d0b 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitAluHelper.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitAluHelper.cs
@@ -145,5 +145,24 @@ namespace ChocolArm64.Instruction
                 Context.EmitStint(Op.Rd);
             }
         }
+
+        public static void EmitSetNZCV(AILEmitterCtx Context, int NZCV)
+        {
+            Context.EmitLdc_I4((NZCV >> 0) & 1);
+
+            Context.EmitStflg((int)APState.VBit);
+
+            Context.EmitLdc_I4((NZCV >> 1) & 1);
+
+            Context.EmitStflg((int)APState.CBit);
+
+            Context.EmitLdc_I4((NZCV >> 2) & 1);
+
+            Context.EmitStflg((int)APState.ZBit);
+
+            Context.EmitLdc_I4((NZCV >> 3) & 1);
+
+            Context.EmitStflg((int)APState.NBit);
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitBfm.cs b/Ryujinx/Cpu/Instruction/AInstEmitBfm.cs
index 4eff013d16..823af73857 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitBfm.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitBfm.cs
@@ -36,7 +36,7 @@ namespace ChocolArm64.Instruction
 
             if (Op.Pos + 1 == BitsCount)
             {
-                EmitBfmShift(Context, OpCodes.Shr);
+                EmitSbfmShift(Context);
             }
             else if (Op.Pos < Op.Shift)
             {
@@ -87,7 +87,7 @@ namespace ChocolArm64.Instruction
 
             if (Op.Pos + 1 == Op.GetBitsCount())
             {
-                EmitBfmShift(Context, OpCodes.Shr_Un);
+                EmitUbfmShift(Context);
             }
             else if (Op.Pos < Op.Shift)
             {
@@ -166,19 +166,28 @@ namespace ChocolArm64.Instruction
             Context.EmitStintzr(Op.Rd);
         }
 
-        private static void EmitBfmShift(AILEmitterCtx Context, OpCode ILOp)
+        private static void EmitSbfmShift(AILEmitterCtx Context)
+        {
+            EmitBfmShift(Context, true);
+        }
+
+        private static void EmitUbfmShift(AILEmitterCtx Context)
+        {
+            EmitBfmShift(Context, false);
+        }
+
+        private static void EmitBfmShift(AILEmitterCtx Context, bool Signed)
         {
             AOpCodeBfm Op = (AOpCodeBfm)Context.CurrOp;
 
-            if (Op.Shift > 0)
-            {
-                Context.EmitLdintzr(Op.Rn);
-                Context.EmitLdc_I4(Op.Shift);
+            Context.EmitLdintzr(Op.Rn);
+            Context.EmitLdc_I4(Op.Shift);
 
-                Context.Emit(ILOp);
+            Context.Emit(Signed
+                ? OpCodes.Shr
+                : OpCodes.Shr_Un);
 
-                Context.EmitStintzr(Op.Rd);
-            }
+            Context.EmitStintzr(Op.Rd);
         }
 
         private static void EmitBfmLsl(AILEmitterCtx Context)
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
index d6ebcc3ffc..08991a90e5 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
@@ -215,6 +215,24 @@ namespace ChocolArm64.Instruction
             });
         }
 
+        public static void Fnmsub_S(AILEmitterCtx Context)
+        {
+            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+            int SizeF = Op.Size & 1;
+            
+            EmitVectorExtractF(Context, Op.Rn, 0, SizeF);
+            EmitVectorExtractF(Context, Op.Rm, 0, SizeF);
+
+            Context.Emit(OpCodes.Mul);
+
+            EmitVectorExtractF(Context, Op.Ra, 0, SizeF);
+
+            Context.Emit(OpCodes.Sub);
+
+            EmitScalarSetF(Context, Op.Rd, SizeF);
+        }
+
         public static void Frinta_S(AILEmitterCtx Context)
         {
             AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@@ -282,7 +300,7 @@ namespace ChocolArm64.Instruction
 
         public static void Saddw_V(AILEmitterCtx Context)
         {
-            EmitVectorWidenBinaryOpSx(Context, () => Context.Emit(OpCodes.Add));
+            EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add));
         }
 
         public static void Smax_V(AILEmitterCtx Context)
@@ -303,6 +321,11 @@ namespace ChocolArm64.Instruction
             EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
         }
 
+        public static void Smull_V(AILEmitterCtx Context)
+        {
+            EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
+        }
+
         public static void Sub_S(AILEmitterCtx Context)
         {
             EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
@@ -333,7 +356,7 @@ namespace ChocolArm64.Instruction
 
         public static void Uaddw_V(AILEmitterCtx Context)
         {
-            EmitVectorWidenBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
+            EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdCmp.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdCmp.cs
index 92361fbd3f..97ccf0ab4e 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdCmp.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdCmp.cs
@@ -4,6 +4,7 @@ using ChocolArm64.Translation;
 using System;
 using System.Reflection.Emit;
 
+using static ChocolArm64.Instruction.AInstEmitAluHelper;
 using static ChocolArm64.Instruction.AInstEmitSimdHelper;
 
 namespace ChocolArm64.Instruction
@@ -54,24 +55,9 @@ namespace ChocolArm64.Instruction
 
             Context.EmitCondBranch(LblTrue, Op.Cond);
 
-            //TODO: Share this logic with Ccmp.
-            Context.EmitLdc_I4((Op.NZCV >> 0) & 1);
+            EmitSetNZCV(Context, Op.NZCV);
 
-            Context.EmitStflg((int)APState.VBit);
-
-            Context.EmitLdc_I4((Op.NZCV >> 1) & 1);
-
-            Context.EmitStflg((int)APState.CBit);
-
-            Context.EmitLdc_I4((Op.NZCV >> 2) & 1);
-
-            Context.EmitStflg((int)APState.ZBit);
-
-            Context.EmitLdc_I4((Op.NZCV >> 3) & 1);
-
-            Context.EmitStflg((int)APState.NBit);
-
-            Context.Emit(OpCodes.Br_S, LblEnd);
+            Context.Emit(OpCodes.Br, LblEnd);
 
             Context.MarkLabel(LblTrue);
 
@@ -80,12 +66,35 @@ namespace ChocolArm64.Instruction
             Context.MarkLabel(LblEnd);
         }
 
+        public static void Fccmpe_S(AILEmitterCtx Context)
+        {
+            Fccmp_S(Context);
+        }
+
         public static void Fcmp_S(AILEmitterCtx Context)
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
             bool CmpWithZero = !(Op is AOpCodeSimdFcond) ? Op.Bit3 : false;
 
+            //Handle NaN case. If any number is NaN, then NZCV = 0011.
+            if (CmpWithZero)
+            {
+                EmitNaNCheck(Context, Op.Rn);
+            }
+            else
+            {
+                EmitNaNCheck(Context, Op.Rn);
+                EmitNaNCheck(Context, Op.Rm);
+
+                Context.Emit(OpCodes.Or);
+            }
+
+            AILLabel LblNaN = new AILLabel();
+            AILLabel LblEnd = new AILLabel();
+
+            Context.Emit(OpCodes.Brtrue_S, LblNaN);
+
             void EmitLoadOpers()
             {
                 EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
@@ -102,7 +111,7 @@ namespace ChocolArm64.Instruction
 
             //Z = Rn == Rm
             EmitLoadOpers();
-            
+
             Context.Emit(OpCodes.Ceq);
             Context.Emit(OpCodes.Dup);
 
@@ -123,30 +132,18 @@ namespace ChocolArm64.Instruction
 
             Context.EmitStflg((int)APState.NBit);
 
-            //Handle NaN case. If any number is NaN, then NZCV = 0011.
-            AILLabel LblNotNaN = new AILLabel();
+            //V = 0
+            Context.EmitLdc_I4(0);
 
-            if (CmpWithZero)
-            {
-                EmitNaNCheck(Context, Op.Rn);
-            }
-            else
-            {
-                EmitNaNCheck(Context, Op.Rn);
-                EmitNaNCheck(Context, Op.Rm);
-
-                Context.Emit(OpCodes.Or);
-            }
-
-            Context.Emit(OpCodes.Brfalse_S, LblNotNaN);
-
-            Context.EmitLdc_I4(1);
-            Context.EmitLdc_I4(1);
-
-            Context.EmitStflg((int)APState.CBit);
             Context.EmitStflg((int)APState.VBit);
 
-            Context.MarkLabel(LblNotNaN);
+            Context.Emit(OpCodes.Br_S, LblEnd);
+
+            Context.MarkLabel(LblNaN);
+
+            EmitSetNZCV(Context, 0b0011);
+
+            Context.MarkLabel(LblEnd);
         }
 
         public static void Fcmpe_S(AILEmitterCtx Context)
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
index fbb0dfda5a..00c2fe9b5b 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
@@ -91,7 +91,7 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
 
-            EmitVectorExtractSx(Context, Op.Rd, 0, Op.Size + 2);
+            EmitVectorExtractSx(Context, Op.Rn, 0, Op.Size + 2);
 
             EmitFloatCast(Context, Op.Size);
 
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
index 97f288161c..20c8be26dc 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
@@ -133,7 +133,7 @@ namespace ChocolArm64.Instruction
 
         public static void EmitScalarOp(AILEmitterCtx Context, Action Emit, OperFlags Opers, bool Signed)
         {
-            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
 
             if (Opers.HasFlag(OperFlags.Rd))
             {
@@ -147,7 +147,7 @@ namespace ChocolArm64.Instruction
 
             if (Opers.HasFlag(OperFlags.Rm))
             {
-                EmitVectorExtract(Context, Op.Rm, 0, Op.Size, Signed);
+                EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, 0, Op.Size, Signed);
             }
 
             Emit();
@@ -383,17 +383,17 @@ namespace ChocolArm64.Instruction
             }
         }
 
-        public static void EmitVectorWidenBinaryOpSx(AILEmitterCtx Context, Action Emit)
+        public static void EmitVectorWidenRmBinaryOpSx(AILEmitterCtx Context, Action Emit)
         {
-            EmitVectorWidenBinaryOp(Context, Emit, true);
+            EmitVectorWidenRmBinaryOp(Context, Emit, true);
         }
 
-        public static void EmitVectorWidenBinaryOpZx(AILEmitterCtx Context, Action Emit)
+        public static void EmitVectorWidenRmBinaryOpZx(AILEmitterCtx Context, Action Emit)
         {
-            EmitVectorWidenBinaryOp(Context, Emit, false);
+            EmitVectorWidenRmBinaryOp(Context, Emit, false);
         }
 
-        public static void EmitVectorWidenBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed)
+        public static void EmitVectorWidenRmBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed)
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
@@ -415,6 +415,38 @@ namespace ChocolArm64.Instruction
             Context.EmitStvec(Op.Rd);
         }
 
+        public static void EmitVectorWidenRnRmBinaryOpSx(AILEmitterCtx Context, Action Emit)
+        {
+            EmitVectorWidenRnRmBinaryOp(Context, Emit, true);
+        }
+
+        public static void EmitVectorWidenRnRmBinaryOpZx(AILEmitterCtx Context, Action Emit)
+        {
+            EmitVectorWidenRnRmBinaryOp(Context, Emit, false);
+        }
+
+        public static void EmitVectorWidenRnRmBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed)
+        {
+            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+            int Elems = 8 >> Op.Size;
+
+            int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
+
+            for (int Index = 0; Index < Elems; Index++)
+            {
+                EmitVectorExtract(Context, Op.Rn, Part + Index, Op.Size, Signed);
+                EmitVectorExtract(Context, Op.Rm, Part + Index, Op.Size, Signed);
+
+                Emit();
+
+                EmitVectorInsertTmp(Context, Index, Op.Size + 1);
+            }
+
+            Context.EmitLdvectmp();
+            Context.EmitStvec(Op.Rd);
+        }
+
         public static void EmitScalarSet(AILEmitterCtx Context, int Reg, int Size)
         {
             EmitVectorZeroAll(Context, Reg);
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdShift.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdShift.cs
index 165642342e..8740ba4d69 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdShift.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdShift.cs
@@ -10,15 +10,6 @@ namespace ChocolArm64.Instruction
 {
     static partial class AInstEmit
     {
-        [Flags]
-        private enum ShrFlags
-        {
-            None       = 0,
-            Signed     = 1 << 0,
-            Rounding   = 1 << 1,
-            Accumulate = 1 << 2
-        }
-
         public static void Shl_S(AILEmitterCtx Context)
         {
             AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
@@ -100,14 +91,43 @@ namespace ChocolArm64.Instruction
             EmitVectorShImmWidenBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift);
         }
 
+        public static void Ushr_S(AILEmitterCtx Context)
+        {
+            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
+
+            EmitScalarUnaryOpZx(Context, () =>
+            {
+                Context.EmitLdc_I4(GetImmShr(Op));
+
+                Context.Emit(OpCodes.Shr_Un);
+            });
+        }
+
         public static void Ushr_V(AILEmitterCtx Context)
         {
-            EmitVectorShr(Context, ShrFlags.None);
+            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
+
+            EmitVectorUnaryOpZx(Context, () =>
+            {
+                Context.EmitLdc_I4(GetImmShr(Op));
+
+                Context.Emit(OpCodes.Shr_Un);
+            });
         }
 
         public static void Usra_V(AILEmitterCtx Context)
         {
-            EmitVectorShr(Context, ShrFlags.Accumulate);
+            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
+
+            Action Emit = () =>
+            {
+                Context.EmitLdc_I4(GetImmShr(Op));
+
+                Context.Emit(OpCodes.Shr_Un);
+                Context.Emit(OpCodes.Add);
+            };
+
+            EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false);
         }
 
         private static void EmitVectorShl(AILEmitterCtx Context, bool Signed)
@@ -173,35 +193,6 @@ namespace ChocolArm64.Instruction
             }
         }
 
-        private static void EmitVectorShr(AILEmitterCtx Context, ShrFlags Flags)
-        {
-            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
-
-            int Shift = (8 << (Op.Size + 1)) - Op.Imm;
-
-            if (Flags.HasFlag(ShrFlags.Accumulate))
-            {
-                Action Emit = () =>
-                {
-                    Context.EmitLdc_I4(Shift);
-
-                    Context.Emit(OpCodes.Shr_Un);
-                    Context.Emit(OpCodes.Add);
-                };
-
-                EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false);
-            }
-            else
-            {
-                EmitVectorUnaryOpZx(Context, () =>
-                {
-                    Context.EmitLdc_I4(Shift);
-
-                    Context.Emit(OpCodes.Shr_Un);
-                });
-            }
-        }
-
         private static void EmitVectorShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm)
         {
             EmitVectorShImmBinaryOp(Context, Emit, Imm, true);
diff --git a/Ryujinx/Cpu/Instruction/ASoftFallback.cs b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
index b70d0b4f40..a57966baf8 100644
--- a/Ryujinx/Cpu/Instruction/ASoftFallback.cs
+++ b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
@@ -1,6 +1,7 @@
 using ChocolArm64.State;
 using ChocolArm64.Translation;
 using System;
+using System.Numerics;
 using System.Runtime.CompilerServices;
 
 namespace ChocolArm64.Instruction
@@ -101,6 +102,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static int SatF32ToS32(float Value)
         {
+            if (float.IsNaN(Value)) return 0;
+
             return Value > int.MaxValue ? int.MaxValue :
                    Value < int.MinValue ? int.MinValue : (int)Value;
         }
@@ -108,6 +111,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static long SatF32ToS64(float Value)
         {
+            if (float.IsNaN(Value)) return 0;
+
             return Value > long.MaxValue ? long.MaxValue :
                    Value < long.MinValue ? long.MinValue : (long)Value;
         }
@@ -115,6 +120,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static uint SatF32ToU32(float Value)
         {
+            if (float.IsNaN(Value)) return 0;
+
             return Value > uint.MaxValue ? uint.MaxValue :
                    Value < uint.MinValue ? uint.MinValue : (uint)Value;
         }
@@ -122,6 +129,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static ulong SatF32ToU64(float Value)
         {
+            if (float.IsNaN(Value)) return 0;
+
             return Value > ulong.MaxValue ? ulong.MaxValue :
                    Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
         }
@@ -129,6 +138,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static int SatF64ToS32(double Value)
         {
+            if (double.IsNaN(Value)) return 0;
+
             return Value > int.MaxValue ? int.MaxValue :
                    Value < int.MinValue ? int.MinValue : (int)Value;
         }
@@ -136,6 +147,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static long SatF64ToS64(double Value)
         {
+            if (double.IsNaN(Value)) return 0;
+
             return Value > long.MaxValue ? long.MaxValue :
                    Value < long.MinValue ? long.MinValue : (long)Value;
         }
@@ -143,6 +156,8 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static uint SatF64ToU32(double Value)
         {
+            if (double.IsNaN(Value)) return 0;
+
             return Value > uint.MaxValue ? uint.MaxValue :
                    Value < uint.MinValue ? uint.MinValue : (uint)Value;
         }
@@ -150,46 +165,20 @@ namespace ChocolArm64.Instruction
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static ulong SatF64ToU64(double Value)
         {
+            if (double.IsNaN(Value)) return 0;
+
             return Value > ulong.MaxValue ? ulong.MaxValue :
                    Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
         }
 
-        public static ulong SMulHi128(ulong LHS, ulong RHS)
+        public static long SMulHi128(long LHS, long RHS)
         {
-            long LLo = (uint)(LHS >>  0);
-            long LHi =  (int)(LHS >> 32);
-            long RLo = (uint)(RHS >>  0);
-            long RHi =  (int)(RHS >> 32);
-
-            long LHiRHi = LHi * RHi;
-            long LHiRLo = LHi * RLo;
-            long LLoRHi = LLo * RHi;
-            long LLoRLo = LLo * RLo;
-
-            long Carry = ((uint)LHiRLo + ((uint)LLoRHi + (LLoRLo >> 32))) >> 32;
-
-            long ResHi = LHiRHi + (LHiRLo >> 32) + (LLoRHi >> 32) + Carry;
-
-            return (ulong)ResHi;
+            return (long)(BigInteger.Multiply(LHS, RHS) >> 64);
         }
 
         public static ulong UMulHi128(ulong LHS, ulong RHS)
         {
-            ulong LLo = (uint)(LHS >>  0);
-            ulong LHi = (uint)(LHS >> 32);
-            ulong RLo = (uint)(RHS >>  0);
-            ulong RHi = (uint)(RHS >> 32);
-
-            ulong LHiRHi = LHi * RHi;
-            ulong LHiRLo = LHi * RLo;
-            ulong LLoRHi = LLo * RHi;
-            ulong LLoRLo = LLo * RLo;
-
-            ulong Carry = ((uint)LHiRLo + ((uint)LLoRHi + (LLoRLo >> 32))) >> 32;
-
-            ulong ResHi = LHiRHi + (LHiRLo >> 32) + (LLoRHi >> 32) + Carry;
-
-            return ResHi;
+            return (ulong)(BigInteger.Multiply(LHS, RHS) >> 64);
         }
 
         public static int CountSetBits8(byte Value)