Объединение префиксов в SSE - PullRequest
7 голосов
/ 08 марта 2010

В SSE префиксы 066h (переопределение размера операнда) 0F2H (REPNE) и 0F3h (REPE) являются частью кода операции.

В не-SSE 066h переключается между 32-битной (или 64-битной) и 16-битной операциями. 0F2h и 0F3h используются для строковых операций. Они могут быть объединены так, что 066h и 0F2h (или 0F3h) могут использоваться в одной и той же инструкции, потому что это имеет смысл. Каково поведение в инструкции SSE? Например, у нас есть (игнорируя mod / rm):

0f 58 -> addps

66 0f 58 -> addpd

f2 0f 58 -> addsd

f3 0f 58 -> addss

Но что это?

66 f2 0f 58

А как насчет?

f2 66 0f 58

Не говоря уже о двух конфликтующих префиксах REP:

f2 f3 0f 58

Какова спецификация для них?

1 Ответ

3 голосов
/ 09 марта 2010

Я не помню, чтобы видел какие-либо спецификации на то, что вы должны ожидать в случае дикого объединения случайных префиксов, поэтому я предполагаю, что поведение ЦП может быть "неопределенным" и, возможно, специфичным для ЦП. (Понятно, что некоторые вещи указаны, например, в документации Intel, но многие случаи не рассматриваются). И некоторые комбинации могут быть зарезервированы для будущего использования.

Мои наивные предположения, как правило, заключались бы в том, что дополнительные префиксы были бы неактивными, но нет никакой гарантии. Это кажется разумным, учитывая, например, что в некоторых руководствах по оптимизации рекомендуется использовать многобайтовый NOP (канонически 90h) префикс с 66h, например ::100100

db 66h, 90h; 2-byte NOP
db 66h, 66h, 90h; 3-byte NOP
db 66h, 66h, 66h, 90h; 4-byte NOP

Тем не менее, я также знаю, что префиксы переопределения сегментов CS и DS имеют новые функции в качестве префиксов подсказок ветвей SSE2 (выполнено предсказание перехода = 3Eh = DS переопределено; предсказание перехода не принято = 2Eh = CS переопределить) применительно к инструкциям условного перехода.

В любом случае, я смотрел на ваши примеры выше, всегда устанавливая XMM1 для всех 0 и XMM7 для всех 0FFh на

pxor xmm1, xmm1    ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs 

и затем соответствующий код с xmm1, xmm7 аргументами. То, что я заметил (32-битный код в системе Win64 и Intel T7300 Core 2 Duo) было:

1) никаких изменений не наблюдается для addsd путем добавления префикса 66h

db 66h 
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF     

2) никаких изменений не наблюдается для addss путем добавления префикса 0F2h

db 0f2h     
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF

3) Однако, я заметил изменение, добавив префикс addpd к 0F2h:

db 0f2h    
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF

В этом случае результат в XMM1 был 0000000000000000FFFFFFFFFFFFFFFFh вместо FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh.

Итак, я пришел к выводу, что не следует делать никаких предположений и ожидать "неопределенного" поведения . Однако я не удивлюсь, если вы найдете некоторые подсказки в руководствах Агнера Тумана .

...