TL: DR : Неупорядоченное - это отношение, которое могут иметь два значения FP. «Неупорядоченный» в FUCOM
означает, что он не вызывает исключение FP, когда результат сравнения неупорядочен, в то время как FCOM
делает. Это то же самое, что и различие между предикатами OQ и OS cmpps
ORD и UNORD - два варианта предиката для cmppd
/ cmpps
/ cmpss
/ cmpsd
insns (полные таблицы в записи cmppd
, которая начинается в алфавитном порядке) . Этот HTML-фрагмент имеет удобочитаемое форматирование таблицы, но официальный оригинал Intel в формате PDF несколько лучше. (См. Вики-тег x86 для ссылок).
Два операнда с плавающей точкой упорядочены относительно друг друга, если ни один из них не равен NaN . Они неупорядочены, если любой из них является NaN. т.е. ordered = (x>y) | (x==y) | (x<y);
. Правильно, с плавающей точкой ни одна из этих вещей не может быть правдой. Для получения дополнительной информации о безумии с плавающей точкой см. превосходную серию статей Брюса Доусона.
cmpps
берет предикат и выдает вектор результатов вместо сравнения двух скаляров и установки флагов, чтобы вы могли проверить любой предикат, который вам нужен, после факта. Поэтому для всего, что вы можете проверить, нужны конкретные предикаты.
Скалярный эквивалент равен comiss
/ ucomiss
для установки ZF / PF / CF из результата сравнения FP (который работает как инструкции сравнения x87 (см. Последний раздел этого ответа), но для младшего элемента XMM regs).
Чтобы проверить неупорядоченное, посмотрите на PF
. Если сравнение упорядочено, вы можете посмотреть другие флаги, чтобы увидеть, были ли операнды больше, равны или меньше (, используя те же условия, что и для целых чисел без знака, например, jae
для Above или Equal ) .
Инструкция COMISS отличается от инструкции UCOMISS тем, что она сигнализирует об исключении недопустимой операции SIMD с плавающей запятой (#I), когда исходным операндом является QNaN или SNaN. Инструкция UCOMISS сообщает о недопустимом числовом исключении, только если исходным операндом является SNaN.
Обычно исключения FP маскируются, так что это фактически не прерывает вашу программу; он просто устанавливает бит в MXCSR, который вы можете проверить позже.
Это то же самое, что O / UQ против разновидностей O / US предиката для cmpps
/ vcmpps
. AVX-версия инструкций cmp[ps][sd]
имеет расширенный выбор предикатов, поэтому для их отслеживания требовалось соглашение об именах.
O против U говорит вам, является ли предикат истинным, когда операнды неупорядочены.
Q vs. S говорит вам, будет ли поднято #I, если любой из операндов является тихим NaN. # Я всегда буду вызываться, если любой из операндов является сигнальным NaN, но они не «встречаются естественным образом». Вы не получаете их в качестве выходных данных от других операций, только создавая битовую комбинацию самостоятельно (например, как возвращаемое значение ошибки из функции, чтобы гарантировать обнаружение проблем позже).
Эквивалент x87 использует fcom
или fucom
для установки слова состояния FPU -> fstsw ax
-> sahf
, или предпочтительно fucomi
для прямой установки EFLAGS, например comiss
.
Различие U / non-U с инструкциями x87 такое же, как для comiss
/ ucomiss