Compare Scalar Single-Precision Floating-Point Values

Encoding

EncodingOperand 1Operand 2Operand 3Operand 4Operand 5
rmin/aModRM.reg[rw]ModRM.r/m[r]imm8
rvmin/aModRM.reg[rw]VEX.vvvv[r]ModRM.r/m[r]imm8
ervmituple1-scalarModRM.reg[rw]EVEX.vvvvv[r]ModRM.r/m[r]imm8

Description

The (V)CMPSS instruction compares a single single-precision floating-point values from the two source operands. The eight bit immediate determines the operation. The result is stored in the destination operand.

The VEX form will copy bits 32..127 from the first source operand into the destination. All forms except the legacy SSE one will zero the upper (untouched) bits.

For the legacy SSE and VEX versions, the results will all be a 32 bit integer (not a single-precision floating-point) of either all zeros or ones. For the EVEX versions, the destination is a mask register where each bit contains an individual comparison result.

For the legacy SSE version, bits 0..2 are used to determine the operation. For the VEX and EVEX encoded versions, bits 0..4 are used. The other bits are reserved. The operation is determined from the table below (an empty row indicates the division between allowed predicates from legacy SSE and VEX/EVEX encoded forms):

imm8 ValuePredicateDescriptionResult1QNaN Signals #IA
A < BA = BA > BUnordered2
00hEQ_OQ (EQ)Equal (ordered, non-signaling)falsetruefalsefalseno
01hLT_OS (LT)Less-than (ordered, signaling)truefalsefalsefalseyes
02hLE_OS (LE)Less-than-or-equal (ordered, signaling)truetruefalsefalseyes
03hUNORD_Q (UNORD)Unordered (non-signaling)falsefalsefalsetrueno
04hNEQ_UQ (NEQ)Not-equal (unordered, non-signaling)truefalsetruetrueno
05hNLT_US (NLT)Not-less-than (unordered, signaling)falsetruetruetrueyes
06hNLE_US (NLE)Not-less-than-or-equal (unordered, signaling)falsefalsetruetrueyes
07hORD_Q (ORD)Ordered (non-signaling)truetruetruefalseno
08hEQ_UQEqual (unordered, non-signaling)falsetruefalsetrueno
09hNGE_US (NGE)Not-greater-than-or-equal (unordered, signaling)truefalsefalsetrueyes
0AhNGT_US (NGT)Not-greater-than (unordered, signaling)truetruefalsetrueyes
0BhFALSE_OQ (FALSE)False (ordered, non-signaling)falsefalsefalsefalseno
0ChNEQ_OQNot-equal (ordered, non-signaling)truefalsetruefalseno
0DhGE_OS (GE)Greater-than-or-equal (ordered, signaling)falsetruetruefalseyes
0EhGT_OS (GT)Greater-than (ordered, signaling)falsefalsetruefalseyes
0FhTRUE_UQ (TRUE)True (unordered, non-signaling)truetruetruetrueno
10hEQ_OSEqual (ordered, signaling)falsetruefalsefalseyes
11hLT_OQLess-than (ordered, non-signaling)truefalsefalsefalseno
12hLE_OQLess-than-or-equal (ordered, non-signaling)truetruefalsefalseno
13hUNORD_SUnordered (signaling)falsefalsefalsetrueyes
14hNEQ_USNot-equal (unordered, signaling)truefalsetruetrueyes
15hNLT_UQNot-less-than (unordered, non-signaling)falsetruetruetrueno
16hNLE_UQNot-less-than-or-equal (unordered, non-signaling)falsefalsetruetrueno
17hORD_SOrdered (signaling)truetruetruefalseyes
18hEQ_USEqual (unordered, signaling)falsetruefalsetrueyes
19hNGE_UQNot-greater-than-or-equal (unordered, non-signaling)truefalsefalsetrueno
1AhNGT_UQNot-greater-than (unordered, non-signaling)truetruefalsetrueno
1BhFALSE_OSFalse (ordered, signaling)falsefalsefalsefalseyes
1ChNEQ_OSNot-equal (ordered, signaling)truefalsetruefalseyes
1DhGE_OQGreater-than-or-equal (ordered, non-signaling)falsetruetruefalseno
1EhGT_OQGreater-than (ordered, non-signaling)falsefalsetruefalseno
1FhTRUE_USTrue (unordered, signaling)truetruetruetrueyes
  1. A is 1st operand; B is 2nd operand
  2. If either A or B is NaN.

