2010-03-08 20 views
7

En SSE, los prefijos 066h (modifican el tamaño del operando) 0F2H (REPNE) y 0F3h (REPE) forman parte del código de operación.Combinación de prefijos en SSE

En SSE 066h conmuta entre operaciones de 32 bits (o 64 bits) y 16 bits. 0F2h y 0F3h se utilizan para operaciones de cuerda. Se pueden combinar para que 066h y 0F2h (o 0F3h) se puedan usar en la misma instrucción, porque esto es significativo. ¿Cuál es el comportamiento en una instrucción SSE? Por ejemplo, hemos (ignorando mod/rm por ahora):

0f 58 ->addps

66 0f 58 ->addpd

f2 0f 58 ->addsd

f3 0f 58 ->addss

Pero, ¿qué es esto?

66 f2 0f 58

Y qué tal?

f2 66 0f 58

Por no mencionar lo siguiente, que tiene dos conflictivos prefijos REP:

f2 f3 0f 58

¿Cuál es la especificación de estos?

+1

¿No es F3 0f 58 ADDSS en lugar de ADDPD? – PhiS

+0

¡Uy! ¡fijo! Gracias –

Respuesta

3

No recuerdo haber visto ninguna especificación sobre lo que debería esperar en el caso de combinar salvajemente prefijos aleatorios, así que supongo que el comportamiento de la CPU puede ser "indefinido" y posiblemente específico de la CPU. (Claramente, algunas cosas se especifican en, por ejemplo, los documentos de Intel, pero muchos casos no están cubiertos). Y algunas combinaciones pueden reservarse para uso futuro.

Mis suposiciones ingenuas generalmente habrían sido que los prefijos adicionales no funcionarían, pero no hay garantía. Eso parece razonable dado que, por ejemplo, algunos manuales optimizando recomiendan varios bytes NOP (canónicamente 90h) prefijando 66h, por ejemplo:

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

Sin embargo, también sé que CS y DS prefijos reemplazo de segmento han adquirido nuevas funciones como SSE2 prefijos de sugerencia rama (predecir rama taken = 3Eh = DS anular; predecir rama no tomada = 2Eh = CS anular) cuando se aplica a las instrucciones de salto condicional.

De todos modos, miré sus ejemplos anteriores, siempre ha marcado a todos XMM10 y XMM7 a todos 0FFh por

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

y luego el código en cuestión, con xmm1, xmm7 argumentos.Lo que he observado (código de 32 bits en un sistema Win64 e Intel T7300 Core 2 Duo) era:

1) ningún cambio observado para addsd añadiendo 66h prefijo

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

2) ningún cambio observado para addss añadiendo 0F2h prefijo

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

3) Sin embargo, he observado un cambio prefijando addpd por 0F2h:

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

En este caso, el resultado en XMM1 fue 0000000000000000FFFFFFFFFFFFFFFFh en lugar de FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh.

Así que mi conclusión es que uno no debe hacer suposiciones y esperar un comportamiento "indefinido". No me sorprendería, sin embargo, si pudiera encontrar algunas pistas en Agner fog's manuals.

+0

En el último caso, al parecer, el '0F2h' tenía prioridad sobre el' 066h', y convirtió la instrucción en 'addsd', por lo que solo se escribió un fragmento. –

+0

Esa sería una hipótesis, sí. Sin embargo, creo que sería una mala idea si alguien quisiera confiar en tal comportamiento. – PhiS