diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index d84a58200..599c674f3 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -89,6 +89,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
             Set("0111100x0xxxxx", InstEmit.Hmul2,   typeof(OpCodeAluImm2x10));
             Set("0010101xxxxxxx", InstEmit.Hmul2,   typeof(OpCodeAluImm32));
             Set("0101110100001x", InstEmit.Hmul2,   typeof(OpCodeAluReg));
+            Set("0111110x1xxxxx", InstEmit.Hset2,   typeof(OpCodeSetCbuf));
+            Set("0111110x0xxxxx", InstEmit.Hset2,   typeof(OpCodeHsetImm2x10));
+            Set("0101110100011x", InstEmit.Hset2,   typeof(OpCodeSetReg));
             Set("0111111x1xxxxx", InstEmit.Hsetp2,  typeof(OpCodeSetCbuf));
             Set("0111111x0xxxxx", InstEmit.Hsetp2,  typeof(OpCodeHsetImm2x10));
             Set("0101110100100x", InstEmit.Hsetp2,  typeof(OpCodeSetReg));
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
index 5c4f53988..e283c3b77 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 {
     static class InstEmitAluHelper
     {
-        public static int GetIntMin(IntegerType type)
+        public static long GetIntMin(IntegerType type)
         {
             switch (type)
             {
@@ -18,14 +18,14 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 case IntegerType.S8:  return sbyte.MinValue;
                 case IntegerType.U16: return ushort.MinValue;
                 case IntegerType.S16: return short.MinValue;
-                case IntegerType.U32: return (int)uint.MinValue;
+                case IntegerType.U32: return uint.MinValue;
                 case IntegerType.S32: return int.MinValue;
             }
 
             throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
         }
 
-        public static int GetIntMax(IntegerType type)
+        public static long GetIntMax(IntegerType type)
         {
             switch (type)
             {
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 case IntegerType.S8:  return sbyte.MaxValue;
                 case IntegerType.U16: return ushort.MaxValue;
                 case IntegerType.S16: return short.MaxValue;
-                case IntegerType.U32: return unchecked((int)uint.MaxValue);
+                case IntegerType.U32: return uint.MaxValue;
                 case IntegerType.S32: return int.MaxValue;
             }
 
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
index 5aa925d9c..b15241528 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
@@ -14,18 +14,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
         {
             OpCodeFArith op = (OpCodeFArith)context.CurrOp;
 
-            FPType srcType = (FPType)op.RawOpCode.Extract(8,  2);
-            FPType dstType = (FPType)op.RawOpCode.Extract(10, 2);
+            FPType dstType = (FPType)op.RawOpCode.Extract(8,  2);
+            FPType srcType = (FPType)op.RawOpCode.Extract(10, 2);
 
-            bool pass      = op.RawOpCode.Extract(40);
+            bool round     = op.RawOpCode.Extract(42);
             bool negateB   = op.RawOpCode.Extract(45);
             bool absoluteB = op.RawOpCode.Extract(49);
 
-            pass &= op.RoundingMode == RoundingMode.TowardsNegativeInfinity;
-
             Operand srcB = context.FPAbsNeg(GetSrcB(context, srcType), absoluteB, negateB);
 
-            if (!pass)
+            if (round)
             {
                 switch (op.RoundingMode)
                 {
@@ -84,6 +82,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             switch (op.RoundingMode)
             {
+                case RoundingMode.ToNearest:
+                    srcB = context.FPRound(srcB);
+                    break;
+
                 case RoundingMode.TowardsNegativeInfinity:
                     srcB = context.FPFloor(srcB);
                     break;
@@ -97,19 +99,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     break;
             }
 
+            long min = GetIntMin(intType);
+            long max = GetIntMax(intType);
+
+            srcB = context.FPClamp(srcB, ConstF(min), ConstF(max));
+
             srcB = context.FPConvertToS32(srcB);
 
-            // TODO: S/U64, conversion overflow handling.
-            if (intType != IntegerType.S32)
-            {
-                int min = GetIntMin(intType);
-                int max = GetIntMax(intType);
-
-                srcB = isSignedInt
-                    ? context.IClampS32(srcB, Const(min), Const(max))
-                    : context.IClampU32(srcB, Const(min), Const(max));
-            }
-
             Operand dest = GetDest(context);
 
             context.Copy(dest, srcB);
@@ -194,8 +190,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     dstType |= IntegerType.S8;
                 }
 
-                int min = GetIntMin(dstType);
-                int max = GetIntMax(dstType);
+                int min = (int)GetIntMin(dstType);
+                int max = (int)GetIntMax(dstType);
 
                 srcB = dstIsSignedInt
                     ? context.IClampS32(srcB, Const(min), Const(max))
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
index 79d92c2d7..3b8d7305b 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
@@ -232,7 +232,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             bool saturate = op.RawOpCode.Extract(op is IOpCodeReg ? 32 : 52);
 
-            Operand[] srcA = GetHalfSrcA(context);
+            Operand[] srcA = GetHalfSrcA(context, isAdd);
             Operand[] srcB = GetHalfSrcB(context);
 
             Operand[] res = new Operand[2];
@@ -254,13 +254,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
             context.Copy(GetDest(context), GetHalfPacked(context, res));
         }
 
-        public static void Hsetp2(EmitterContext context)
+        public static void Hset2(EmitterContext context)
         {
             OpCodeSet op = (OpCodeSet)context.CurrOp;
 
-            bool hAnd = op.RawOpCode.Extract(53);
+            bool isRegVariant = op is IOpCodeReg;
 
-            Condition cmpOp = op is IOpCodeReg
+            bool boolFloat = isRegVariant
+                ? op.RawOpCode.Extract(49)
+                : op.RawOpCode.Extract(53);
+
+            Condition cmpOp = isRegVariant
                 ? (Condition)op.RawOpCode.Extract(35, 4)
                 : (Condition)op.RawOpCode.Extract(49, 4);
 
@@ -269,8 +273,49 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             Operand[] res = new Operand[2];
 
+            res[0] = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
+            res[1] = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
+
             Operand pred = GetPredicate39(context);
 
+            res[0] = GetPredLogicalOp(context, op.LogicalOp, res[0], pred);
+            res[1] = GetPredLogicalOp(context, op.LogicalOp, res[1], pred);
+
+            if (boolFloat)
+            {
+                res[0] = context.ConditionalSelect(res[0], ConstF(1), Const(0));
+                res[1] = context.ConditionalSelect(res[1], ConstF(1), Const(0));
+
+                context.Copy(GetDest(context), context.PackHalf2x16(res[0], res[1]));
+            }
+            else
+            {
+                Operand low  = context.BitwiseAnd(res[0], Const(0xffff));
+                Operand high = context.ShiftLeft (res[1], Const(16));
+
+                Operand packed = context.BitwiseOr(low, high);
+
+                context.Copy(GetDest(context), packed);
+            }
+        }
+
+        public static void Hsetp2(EmitterContext context)
+        {
+            OpCodeSet op = (OpCodeSet)context.CurrOp;
+
+            bool isRegVariant = op is IOpCodeReg;
+
+            bool hAnd = isRegVariant
+                ? op.RawOpCode.Extract(49)
+                : op.RawOpCode.Extract(53);
+
+            Condition cmpOp = isRegVariant
+                ? (Condition)op.RawOpCode.Extract(35, 4)
+                : (Condition)op.RawOpCode.Extract(49, 4);
+
+            Operand[] srcA = GetHalfSrcA(context);
+            Operand[] srcB = GetHalfSrcB(context);
+
             Operand p0Res = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
             Operand p1Res = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
 
@@ -280,6 +325,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 p1Res = context.BitwiseNot(p0Res);
             }
 
+            Operand pred = GetPredicate39(context);
+
             p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
             p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
 
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
index 4b85e96fd..22e2a1400 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             // TODO: Warn about invalid floating point type.
 
-            return Const(0);
+            return ConstF(0);
         }
 
         public static Operand GetSrcB(EmitterContext context)
@@ -98,13 +98,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
             throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\".");
         }
 
-        public static Operand[] GetHalfSrcA(EmitterContext context)
+        public static Operand[] GetHalfSrcA(EmitterContext context, bool isAdd = false)
         {
             OpCode op = context.CurrOp;
 
             bool absoluteA = false, negateA = false;
 
-            if (op is IOpCodeCbuf || op is IOpCodeImm)
+            if (isAdd || op is IOpCodeCbuf || op is IOpCodeImm)
             {
                 negateA   = op.RawOpCode.Extract(43);
                 absoluteA = op.RawOpCode.Extract(44);
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
             {
                 absoluteA = op.RawOpCode.Extract(44);
             }
-            else if (op is OpCodeAluImm32 && op.Emitter == InstEmit.Hadd2)
+            else if (op is OpCodeAluImm32 && isAdd)
             {
                 negateA = op.RawOpCode.Extract(56);
             }
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
index e94d4d2da..c55e34309 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
@@ -206,6 +206,11 @@ namespace Ryujinx.Graphics.Shader.Translation
             return context.Add(Instruction.FP | Instruction.Ceiling, Local(), a);
         }
 
+        public static Operand FPClamp(this EmitterContext context, Operand a, Operand b, Operand c)
+        {
+            return context.Add(Instruction.FP | Instruction.Clamp, Local(), a, b, c);
+        }
+
         public static Operand FPCompareEqual(this EmitterContext context, Operand a, Operand b)
         {
             return context.Add(Instruction.FP | Instruction.CompareEqual, Local(), a, b);