Assemblers may implement the following pseudo-mnemonics for the various predicate values:

Pseudo-Mnemonic FormEncoded Form
CMPEQSS src1, src2CMPSS src1, src2, 00h
CMPLTSS src1, src2CMPSS src1, src2, 01h
CMPLESS src1, src2CMPSS src1, src2, 02h
CMPUNORDSS src1, src2CMPSS src1, src2, 03h
CMPNEQSS src1, src2CMPSS src1, src2, 04h
CMPNLTSS src1, src2CMPSS src1, src2, 05h
CMPNLESS src1, src2CMPSS src1, src2, 06h
CMPORDSS src1, src2CMPSS src1, src2, 07h
VCMPEQSS dest, src1, src2VCMPSS dest, src1, src2, 00h
VCMPLTSS dest, src1, src2VCMPSS dest, src1, src2, 01h
VCMPLESS dest, src1, src2VCMPSS dest, src1, src2, 02h
VCMPUNORDSS dest, src1, src2VCMPSS dest, src1, src2, 03h
VCMPNEQSS dest, src1, src2VCMPSS dest, src1, src2, 04h
VCMPNLTSS dest, src1, src2VCMPSS dest, src1, src2, 05h
VCMPNLESS dest, src1, src2VCMPSS dest, src1, src2, 06h
VCMPORDSS dest, src1, src2VCMPSS dest, src1, src2, 07h
VCMPEQ_UQSS dest, src1, src2VCMPSS dest, src1, src2, 08h
VCMPNGESS dest, src1, src2VCMPSS dest, src1, src2, 09h
VCMPNGTSS dest, src1, src2VCMPSS dest, src1, src2, 0Ah
VCMPFALSESS dest, src1, src2VCMPSS dest, src1, src2, 0Bh
VCMPNEQ_OQSS dest, src1, src2VCMPSS dest, src1, src2, 0Ch
VCMPGESS dest, src1, src2VCMPSS dest, src1, src2, 0Dh
VCMPGTSS dest, src1, src2VCMPSS dest, src1, src2, 0Eh
VCMPTRUESS dest, src1, src2VCMPSS dest, src1, src2, 0Fh
VCMPEQ_OSSS dest, src1, src2VCMPSS dest, src1, src2, 10h
VCMPLT_OQSS dest, src1, src2VCMPSS dest, src1, src2, 11h
VCMPLE_OQSS dest, src1, src2VCMPSS dest, src1, src2, 12h
VCMPUNORD_SSS dest, src1, src2VCMPSS dest, src1, src2, 13h
VCMPNEQ_USSS dest, src1, src2VCMPSS dest, src1, src2, 14h
VCMPNLT_UQSS dest, src1, src2VCMPSS dest, src1, src2, 15h
VCMPNLE_UQSS dest, src1, src2VCMPSS dest, src1, src2, 16h
VCMPORD_SPDSS dest, src1, src2VCMPSS dest, src1, src2, 17h
VCMPEQ_USSS dest, src1, src2VCMPSS dest, src1, src2, 18h
VCMPNGE_UQSS dest, src1, src2VCMPSS dest, src1, src2, 19h
VCMPNGT_UQSS dest, src1, src2VCMPSS dest, src1, src2, 1Ah
VCMPFALSE_OSSS dest, src1, src2VCMPSS dest, src1, src2, 1Bh
VCMPNEQ_OSSS dest, src1, src2VCMPSS dest, src1, src2, 1Ch
VCMPGE_OQSS dest, src1, src2VCMPSS dest, src1, src2, 1Dh
VCMPGT_OQSS dest, src1, src2VCMPSS dest, src1, src2, 1Eh
VCMPTRUE_USSS dest, src1, src2VCMPSS dest, src1, src2, 1Fh

Operation

