xmm регистры, в которых лежат unsigned значения? Нужно узнать в каком большее значение. К сожалению, подсчет Leading Zero Bits невозможен, а все встроенные инструкции сравнивают только signed значения
VPTEST?
Оно, насколько я понял, bitwise and сделает, но не покажет какой из операндов больше
Тебе нужно сравнить ответ с любым слагаемым, если ответ меньше, значит имело место переполнение, но по любому должны быть какие-то флаги
Сравнить то нужно, но вот нигде никакие флаги не задаются, просто "When an individual result is too large to be represented in 8 bits (overflow), the result is wrapped around and the low 8 bits are written to the destination operand (that is, the carry is ignored)."
Так тебе всего-то нужны флаги ZF, SF, OF. Насчёт VPTEST — да, не подойдёт.
У него операнды в xmm
Конвертировать в signed и сравнивать, например. Конвертировать можно, изменив старший бит или вычитая половину диапазона (sub/xor с 0x80...000). Это плюс несколько инструкций, но одной-двумя всё равно не получится.
Можешь посчитать с переполнением и без переполнения и сравнить. Но получится примерно то же по количеству инструкций: movdqa xmm2,xmm0 paddw xmm0,xmm1 paddusw xmm2,xmm1 pcmpeqw xmm2,xmm0 ; плюс что-то делаем с маской в xmm2
так проблема в сравнивании опять же, маска xmm2 будет либо строка едениц, если xmm2 == xmm0, либо строка 0, если соответственно не равны, флаги не трогаются какие либо
А что тебе потом делать-то нужно? Маска в таком виде специально формируется, потому что самый частый следующий шаг - инвертировать маску если нужно, потом замаскировать и заменить часть упакованных значений.
Изначальная цель - сложить, узнать есть ли оверфлоу
Но ты ведь можешь забрать маску pmovmskb в обычный регистр.
А я балбес, видимо, мне переполнение в unsigned сложении надо определить
Так я же предложил решение, что с ним не так? Ну кроме того, что длинное. Если точное место переполнения не интересует, то можно сократить на пару инструкций, отложив финальную проверку до конца цикла.
ааааа, пришлось открыть глаза чтобы понять, что написано. Осталось понять как узнать старший бит, менять понятно как
movdqa xmm2,xmm0 ; paddw xmm0,xmm1 ; С переполнением. paddusw xmm2,xmm1 ; С накоплением. pcmpeqw xmm2,xmm0 ; 11..11 совпало, 00..00 нет. pmovmskb eax,xmm2 ; Старшие биты каждого байта маски. cmp (или xor) eax,0xffff ; 2 (одинаковых) бита на слово, 8 слов. jnz overflow ; И там какое-нибудь tzcnt/bsf, если надо. Наверняка быстрее можно, если что-то поновее SSE2 взять. Но надо думать/мерять.
Гипотетическая ситуация: xmm0 задан старший бит, а у xmm1 не задан, а в unsigned сумме переполнения нет. После paddw и paddusw в xmm0 и xmm2 будут лежать разные числа => дальше пойдем по логике overflow, однако переполнения в реале нет. Во избежание такого, нужно конвертировать числа из unsigned в signed, как и было уже написано тобой, но просто ксорить или вычитатать нельзя, потому что теряется информация о старшем бите, который как раз и определяет будет ли переполнение или нет. А считать старший бит xmm регистров без avx512 невозможно (или я уже не знаю)
А почему будут разные-то? Давай для двухбитных: 10 + 01 = 11, с накоплением тоже 11. И нет, при преобразовании в signed сдвигом диапазона ничего не теряется, просто телодвижений больше.
когда переходим из unsigned в signed 2^128 -> 2^127 - 1 бит под знак. По этой же причине будут и разные результаты, потому что число с заданным старшим битом будет как отрицательное во время paddw
Обсуждают сегодня