diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 052e6d24eeaefcf67840df9eb51a312215fc7adf..82d912c767a771993892a0bde28f948037738863 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -933,6 +933,11 @@ union Instruction {
         BitField<49, 3, PredCondition> cond;
     } isetp;
 
+    union {
+        BitField<48, 1, u64> is_signed;
+        BitField<49, 3, PredCondition> cond;
+    } icmp;
+
     union {
         BitField<0, 3, u64> pred0;
         BitField<3, 3, u64> pred3;
@@ -1628,6 +1633,9 @@ public:
         SEL_C,
         SEL_R,
         SEL_IMM,
+        ICMP_RC,
+        ICMP_R,
+        ICMP_CR,
         MUFU,  // Multi-Function Operator
         RRO_C, // Range Reduction Operator
         RRO_R,
@@ -1892,6 +1900,9 @@ private:
             INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
             INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
             INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),
+            INST("010100110100----", Id::ICMP_RC, Type::ArithmeticInteger, "ICMP_RC"),
+            INST("010110110100----", Id::ICMP_R, Type::ArithmeticInteger, "ICMP_R"),
+            INST("010010110100----", Id::ICMP_CR, Type::ArithmeticInteger, "ICMP_CR"),
             INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"),
             INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"),
             INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index c8c1a7f4098aeedede3562fca4dd055ee3ca235b..1aa21010ab63c5662aac4373a51e8f28ebf49da5 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -138,6 +138,32 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
         SetRegister(bb, instr.gpr0, value);
         break;
     }
+    case OpCode::Id::ICMP_CR:
+    case OpCode::Id::ICMP_R:
+    case OpCode::Id::ICMP_RC: {
+        UNIMPLEMENTED_IF(instr.icmp.is_signed != 0);
+        const Node zero = Immediate(0);
+
+        const auto [op_a, op_b] = [&]() -> std::tuple<Node, Node> {
+            switch (opcode->get().GetId()) {
+            case OpCode::Id::ICMP_CR:
+                return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset),
+                        GetRegister(instr.gpr39)};
+            case OpCode::Id::ICMP_R:
+                return {GetRegister(instr.gpr20), GetRegister(instr.gpr39)};
+            case OpCode::Id::ICMP_RC:
+                return {GetRegister(instr.gpr39),
+                        GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)};
+            default:
+                UNIMPLEMENTED();
+                return {zero, zero};
+            }
+        }();
+        const Node test = GetRegister(instr.gpr8);
+        const Node comparison = GetPredicateComparisonInteger(instr.icmp.cond, false, test, zero);
+        SetRegister(bb, instr.gpr0, Operation(OperationCode::Select, comparison, op_a, op_b));
+        break;
+    }
     case OpCode::Id::LOP_C:
     case OpCode::Id::LOP_R:
     case OpCode::Id::LOP_IMM: {