Looking at the SSE operators
CMPORDPS - ordered compare packed singles
CMPUNORDPS - unordered compare packed singles
What do ordered and unordered mean? I looked for equivalent instructions in the x86 instruction set, and it only seems to have unordered (FUCOM).
TL:DR: Unordered is a relation two FP values can have. The "Unordered" in
FUCOM
means it doesn't raise an FP exception when the comparison result is unordered, whileFCOM
does. This is the same as the distinction between OQ and OScmpps
predicatesORD and UNORD are two choices of predicate for the
cmppd
/cmpps
/cmpss
/cmpsd
insns (full tables in thecmppd
entry which is alphabetically first). That html extract has readable table formatting, but Intel's official PDF original is somewhat better. (See the x86 tag wiki for links).Two floating point operands are ordered with respect to each other if neither is NaN. They're unordered if either is NaN. i.e.
ordered = (x>y) | (x==y) | (x<y);
. That's right, with floating point it's possible for none of those things to be true. For more Floating Point madness, see Bruce Dawson's excellent series of articles.cmpps
takes a predicate and produces a vector of results, instead of doing a comparison between two scalars and setting flags so you can check any predicate you want after the fact. So it needs specific predicates for everything you can check.The scalar equivalent is
comiss
/ucomiss
to set ZF/PF/CF from the FP comparison result (which works like the x87 compare instructions (see the last section of this answer), but on the low element of XMM regs).To check for unordered, look at
PF
. If the comparison is ordered, you can look at the other flags to see whether the operands were greater, equal, or less (using the same conditions as for unsigned integers, likejae
for Above or Equal).Normally FP exceptions are masked, so this doesn't actually interrupt your program; it just sets the bit in the MXCSR which you can check later.
This is the same as O/UQ vs. O/US flavours of predicate for
cmpps
/vcmpps
. The AVX version of thecmp[ps][sd]
instructions have an expanded choice of predicate, so they needed a naming convention to keep track of them.The O vs. U tells you whether the predicate is true when the operands are unordered.
The Q vs. S tells you whether #I will be raised if either operand is a Quiet NaN. #I will always be raised if either operand is a Signalling NaN, but those are not "naturally occurring". You don't get them as outputs from other operations, only by creating the bit pattern yourself (e.g. as an error-return value from a function, to ensure detection of problems later).
The x87 equivalent is using
fcom
orfucom
to set the FPU status word ->fstsw ax
->sahf
, or preferablyfucomi
to set EFLAGS directly likecomiss
.The U / non-U distinction is the same with x87 instructions as for
comiss
/ucomiss
An ordered comparison checks if neither operand is
NaN
. Conversely, an unordered comparison checks if either operand is aNaN
.This page gives some more information on this:
The idea here is that comparisons with
NaN
are indeterminate. (can't decide the result) So an ordered/unordered comparison checks if this is (or isn't) the case.Result:
NaN
and1.0
givesfalse
.NaN
and1.0
givestrue
.1.0
and1.0
givestrue
.1.0
and1.0
givesfalse
.NaN
andNan
givesfalse
.NaN
andNaN
givestrue
.Perhaps this page on Visual C++ intrinsics can be of help? :)
CMPORDPS
CMPUNORDPS
This Intel guide: http://intel80386.com/simd/mmx2-doc.html contains examples of the two which are fairly straight-forward:
The difference is AND (ordered) vs OR (unordered).