ComparisonFunc[] PredicateMapping8 = new[]
{
    EQ_OQ, //   0 - equal                  (ordered, non-signaling)
    LT_OS, //   1 - less-than              (ordered, signaling)
    LE_OS, //   2 - less-than-or-equal     (ordered, signaling)
    UNORD_Q, // 3 - unordered              (non-signaling)
    NEQ_UQ, //  4 - not-equal              (unordered, non-signaling)
    NLT_US, //  5 - not-less-than          (unordered, signaling)
    NLE_US, //  6 - not-less-than-or-equal (unordered, signaling)
    ORD_Q, //   7 - ordered                (non-signaling)
};
ComparisonFunc[] PredicateMapping32 = new[]
{
    EQ_OQ, //     0 - equal                     (ordered, non-signaling)
    LT_OS, //     1 - less-than                 (ordered, signaling)
    LE_OS, //     2 - less-than-or-equal        (ordered, signaling)
    UNORD_Q, //   3 - unordered                 (non-signaling)
    NEQ_UQ, //    4 - not-equal                 (unordered, non-signaling)
    NLT_US, //    5 - not-less-than             (unordered, signaling)
    NLE_US, //    6 - not-less-than-or-equal    (unordered, signaling)
    ORD_Q, //     7 - ordered                   (non-signaling)
    EQ_UQ, //     8 - equal                     (unordered, non-signaling)
    NGE_US, //    9 - not-greater-than-or-equal (unordered, signaling)
    NGT_US, //   10 - not-greater-than          (unordered, signaling)
    FALSE_OQ, // 11 - false                     (ordered, non-signaling)
    NEQ_OQ, //   12 - not-equal                 (ordered, non-signaling)
    GE_OS, //    13 - greater-than-or-equal     (ordered, signaling)
    GT_OS, //    14 - greater-than              (ordered, signaling)
    TRUE_UQ, //  15 - true                      (unordered, non-signaling)
    EQ_OS, //    16 - equal                     (ordered, signaling)
    LT_OQ, //    17 - less-than                 (ordered, non-signaling)
    LE_OQ, //    18 - less-than-or-equal        (ordered, non-signaling)
    UNORD_S, //  19 - unordered                 (signaling)
    NEQ_US, //   20 - not-equal                 (unordered, signaling)
    NLT_UQ, //   21 - not-less-than             (unordered, non-signaling)
    NLE_UQ, //   22 - not-less-than-or-equal    (unordered, non-signaling)
    ORD_S, //    23 - ordered                   (signaling)
    EQ_US, //    24 - equal                     (unordered, signaling)
    NGE_UQ, //   25 - not-greater-than-or-equal (unordered, non-signaling)
    NGT_UQ, //   26 - not-greater-than          (unordered, non-signaling)
    FALSE_OS, // 27 - false                     (ordered, signaling)
    NEQ_OS, //   28 - not-equal                 (ordered, signaling)
    GE_OQ, //    29 - greater-than-or-equal     (ordered, non-signaling)
    GT_OQ, //    30 - greater-than              (ordered, non-signaling)
    TRUE_US, //  31 - true                      (unordered, signaling)
};

public void CMPSS(SimdU32 dest, SimdF32 src, U8 predicate)
{
    ComparisonFunc func = PredicateMapping8[predicate];
    dest[0] = func(dest[0], src[0]) ? 0xFFFF_FFFF_FFFF_FFFFul : 0;
    // dest[1..] is unmodified
}

public void VCMPSS_Vex(SimdU32 dest, SimdF32 src1, SimdF32 src2, U8 predicate, int kl)
{
    ComparisonFunc func = PredicateMapping32[predicate];
    dest[0] = func(dest[0], src[0]) ? 0xFFFF_FFFF_FFFF_FFFFul : 0;
    dest[1] = src1[1];
    dest[2] = src1[2];
    dest[3] = src1[3];
    dest[4..] = 0;
}

public void VCMPSS_Evex(KMask dest, SimdF32 src1, SimdF32 src2, U8 predicate, KMask k, int kl)
{
    ComparisonFunc func = PredicateMapping32[predicate];
    if (k[0])
        dest[0] = func(dest[0], src[0]) ? 0xFFFF_FFFF_FFFF_FFFFul : 0;
    else
        dest[0] = 0;
    // no merge masking - EVEX.z is implicit (zero masking)
    dest[1..] = 0;
}

Intrinsics

Exceptions

SIMD Floating-Point

#XM
  • #D - Denormal operand.
  • #I - Invalid operation.

Other Exceptions

VEX Encoded Form: See Type 3 Exception Conditions.
EVEX Encoded Form: See Type E3 Exception Conditions.