Introduction
AVX (Advanced Vector Extensions) widened the vector registers from 128 to 256 bits and brought a new instruction prefix, VEX. The 16 xmm registers became the low halves of 16 ymm registers, ymm0–ymm15 (8 outside 64-bit mode). Intel brought AVX with Sandy Bridge, in 2011, and AMD with Bulldozer later the same year.
AVX did three things:
- It gave almost every SSE instruction on the xmm registers, from SSE to SSE4.2, AES-NI and PCLMULQDQ, a VEX form. The forms on the MMX registers, and AMD’s SSE4a, got none. The VEX form has a
vbefore its name, takes an extra source operand so that it does not have to overwrite one (vaddps xmm0, xmm1, xmm2rather thanaddps xmm0, xmm1), and clears the destination’s bits above 127. - It gave the floating-point instructions 256-bit forms on the ymm registers. The integer instructions stayed at 128 bits; their 256-bit forms came with AVX2.
- It added a few new instructions: broadcasts, inserts and extracts of 128-bit halves, permutes, masked loads and stores,
vtestps, andvzeroupperandvzeroall.
F16C adds two instructions that convert between single precision and half precision (FP16). Intel brought it with Ivy Bridge, in 2012, and AMD with Piledriver, also in 2012.
A program checks for AVX with CPUID leaf 01H, ECX bit 28 (AVX), and for F16C with ECX bit 29 (F16C). The processor’s bit is not enough: the operating system must also save the ymm registers on a task switch. So a program also checks ECX bit 27 (OSXSAVE), then runs XGETBV with ECX = 0 and checks that bits 1 (SSE state) and 2 (AVX state) of XCR0 are set.
AVX uses the vector registers, the MXCSR register for rounding and exception masks, and EFLAGS for the compares and tests that set flags. The legacy SSE forms and the AES-NI and PCLMULQDQ instructions are on their own pages (SSE, SSE2, SSE3 and SSSE3, SSE4, Cryptography); this page has their VEX forms, apart from AES-NI and PCLMULQDQ, whose VEX forms are on the Cryptography page.
The VEX prefix
A VEX prefix takes the place of the legacy prefixes 66, F2 and F3, of REX, and of the 0F, 0F 38 and 0F 3A escape bytes. It has two forms:
- C5 and one byte: R (inverted), vvvv (a register, inverted), L and pp. The map is 0F, and W is 0.
- C4 and two bytes: R, X and B (inverted) and the map (1 = 0F, 2 = 0F 38, 3 = 0F 3A), then W, vvvv, L and pp.
pp stands for the mandatory prefix the SSE form used: 0 none, 1 66, 2 F3, 3 F2. L is the length: 0 for 128 bits, 1 for 256. vvvv names the extra source register. Outside 64-bit mode C4 and C5 are also les and lds; a processor reads them as VEX when the next byte’s top two bits are both 1, which les and lds cannot have, as they need a memory operand. See Instruction encoding for the details.
The encodings below are written as Intel writes them: VEX.L.pp.map.W opcode. A missing pp means no prefix. WIG means W is ignored, LIG means L is ignored, and LZ means L must be 0. /r means a ModRM byte with a register in ModRM.reg, /n a ModRM byte whose reg field is n, ib an immediate byte, and /is4 an immediate byte whose bits 7:4 name a fourth register.
Instructions
In the forms, the first operand is the destination. Where there are three, the second is the register in VEX.vvvv and the third the register or memory in ModRM.rm. A scalar instruction (ss or sd) with three operands works on the low element and copies bits 127:32 (or 127:64) of the result from the second operand. Every 128-bit form clears bits 255:128 of its destination register.
Moves
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vmovaps | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.0F.WIG 28 /rVEX.256.0F.WIG 28 /rVEX.128.0F.WIG 29 /rVEX.256.0F.WIG 29 /r | Moves packed single-precision values; memory must be aligned to 16 bytes (32 for ymm), or the instruction faults (#GP) | AVX (Intel Sandy Bridge, 2011) |
vmovapd | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.66.0F.WIG 28 /rVEX.256.66.0F.WIG 28 /rVEX.128.66.0F.WIG 29 /rVEX.256.66.0F.WIG 29 /r | Moves packed double-precision values, aligned as for vmovaps | AVX (Intel Sandy Bridge, 2011) |
vmovups | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.0F.WIG 10 /rVEX.256.0F.WIG 10 /rVEX.128.0F.WIG 11 /rVEX.256.0F.WIG 11 /r | Moves packed single-precision values; memory may be unaligned | AVX (Intel Sandy Bridge, 2011) |
vmovupd | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.66.0F.WIG 10 /rVEX.256.66.0F.WIG 10 /rVEX.128.66.0F.WIG 11 /rVEX.256.66.0F.WIG 11 /r | Moves packed double-precision values; memory may be unaligned | AVX (Intel Sandy Bridge, 2011) |
vmovdqa | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.66.0F.WIG 6F /rVEX.256.66.0F.WIG 6F /rVEX.128.66.0F.WIG 7F /rVEX.256.66.0F.WIG 7F /r | Moves integer data; memory must be aligned to 16 bytes (32 for ymm) | AVX (Intel Sandy Bridge, 2011) |
vmovdqu | xmm1, xmm2/m128ymm1, ymm2/m256xmm2/m128, xmm1ymm2/m256, ymm1 | VEX.128.F3.0F.WIG 6F /rVEX.256.F3.0F.WIG 6F /rVEX.128.F3.0F.WIG 7F /rVEX.256.F3.0F.WIG 7F /r | Moves integer data; memory may be unaligned | AVX (Intel Sandy Bridge, 2011) |
vmovss | xmm1, m32xmm1, xmm2, xmm3m32, xmm1xmm1, xmm2, xmm3 | VEX.LIG.F3.0F.WIG 10 /rVEX.LIG.F3.0F.WIG 10 /rVEX.LIG.F3.0F.WIG 11 /rVEX.LIG.F3.0F.WIG 11 /r | A load fills the low element and clears the rest; a store writes the low element; the register forms take the low element from the third operand and bits 127:32 from the second (with 11, the destination is ModRM.rm) | AVX (Intel Sandy Bridge, 2011) |
vmovsd | xmm1, m64xmm1, xmm2, xmm3m64, xmm1xmm1, xmm2, xmm3 | VEX.LIG.F2.0F.WIG 10 /rVEX.LIG.F2.0F.WIG 10 /rVEX.LIG.F2.0F.WIG 11 /rVEX.LIG.F2.0F.WIG 11 /r | The same for a double-precision value, with bits 127:64 | AVX (Intel Sandy Bridge, 2011) |
vmovlps | xmm1, xmm2, m64m64, xmm1 | VEX.128.0F.WIG 12 /rVEX.128.0F.WIG 13 /r | Loads two single-precision values into the low half and copies the high half from the second operand; or stores the low half | AVX (Intel Sandy Bridge, 2011) |
vmovhps | xmm1, xmm2, m64m64, xmm1 | VEX.128.0F.WIG 16 /rVEX.128.0F.WIG 17 /r | Loads two single-precision values into the high half and copies the low half from the second operand; or stores the high half | AVX (Intel Sandy Bridge, 2011) |
vmovlpd | xmm1, xmm2, m64m64, xmm1 | VEX.128.66.0F.WIG 12 /rVEX.128.66.0F.WIG 13 /r | The same as vmovlps for one double-precision value | AVX (Intel Sandy Bridge, 2011) |
vmovhpd | xmm1, xmm2, m64m64, xmm1 | VEX.128.66.0F.WIG 16 /rVEX.128.66.0F.WIG 17 /r | The same as vmovhps for one double-precision value | AVX (Intel Sandy Bridge, 2011) |
vmovhlps | xmm1, xmm2, xmm3 | VEX.128.0F.WIG 12 /r | The register form of 12: the low half from the third operand’s high half, the high half from the second operand’s high half | AVX (Intel Sandy Bridge, 2011) |
vmovlhps | xmm1, xmm2, xmm3 | VEX.128.0F.WIG 16 /r | The register form of 16: the low half from the second operand’s low half, the high half from the third operand’s low half | AVX (Intel Sandy Bridge, 2011) |
vmovddup | xmm1, xmm2/m64ymm1, ymm2/m256 | VEX.128.F2.0F.WIG 12 /rVEX.256.F2.0F.WIG 12 /r | Copies each even-numbered double-precision value into the element above it | AVX (Intel Sandy Bridge, 2011) |
vmovsldup | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.F3.0F.WIG 12 /rVEX.256.F3.0F.WIG 12 /r | Copies each even-numbered single-precision value into the element above it | AVX (Intel Sandy Bridge, 2011) |
vmovshdup | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.F3.0F.WIG 16 /rVEX.256.F3.0F.WIG 16 /r | Copies each odd-numbered single-precision value into the element below it | AVX (Intel Sandy Bridge, 2011) |
vmovd | xmm1, r32/m32r32/m32, xmm1 | VEX.128.66.0F.W0 6E /rVEX.128.66.0F.W0 7E /r | Moves a doubleword between a general register or memory and the low element of an xmm register; a load clears the rest | AVX (Intel Sandy Bridge, 2011) |
vmovq | xmm1, r64/m64r64/m64, xmm1xmm1, xmm2/m64xmm1/m64, xmm2 | VEX.128.66.0F.W1 6E /rVEX.128.66.0F.W1 7E /rVEX.128.F3.0F.WIG 7E /rVEX.128.66.0F.WIG D6 /r | Moves a quadword to or from the low element of an xmm register; a load clears the rest. The general-register forms exist in 64-bit mode only: elsewhere W1 is ignored and they are vmovd | AVX (Intel Sandy Bridge, 2011) |
vlddqu | xmm1, m128ymm1, m256 | VEX.128.F2.0F.WIG F0 /rVEX.256.F2.0F.WIG F0 /r | Loads unaligned integer data, possibly with a wider read that may be faster across a cache-line boundary | AVX (Intel Sandy Bridge, 2011) |
vmovntps | m128, xmm1m256, ymm1 | VEX.128.0F.WIG 2B /rVEX.256.0F.WIG 2B /r | Stores packed single-precision values with a non-temporal hint (past the caches); memory must be aligned | AVX (Intel Sandy Bridge, 2011) |
vmovntpd | m128, xmm1m256, ymm1 | VEX.128.66.0F.WIG 2B /rVEX.256.66.0F.WIG 2B /r | The same for double-precision values | AVX (Intel Sandy Bridge, 2011) |
vmovntdq | m128, xmm1m256, ymm1 | VEX.128.66.0F.WIG E7 /rVEX.256.66.0F.WIG E7 /r | The same for integer data | AVX (Intel Sandy Bridge, 2011) |
vmovntdqa | xmm1, m128 | VEX.128.66.0F38.WIG 2A /r | Loads 16 aligned bytes with a non-temporal hint, for write-combining memory (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vmaskmovdqu | xmm1, xmm2 | VEX.128.66.0F.WIG F7 /r | Stores the bytes of the first operand whose mask byte in the second has its top bit set, to the address in DS:rDI, with a non-temporal hint | AVX (Intel Sandy Bridge, 2011) |
vmaskmovps | xmm1, xmm2, m128ymm1, ymm2, m256m128, xmm1, xmm2m256, ymm1, ymm2 | VEX.128.66.0F38.W0 2C /rVEX.256.66.0F38.W0 2C /rVEX.128.66.0F38.W0 2E /rVEX.256.66.0F38.W0 2E /r | Loads or stores only the single-precision elements whose mask (the top bit of the matching element of the middle operand, VEX.vvvv) is set. A load zeroes the others. Masked-out elements cause no faults | AVX (Intel Sandy Bridge, 2011) |
vmaskmovpd | xmm1, xmm2, m128ymm1, ymm2, m256m128, xmm1, xmm2m256, ymm1, ymm2 | VEX.128.66.0F38.W0 2D /rVEX.256.66.0F38.W0 2D /rVEX.128.66.0F38.W0 2F /rVEX.256.66.0F38.W0 2F /r | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vmovmskps | r32, xmm2r32, ymm2 | VEX.128.0F.WIG 50 /rVEX.256.0F.WIG 50 /r | Copies the sign bit of each single-precision element into the low bits of a general register, and clears the rest | AVX (Intel Sandy Bridge, 2011) |
vmovmskpd | r32, xmm2r32, ymm2 | VEX.128.66.0F.WIG 50 /rVEX.256.66.0F.WIG 50 /r | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vpmovmskb | r32, xmm1 | VEX.128.66.0F.WIG D7 /r | Copies the top bit of each of the 16 bytes into the low 16 bits of a general register, and clears the rest (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
Broadcast, 128-bit halves and permutes
These came new with AVX and have no SSE form. Apart from vperm2f128, vinsertf128, vextractf128 and the broadcasts, they work within each 128-bit half (lane) of a ymm register.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vbroadcastss | xmm1, m32ymm1, m32 | VEX.128.66.0F38.W0 18 /rVEX.256.66.0F38.W0 18 /r | Loads one single-precision value into every element (the register forms came with AVX2) | AVX (Intel Sandy Bridge, 2011) |
vbroadcastsd | ymm1, m64 | VEX.256.66.0F38.W0 19 /r | Loads one double-precision value into all four elements (the register form came with AVX2) | AVX (Intel Sandy Bridge, 2011) |
vbroadcastf128 | ymm1, m128 | VEX.256.66.0F38.W0 1A /r | Loads 128 bits into both halves | AVX (Intel Sandy Bridge, 2011) |
vinsertf128 | ymm1, ymm2, xmm3/m128, imm8 | VEX.256.66.0F3A.W0 18 /r ib | Copies the second operand and replaces the half that imm8[0] names with the third | AVX (Intel Sandy Bridge, 2011) |
vextractf128 | xmm1/m128, ymm2, imm8 | VEX.256.66.0F3A.W0 19 /r ib | Writes the half of the source that imm8[0] names | AVX (Intel Sandy Bridge, 2011) |
vperm2f128 | ymm1, ymm2, ymm3/m256, imm8 | VEX.256.66.0F3A.W0 06 /r ib | Fills each half of the result with one of the four halves of the two sources (imm8[1:0] for the low half, imm8[5:4] for the high), or with zero where imm8 bit 3 or bit 7 is set | AVX (Intel Sandy Bridge, 2011) |
vpermilps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256xmm1, xmm2/m128, imm8ymm1, ymm2/m256, imm8 | VEX.128.66.0F38.W0 0C /rVEX.256.66.0F38.W0 0C /rVEX.128.66.0F3A.W0 04 /r ibVEX.256.66.0F3A.W0 04 /r ib | Picks each single-precision element from the four in its lane: by bits 1:0 of the matching doubleword of the third operand, or by a two-bit field of imm8 | AVX (Intel Sandy Bridge, 2011) |
vpermilpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256xmm1, xmm2/m128, imm8ymm1, ymm2/m256, imm8 | VEX.128.66.0F38.W0 0D /rVEX.256.66.0F38.W0 0D /rVEX.128.66.0F3A.W0 05 /r ibVEX.256.66.0F3A.W0 05 /r ib | Picks each double-precision element from the two in its lane: by bit 1 of the matching quadword of the third operand, or by one bit of imm8 | AVX (Intel Sandy Bridge, 2011) |
vtestps | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.66.0F38.W0 0E /rVEX.256.66.0F38.W0 0E /r | Tests the sign bits only: sets ZF if the sign bits of (first AND second) are all zero, and CF if those of (NOT first AND second) are all zero; clears AF, OF, PF and SF | AVX (Intel Sandy Bridge, 2011) |
vtestpd | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.66.0F38.W0 0F /rVEX.256.66.0F38.W0 0F /r | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vzeroupper | (none) | VEX.128.0F.WIG 77 | Clears bits 255:128 of every ymm register. Code runs it before legacy SSE code, which leaves those bits alone and can be slow while they are not zero | AVX (Intel Sandy Bridge, 2011) |
vzeroall | (none) | VEX.256.0F.WIG 77 | Clears every ymm register | AVX (Intel Sandy Bridge, 2011) |
Floating-point arithmetic
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vaddps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 58 /rVEX.256.0F.WIG 58 /r | Adds packed single-precision values | AVX (Intel Sandy Bridge, 2011) |
vaddpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 58 /rVEX.256.66.0F.WIG 58 /r | Adds packed double-precision values | AVX (Intel Sandy Bridge, 2011) |
vaddss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 58 /r | Adds the low single-precision values | AVX (Intel Sandy Bridge, 2011) |
vaddsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 58 /r | Adds the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vsubps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 5C /rVEX.256.0F.WIG 5C /r | Subtracts the third operand’s single-precision values from the second’s | AVX (Intel Sandy Bridge, 2011) |
vsubpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 5C /rVEX.256.66.0F.WIG 5C /r | Subtracts packed double-precision values | AVX (Intel Sandy Bridge, 2011) |
vsubss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 5C /r | Subtracts the low single-precision values | AVX (Intel Sandy Bridge, 2011) |
vsubsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 5C /r | Subtracts the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vmulps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 59 /rVEX.256.0F.WIG 59 /r | Multiplies packed single-precision values | AVX (Intel Sandy Bridge, 2011) |
vmulpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 59 /rVEX.256.66.0F.WIG 59 /r | Multiplies packed double-precision values | AVX (Intel Sandy Bridge, 2011) |
vmulss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 59 /r | Multiplies the low single-precision values | AVX (Intel Sandy Bridge, 2011) |
vmulsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 59 /r | Multiplies the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vdivps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 5E /rVEX.256.0F.WIG 5E /r | Divides the second operand’s single-precision values by the third’s | AVX (Intel Sandy Bridge, 2011) |
vdivpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 5E /rVEX.256.66.0F.WIG 5E /r | Divides packed double-precision values | AVX (Intel Sandy Bridge, 2011) |
vdivss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 5E /r | Divides the low single-precision values | AVX (Intel Sandy Bridge, 2011) |
vdivsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 5E /r | Divides the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vminps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 5D /rVEX.256.0F.WIG 5D /r | The smaller of each pair of single-precision values; if either is a NaN, or both are zero, the result is the third operand’s value | AVX (Intel Sandy Bridge, 2011) |
vminpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 5D /rVEX.256.66.0F.WIG 5D /r | The same for double-precision values | AVX (Intel Sandy Bridge, 2011) |
vminss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 5D /r | The smaller of the low single-precision values, as vminps | AVX (Intel Sandy Bridge, 2011) |
vminsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 5D /r | The smaller of the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vmaxps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 5F /rVEX.256.0F.WIG 5F /r | The larger of each pair of single-precision values; if either is a NaN, or both are zero, the result is the third operand’s value | AVX (Intel Sandy Bridge, 2011) |
vmaxpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 5F /rVEX.256.66.0F.WIG 5F /r | The same for double-precision values | AVX (Intel Sandy Bridge, 2011) |
vmaxss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 5F /r | The larger of the low single-precision values | AVX (Intel Sandy Bridge, 2011) |
vmaxsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 5F /r | The larger of the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vsqrtps | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.0F.WIG 51 /rVEX.256.0F.WIG 51 /r | The square root of each single-precision value | AVX (Intel Sandy Bridge, 2011) |
vsqrtpd | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.66.0F.WIG 51 /rVEX.256.66.0F.WIG 51 /r | The square root of each double-precision value | AVX (Intel Sandy Bridge, 2011) |
vsqrtss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 51 /r | The square root of the third operand’s low single-precision value | AVX (Intel Sandy Bridge, 2011) |
vsqrtsd | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 51 /r | The square root of the third operand’s low double-precision value | AVX (Intel Sandy Bridge, 2011) |
vrcpps | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.0F.WIG 53 /rVEX.256.0F.WIG 53 /r | An approximate reciprocal of each single-precision value, with a relative error of at most 1.5 × 2−12 | AVX (Intel Sandy Bridge, 2011) |
vrcpss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 53 /r | An approximate reciprocal of the third operand’s low value | AVX (Intel Sandy Bridge, 2011) |
vrsqrtps | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.0F.WIG 52 /rVEX.256.0F.WIG 52 /r | An approximate reciprocal square root of each single-precision value, with a relative error of at most 1.5 × 2−12 | AVX (Intel Sandy Bridge, 2011) |
vrsqrtss | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 52 /r | An approximate reciprocal square root of the third operand’s low value | AVX (Intel Sandy Bridge, 2011) |
vaddsubps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.F2.0F.WIG D0 /rVEX.256.F2.0F.WIG D0 /r | Subtracts in the even-numbered single-precision elements and adds in the odd-numbered ones | AVX (Intel Sandy Bridge, 2011) |
vaddsubpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG D0 /rVEX.256.66.0F.WIG D0 /r | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vhaddps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.F2.0F.WIG 7C /rVEX.256.F2.0F.WIG 7C /r | Adds adjacent pairs of single-precision values: those of the second operand into the low half of each lane, those of the third into the high half | AVX (Intel Sandy Bridge, 2011) |
vhaddpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 7C /rVEX.256.66.0F.WIG 7C /r | Adds the two double-precision values of each lane of the second operand into the low element, and those of the third into the high element | AVX (Intel Sandy Bridge, 2011) |
vhsubps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.F2.0F.WIG 7D /rVEX.256.F2.0F.WIG 7D /r | As vhaddps, subtracting the upper value of each pair from the lower | AVX (Intel Sandy Bridge, 2011) |
vhsubpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 7D /rVEX.256.66.0F.WIG 7D /r | As vhaddpd, subtracting | AVX (Intel Sandy Bridge, 2011) |
vdpps | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.66.0F3A.WIG 40 /r ibVEX.256.66.0F3A.WIG 40 /r ib | Dot product in each lane: multiplies the single-precision values that imm8[7:4] picks, adds the products, and writes the sum to the elements that imm8[3:0] picks, zeroing the others | AVX (Intel Sandy Bridge, 2011) |
vdppd | xmm1, xmm2, xmm3/m128, imm8 | VEX.128.66.0F3A.WIG 41 /r ib | The same for the two double-precision values, by imm8[5:4] and imm8[1:0] | AVX (Intel Sandy Bridge, 2011) |
vroundps | xmm1, xmm2/m128, imm8ymm1, ymm2/m256, imm8 | VEX.128.66.0F3A.WIG 08 /r ibVEX.256.66.0F3A.WIG 08 /r ib | Rounds each single-precision value to an integer value: imm8[1:0] is the rounding mode (nearest, down, up, towards zero), imm8[2] set uses MXCSR’s mode instead, and imm8[3] set suppresses the precision exception | AVX (Intel Sandy Bridge, 2011) |
vroundpd | xmm1, xmm2/m128, imm8ymm1, ymm2/m256, imm8 | VEX.128.66.0F3A.WIG 09 /r ibVEX.256.66.0F3A.WIG 09 /r ib | The same for double-precision values | AVX (Intel Sandy Bridge, 2011) |
vroundss | xmm1, xmm2, xmm3/m32, imm8 | VEX.LIG.66.0F3A.WIG 0A /r ib | Rounds the third operand’s low single-precision value, by imm8 as vroundps | AVX (Intel Sandy Bridge, 2011) |
vroundsd | xmm1, xmm2, xmm3/m64, imm8 | VEX.LIG.66.0F3A.WIG 0B /r ib | Rounds the third operand’s low double-precision value | AVX (Intel Sandy Bridge, 2011) |
Floating-point logic
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vandps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 54 /rVEX.256.0F.WIG 54 /r | Bitwise AND | AVX (Intel Sandy Bridge, 2011) |
vandpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 54 /rVEX.256.66.0F.WIG 54 /r | Bitwise AND | AVX (Intel Sandy Bridge, 2011) |
vandnps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 55 /rVEX.256.0F.WIG 55 /r | Bitwise AND of the inverted second operand with the third | AVX (Intel Sandy Bridge, 2011) |
vandnpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 55 /rVEX.256.66.0F.WIG 55 /r | Bitwise AND of the inverted second operand with the third | AVX (Intel Sandy Bridge, 2011) |
vorps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 56 /rVEX.256.0F.WIG 56 /r | Bitwise OR | AVX (Intel Sandy Bridge, 2011) |
vorpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 56 /rVEX.256.66.0F.WIG 56 /r | Bitwise OR | AVX (Intel Sandy Bridge, 2011) |
vxorps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 57 /rVEX.256.0F.WIG 57 /r | Bitwise exclusive OR; with the same register twice, the usual way to clear one | AVX (Intel Sandy Bridge, 2011) |
vxorpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 57 /rVEX.256.66.0F.WIG 57 /r | Bitwise exclusive OR | AVX (Intel Sandy Bridge, 2011) |
Floating-point compare
vcmpps, vcmppd, vcmpss and vcmpsd compare the second operand with the third by a predicate in imm8[4:0], and set each element of the result to all ones where it holds and to zero where not. SSE had predicates 0 to 7; VEX has 32. A predicate is ordered (O) when a NaN makes it false and unordered (U) when a NaN makes it true; it is signalling (S) when a quiet NaN raises the invalid-operation exception, and quiet (Q) when only a signalling NaN does.
As LLVM does, we write predicates 0 to 31 into the mnemonic and drop the immediate (vcmplt_oqps xmm0, xmm1, xmm2). The short names of 0 to 15 are SSE’s and imply the O, U, S or Q of Intel’s full name. Any other immediate byte is shown after the plain mnemonic (vcmpps xmm0, xmm0, xmm1, 0x28); the processor uses only bits 4:0 of it.
| imm8 | In the mnemonic | Intel’s name | True when | With a NaN | A quiet NaN signals |
|---|---|---|---|---|---|
| 0 | eq | EQ_OQ | equal | false | no |
| 1 | lt | LT_OS | less than | false | yes |
| 2 | le | LE_OS | less than or equal | false | yes |
| 3 | unord | UNORD_Q | either is a NaN | true | no |
| 4 | neq | NEQ_UQ | not equal | true | no |
| 5 | nlt | NLT_US | not less than | true | yes |
| 6 | nle | NLE_US | not less than or equal | true | yes |
| 7 | ord | ORD_Q | neither is a NaN | false | no |
| 8 | eq_uq | EQ_UQ | equal | true | no |
| 9 | nge | NGE_US | not greater than or equal | true | yes |
| 10 | ngt | NGT_US | not greater than | true | yes |
| 11 | false | FALSE_OQ | never | false | no |
| 12 | neq_oq | NEQ_OQ | not equal | false | no |
| 13 | ge | GE_OS | greater than or equal | false | yes |
| 14 | gt | GT_OS | greater than | false | yes |
| 15 | true | TRUE_UQ | always | true | no |
| 16 | eq_os | EQ_OS | equal | false | yes |
| 17 | lt_oq | LT_OQ | less than | false | no |
| 18 | le_oq | LE_OQ | less than or equal | false | no |
| 19 | unord_s | UNORD_S | either is a NaN | true | yes |
| 20 | neq_us | NEQ_US | not equal | true | yes |
| 21 | nlt_uq | NLT_UQ | not less than | true | no |
| 22 | nle_uq | NLE_UQ | not less than or equal | true | no |
| 23 | ord_s | ORD_S | neither is a NaN | false | yes |
| 24 | eq_us | EQ_US | equal | true | yes |
| 25 | nge_uq | NGE_UQ | not greater than or equal | true | no |
| 26 | ngt_uq | NGT_UQ | not greater than | true | no |
| 27 | false_os | FALSE_OS | never | false | yes |
| 28 | neq_os | NEQ_OS | not equal | false | yes |
| 29 | ge_oq | GE_OQ | greater than or equal | false | no |
| 30 | gt_oq | GT_OQ | greater than | false | no |
| 31 | true_us | TRUE_US | always | true | yes |
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vcmpps | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.0F.WIG C2 /r ibVEX.256.0F.WIG C2 /r ib | Compares packed single-precision values. Predicate names: vcmpeqps, vcmpltps, vcmpleps, vcmpunordps, vcmpneqps, vcmpnltps, vcmpnleps, vcmpordps, vcmpeq_uqps, vcmpngeps, vcmpngtps, vcmpfalseps, vcmpneq_oqps, vcmpgeps, vcmpgtps, vcmptrueps, vcmpeq_osps, vcmplt_oqps, vcmple_oqps, vcmpunord_sps, vcmpneq_usps, vcmpnlt_uqps, vcmpnle_uqps, vcmpord_sps, vcmpeq_usps, vcmpnge_uqps, vcmpngt_uqps, vcmpfalse_osps, vcmpneq_osps, vcmpge_oqps, vcmpgt_oqps, vcmptrue_usps | AVX (Intel Sandy Bridge, 2011) |
vcmppd | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.66.0F.WIG C2 /r ibVEX.256.66.0F.WIG C2 /r ib | Compares packed double-precision values. Predicate names: vcmpeqpd, vcmpltpd, vcmplepd, vcmpunordpd, vcmpneqpd, vcmpnltpd, vcmpnlepd, vcmpordpd, vcmpeq_uqpd, vcmpngepd, vcmpngtpd, vcmpfalsepd, vcmpneq_oqpd, vcmpgepd, vcmpgtpd, vcmptruepd, vcmpeq_ospd, vcmplt_oqpd, vcmple_oqpd, vcmpunord_spd, vcmpneq_uspd, vcmpnlt_uqpd, vcmpnle_uqpd, vcmpord_spd, vcmpeq_uspd, vcmpnge_uqpd, vcmpngt_uqpd, vcmpfalse_ospd, vcmpneq_ospd, vcmpge_oqpd, vcmpgt_oqpd, vcmptrue_uspd | AVX (Intel Sandy Bridge, 2011) |
vcmpss | xmm1, xmm2, xmm3/m32, imm8 | VEX.LIG.F3.0F.WIG C2 /r ib | Compares the low single-precision values. Predicate names: vcmpeqss, vcmpltss, vcmpless, vcmpunordss, vcmpneqss, vcmpnltss, vcmpnless, vcmpordss, vcmpeq_uqss, vcmpngess, vcmpngtss, vcmpfalsess, vcmpneq_oqss, vcmpgess, vcmpgtss, vcmptruess, vcmpeq_osss, vcmplt_oqss, vcmple_oqss, vcmpunord_sss, vcmpneq_usss, vcmpnlt_uqss, vcmpnle_uqss, vcmpord_sss, vcmpeq_usss, vcmpnge_uqss, vcmpngt_uqss, vcmpfalse_osss, vcmpneq_osss, vcmpge_oqss, vcmpgt_oqss, vcmptrue_usss | AVX (Intel Sandy Bridge, 2011) |
vcmpsd | xmm1, xmm2, xmm3/m64, imm8 | VEX.LIG.F2.0F.WIG C2 /r ib | Compares the low double-precision values. Predicate names: vcmpeqsd, vcmpltsd, vcmplesd, vcmpunordsd, vcmpneqsd, vcmpnltsd, vcmpnlesd, vcmpordsd, vcmpeq_uqsd, vcmpngesd, vcmpngtsd, vcmpfalsesd, vcmpneq_oqsd, vcmpgesd, vcmpgtsd, vcmptruesd, vcmpeq_ossd, vcmplt_oqsd, vcmple_oqsd, vcmpunord_ssd, vcmpneq_ussd, vcmpnlt_uqsd, vcmpnle_uqsd, vcmpord_ssd, vcmpeq_ussd, vcmpnge_uqsd, vcmpngt_uqsd, vcmpfalse_ossd, vcmpneq_ossd, vcmpge_oqsd, vcmpgt_oqsd, vcmptrue_ussd | AVX (Intel Sandy Bridge, 2011) |
vcomiss | xmm1, xmm2/m32 | VEX.LIG.0F.WIG 2F /r | Compares the low single-precision values and sets ZF, PF and CF (all three for unordered), and clears OF, AF and SF; a quiet NaN raises the invalid-operation exception | AVX (Intel Sandy Bridge, 2011) |
vcomisd | xmm1, xmm2/m64 | VEX.LIG.66.0F.WIG 2F /r | The same for the low double-precision values | AVX (Intel Sandy Bridge, 2011) |
vucomiss | xmm1, xmm2/m32 | VEX.LIG.0F.WIG 2E /r | As vcomiss, but only a signalling NaN raises the exception | AVX (Intel Sandy Bridge, 2011) |
vucomisd | xmm1, xmm2/m64 | VEX.LIG.66.0F.WIG 2E /r | As vcomisd, but only a signalling NaN raises the exception | AVX (Intel Sandy Bridge, 2011) |
Conversion
Conversions that can lose precision round by MXCSR.RC; the vcvtt forms truncate towards zero instead. A value too large for the integer gives the “integer indefinite” value, 80000000h (or 8000000000000000h for 64 bits).
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vcvtdq2ps | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.0F.WIG 5B /rVEX.256.0F.WIG 5B /r | Converts signed doublewords to single precision | AVX (Intel Sandy Bridge, 2011) |
vcvtps2dq | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.66.0F.WIG 5B /rVEX.256.66.0F.WIG 5B /r | Converts single precision to signed doublewords, rounding | AVX (Intel Sandy Bridge, 2011) |
vcvttps2dq | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.F3.0F.WIG 5B /rVEX.256.F3.0F.WIG 5B /r | Converts single precision to signed doublewords, truncating | AVX (Intel Sandy Bridge, 2011) |
vcvtdq2pd | xmm1, xmm2/m64ymm1, xmm2/m128 | VEX.128.F3.0F.WIG E6 /rVEX.256.F3.0F.WIG E6 /r | Converts two or four signed doublewords to double precision | AVX (Intel Sandy Bridge, 2011) |
vcvtpd2dq | xmm1, xmm2/m128xmm1, ymm2/m256 | VEX.128.F2.0F.WIG E6 /rVEX.256.F2.0F.WIG E6 /r | Converts two or four double-precision values to signed doublewords, rounding, into the low part of xmm1; the rest is cleared | AVX (Intel Sandy Bridge, 2011) |
vcvttpd2dq | xmm1, xmm2/m128xmm1, ymm2/m256 | VEX.128.66.0F.WIG E6 /rVEX.256.66.0F.WIG E6 /r | The same, truncating | AVX (Intel Sandy Bridge, 2011) |
vcvtps2pd | xmm1, xmm2/m64ymm1, xmm2/m128 | VEX.128.0F.WIG 5A /rVEX.256.0F.WIG 5A /r | Converts two or four single-precision values to double precision | AVX (Intel Sandy Bridge, 2011) |
vcvtpd2ps | xmm1, xmm2/m128xmm1, ymm2/m256 | VEX.128.66.0F.WIG 5A /rVEX.256.66.0F.WIG 5A /r | Converts two or four double-precision values to single precision, into the low part of xmm1; the rest is cleared | AVX (Intel Sandy Bridge, 2011) |
vcvtss2sd | xmm1, xmm2, xmm3/m32 | VEX.LIG.F3.0F.WIG 5A /r | Converts the third operand’s low single-precision value to double precision | AVX (Intel Sandy Bridge, 2011) |
vcvtsd2ss | xmm1, xmm2, xmm3/m64 | VEX.LIG.F2.0F.WIG 5A /r | Converts the third operand’s low double-precision value to single precision | AVX (Intel Sandy Bridge, 2011) |
vcvtsi2ss | xmm1, xmm2, r/m32xmm1, xmm2, r/m64 | VEX.LIG.F3.0F.W0 2A /rVEX.LIG.F3.0F.W1 2A /r | Converts a signed integer to single precision, into the low element; the 64-bit form exists in 64-bit mode only | AVX (Intel Sandy Bridge, 2011) |
vcvtsi2sd | xmm1, xmm2, r/m32xmm1, xmm2, r/m64 | VEX.LIG.F2.0F.W0 2A /rVEX.LIG.F2.0F.W1 2A /r | Converts a signed integer to double precision, into the low element | AVX (Intel Sandy Bridge, 2011) |
vcvtss2si | r32, xmm1/m32r64, xmm1/m32 | VEX.LIG.F3.0F.W0 2D /rVEX.LIG.F3.0F.W1 2D /r | Converts the low single-precision value to a signed integer, rounding | AVX (Intel Sandy Bridge, 2011) |
vcvtsd2si | r32, xmm1/m64r64, xmm1/m64 | VEX.LIG.F2.0F.W0 2D /rVEX.LIG.F2.0F.W1 2D /r | Converts the low double-precision value to a signed integer, rounding | AVX (Intel Sandy Bridge, 2011) |
vcvttss2si | r32, xmm1/m32r64, xmm1/m32 | VEX.LIG.F3.0F.W0 2C /rVEX.LIG.F3.0F.W1 2C /r | The same as vcvtss2si, truncating | AVX (Intel Sandy Bridge, 2011) |
vcvttsd2si | r32, xmm1/m64r64, xmm1/m64 | VEX.LIG.F2.0F.W0 2C /rVEX.LIG.F2.0F.W1 2C /r | The same as vcvtsd2si, truncating | AVX (Intel Sandy Bridge, 2011) |
vcvtph2ps | xmm1, xmm2/m64ymm1, xmm2/m128 | VEX.128.66.0F38.W0 13 /rVEX.256.66.0F38.W0 13 /r | Converts four or eight half-precision (FP16) values to single precision | F16C (Intel Ivy Bridge, 2012) |
vcvtps2ph | xmm1/m64, xmm2, imm8xmm1/m128, ymm2, imm8 | VEX.128.66.0F3A.W0 1D /r ibVEX.256.66.0F3A.W0 1D /r ib | Converts four or eight single-precision values to half precision. imm8[1:0] is the rounding mode (nearest, down, up, towards zero); with imm8[2] set, MXCSR.RC is used instead | F16C (Intel Ivy Bridge, 2012) |
Floating-point shuffle, blend, insert and extract
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vshufps | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.0F.WIG C6 /r ibVEX.256.0F.WIG C6 /r ib | In each lane, picks the two low elements from the second operand and the two high ones from the third, each by a two-bit field of imm8 | AVX (Intel Sandy Bridge, 2011) |
vshufpd | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.66.0F.WIG C6 /r ibVEX.256.66.0F.WIG C6 /r ib | In each lane, picks the low element from the second operand and the high one from the third, each by one bit of imm8 | AVX (Intel Sandy Bridge, 2011) |
vunpcklps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 14 /rVEX.256.0F.WIG 14 /r | Interleaves the single-precision values of the low halves of each lane of the two sources | AVX (Intel Sandy Bridge, 2011) |
vunpckhps | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.0F.WIG 15 /rVEX.256.0F.WIG 15 /r | Interleaves those of the high halves | AVX (Intel Sandy Bridge, 2011) |
vunpcklpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 14 /rVEX.256.66.0F.WIG 14 /r | Takes the low double-precision value of each lane of the second operand, then that of the third | AVX (Intel Sandy Bridge, 2011) |
vunpckhpd | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.66.0F.WIG 15 /rVEX.256.66.0F.WIG 15 /r | The same with the high values | AVX (Intel Sandy Bridge, 2011) |
vblendps | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.66.0F3A.WIG 0C /r ibVEX.256.66.0F3A.WIG 0C /r ib | Takes each single-precision element from the third operand where its bit of imm8 is set, and from the second where not | AVX (Intel Sandy Bridge, 2011) |
vblendpd | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8 | VEX.128.66.0F3A.WIG 0D /r ibVEX.256.66.0F3A.WIG 0D /r ib | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vblendvps | xmm1, xmm2, xmm3/m128, xmm4ymm1, ymm2, ymm3/m256, ymm4 | VEX.128.66.0F3A.W0 4A /r /is4VEX.256.66.0F3A.W0 4A /r /is4 | Takes each single-precision element from the third operand where the sign bit of the matching element of the fourth is set, and from the second where not | AVX (Intel Sandy Bridge, 2011) |
vblendvpd | xmm1, xmm2, xmm3/m128, xmm4ymm1, ymm2, ymm3/m256, ymm4 | VEX.128.66.0F3A.W0 4B /r /is4VEX.256.66.0F3A.W0 4B /r /is4 | The same for double-precision elements | AVX (Intel Sandy Bridge, 2011) |
vinsertps | xmm1, xmm2, xmm3/m32, imm8 | VEX.128.66.0F3A.WIG 21 /r ib | Copies the second operand, puts one single-precision value in the element imm8[5:4] names, and zeroes the elements set in imm8[3:0]. The value is element imm8[7:6] of a register, or the doubleword in memory | AVX (Intel Sandy Bridge, 2011) |
vextractps | r/m32, xmm1, imm8 | VEX.128.66.0F3A.WIG 17 /r ib | Writes the single-precision element that imm8[1:0] names to a general register or memory | AVX (Intel Sandy Bridge, 2011) |
Integer add, subtract and multiply
The integer instructions of AVX are 128 bits wide. Most have a 256-bit form, which came with AVX2; each such row links to it.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpaddb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG FC /r | Adds packed bytes, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG FD /r | Adds packed words, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG FE /r | Adds packed doublewords, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG D4 /r | Adds packed quadwords, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddsb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG EC /r | Adds packed signed bytes with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG ED /r | Adds packed signed words with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddusb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DC /r | Adds packed unsigned bytes with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpaddusw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DD /r | Adds packed unsigned words with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG F8 /r | Subtracts the third operand’s bytes from the second’s, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG F9 /r | Subtracts packed words, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG FA /r | Subtracts packed doublewords, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG FB /r | Subtracts packed quadwords, wrapping round (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubsb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E8 /r | Subtracts packed signed bytes with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E9 /r | Subtracts packed signed words with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubusb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG D8 /r | Subtracts packed unsigned bytes with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsubusw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG D9 /r | Subtracts packed unsigned words with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmullw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG D5 /r | Multiplies packed words and keeps the low 16 bits of each product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmulhw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E5 /r | Multiplies packed signed words and keeps the high 16 bits of each product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmulhuw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E4 /r | Multiplies packed unsigned words and keeps the high 16 bits of each product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmulld | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 40 /r | Multiplies packed doublewords and keeps the low 32 bits of each product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmuludq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG F4 /r | Multiplies the unsigned low doubleword of each quadword into a 64-bit product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmuldq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 28 /r | Multiplies the signed low doubleword of each quadword into a 64-bit product (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmulhrsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 0B /r | Multiplies packed signed words and keeps bits 30:15 of each product, rounded: (x × y + 4000h) >> 15 (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaddwd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG F5 /r | Multiplies packed signed words and adds each adjacent pair of products into a doubleword (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaddubsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 04 /r | Multiplies the unsigned bytes of the second operand by the signed bytes of the third and adds each adjacent pair of products into a word, with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
Integer average, absolute value, sign and sums of differences
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpavgb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E0 /r | Averages packed unsigned bytes, rounding up: (x + y + 1) >> 1 (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpavgw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG E3 /r | Averages packed unsigned words, rounding up (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpabsb | xmm1, xmm2/m128 | VEX.128.66.0F38.WIG 1C /r | The absolute value of each signed byte (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpabsw | xmm1, xmm2/m128 | VEX.128.66.0F38.WIG 1D /r | The absolute value of each signed word (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpabsd | xmm1, xmm2/m128 | VEX.128.66.0F38.WIG 1E /r | The absolute value of each signed doubleword (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsignb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 08 /r | Negates, zeroes or keeps each byte of the second operand as the matching byte of the third is negative, zero or positive (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsignw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 09 /r | The same for words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsignd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 0A /r | The same for doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsadbw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG F6 /r | Adds the absolute differences of the eight unsigned bytes in each quadword into the low word of that quadword, and clears the rest of it (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vmpsadbw | xmm1, xmm2, xmm3/m128, imm8 | VEX.128.66.0F3A.WIG 42 /r ib | Sums the absolute differences between one four-byte group of the third operand (picked by imm8[1:0]) and eight overlapping four-byte groups of the second (starting where imm8[2] says), into eight words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphaddw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 01 /r | Adds each adjacent pair of words, those of the second operand into the low half and those of the third into the high half (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphaddd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 02 /r | The same for doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphaddsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 03 /r | As vphaddw, with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphsubw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 05 /r | Subtracts the upper word of each adjacent pair from the lower, arranged as vphaddw (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphsubd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 06 /r | The same for doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphsubsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 07 /r | As vphsubw, with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vphminposuw | xmm1, xmm2/m128 | VEX.128.66.0F38.WIG 41 /r | Finds the smallest of the eight unsigned words: writes it to word 0 and its index to bits 18:16, and clears the rest | AVX (Intel Sandy Bridge, 2011) |
Integer minimum and maximum
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpminsb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 38 /r | The smaller of each pair of signed bytes (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpminsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG EA /r | The smaller of each pair of signed words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpminsd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 39 /r | The smaller of each pair of signed doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpminub | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DA /r | The smaller of each pair of unsigned bytes (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpminuw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3A /r | The smaller of each pair of unsigned words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpminud | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3B /r | The smaller of each pair of unsigned doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxsb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3C /r | The larger of each pair of signed bytes (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxsw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG EE /r | The larger of each pair of signed words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxsd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3D /r | The larger of each pair of signed doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxub | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DE /r | The larger of each pair of unsigned bytes (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxuw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3E /r | The larger of each pair of unsigned words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmaxud | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 3F /r | The larger of each pair of unsigned doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
Integer compare, test and string compare
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpcmpeqb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 74 /r | Sets each byte to all ones where the two bytes are equal, and to zero where not (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpeqw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 75 /r | The same for words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpeqd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 76 /r | The same for doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpeqq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 29 /r | The same for quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpgtb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 64 /r | Sets each byte to all ones where the signed byte of the second operand is greater than that of the third, and to zero where not (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpgtw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 65 /r | The same for signed words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpgtd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 66 /r | The same for signed doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpcmpgtq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 37 /r | The same for signed quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vptest | xmm1, xmm2/m128ymm1, ymm2/m256 | VEX.128.66.0F38.WIG 17 /rVEX.256.66.0F38.WIG 17 /r | Sets ZF if (first AND second) is all zero, and CF if (NOT first AND second) is all zero; clears AF, OF, PF and SF. Its 256-bit form came with AVX, not AVX2 | AVX (Intel Sandy Bridge, 2011) |
vpcmpestri | xmm1, xmm2/m128, imm8 | VEX.128.66.0F3A 61 /r ib | Compares two strings of bytes or words whose lengths are in EAX and EDX, in the way imm8 says, and writes an index to ECX; sets CF, ZF, SF and OF from the result and clears AF and PF | AVX (Intel Sandy Bridge, 2011) |
vpcmpestrm | xmm1, xmm2/m128, imm8 | VEX.128.66.0F3A 60 /r ib | The same, writing a mask to xmm0 instead of an index | AVX (Intel Sandy Bridge, 2011) |
vpcmpistri | xmm1, xmm2/m128, imm8 | VEX.128.66.0F3A 63 /r ib | As vpcmpestri for strings ended by a zero element (implicit lengths) | AVX (Intel Sandy Bridge, 2011) |
vpcmpistrm | xmm1, xmm2/m128, imm8 | VEX.128.66.0F3A 62 /r ib | As vpcmpestrm for strings ended by a zero element | AVX (Intel Sandy Bridge, 2011) |
Integer logic and shifts
The shift forms with an xmm count shift every element by the same count, the low 64 bits of that operand. The forms with imm8 write the register in VEX.vvvv (the first operand) and read ModRM.rm. A count larger than the element’s width gives 0, or for the arithmetic shifts fills the element with its sign.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpand | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DB /r | Bitwise AND (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpandn | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG DF /r | Bitwise AND of the inverted second operand with the third (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpor | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG EB /r | Bitwise OR (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpxor | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG EF /r | Bitwise exclusive OR (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsllw | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG F1 /rVEX.128.66.0F.WIG 71 /6 ib | Shifts each word left, filling with zeros (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpslld | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG F2 /rVEX.128.66.0F.WIG 72 /6 ib | Shifts each doubleword left (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsllq | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG F3 /rVEX.128.66.0F.WIG 73 /6 ib | Shifts each quadword left (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsrlw | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG D1 /rVEX.128.66.0F.WIG 71 /2 ib | Shifts each word right, filling with zeros (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsrld | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG D2 /rVEX.128.66.0F.WIG 72 /2 ib | Shifts each doubleword right, filling with zeros (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsrlq | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG D3 /rVEX.128.66.0F.WIG 73 /2 ib | Shifts each quadword right, filling with zeros (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsraw | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG E1 /rVEX.128.66.0F.WIG 71 /4 ib | Shifts each signed word right, filling with its sign bit (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsrad | xmm1, xmm2, xmm3/m128xmm1, xmm2, imm8 | VEX.128.66.0F.WIG E2 /rVEX.128.66.0F.WIG 72 /4 ib | Shifts each signed doubleword right, filling with its sign bit (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpslldq | xmm1, xmm2, imm8 | VEX.128.66.0F.WIG 73 /7 ib | Shifts the whole register left by imm8 bytes, filling with zeros; a count over 15 clears it (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpsrldq | xmm1, xmm2, imm8 | VEX.128.66.0F.WIG 73 /3 ib | Shifts the whole register right by imm8 bytes, filling with zeros (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
Integer pack and unpack
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpacksswb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 63 /r | Narrows the signed words of both sources to bytes with signed saturation, those of the second operand into the low half (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpackssdw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 6B /r | Narrows signed doublewords to words with signed saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpackuswb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 67 /r | Narrows signed words to unsigned bytes with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpackusdw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 2B /r | Narrows signed doublewords to unsigned words with unsigned saturation (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpcklbw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 60 /r | Interleaves the bytes of the low halves of the two sources (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpcklwd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 61 /r | Interleaves the low words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpckldq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 62 /r | Interleaves the low doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpcklqdq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 6C /r | Interleaves the low quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpckhbw | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 68 /r | Interleaves the bytes of the high halves (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpckhwd | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 69 /r | Interleaves the high words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpckhdq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 6A /r | Interleaves the high doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpunpckhqdq | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F.WIG 6D /r | Interleaves the high quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
Integer shuffle, blend, insert and extract
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpshufb | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.WIG 00 /r | Picks each byte from the second operand by the low four bits of the matching byte of the third; where that byte’s top bit is set, the result byte is zero (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpshufd | xmm1, xmm2/m128, imm8 | VEX.128.66.0F.WIG 70 /r ib | Picks each doubleword from the source by a two-bit field of imm8 (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpshufhw | xmm1, xmm2/m128, imm8 | VEX.128.F3.0F.WIG 70 /r ib | Shuffles the four high words by imm8 and copies the low quadword (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpshuflw | xmm1, xmm2/m128, imm8 | VEX.128.F2.0F.WIG 70 /r ib | Shuffles the four low words by imm8 and copies the high quadword (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpalignr | xmm1, xmm2, xmm3/m128, imm8 | VEX.128.66.0F3A.WIG 0F /r ib | Joins the second operand (high) and the third (low) into 32 bytes, shifts them right by imm8 bytes and keeps the low 16 (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpblendw | xmm1, xmm2, xmm3/m128, imm8 | VEX.128.66.0F3A.WIG 0E /r ib | Takes each word from the third operand where its bit of imm8 is set, and from the second where not (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpblendvb | xmm1, xmm2, xmm3/m128, xmm4 | VEX.128.66.0F3A.W0 4C /r /is4 | Takes each byte from the third operand where the top bit of the matching byte of the fourth is set, and from the second where not (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpextrb | r32/m8, xmm2, imm8 | VEX.128.66.0F3A.W0 14 /r ib | Writes the byte that imm8[3:0] names to memory, or zero-extended to a general register | AVX (Intel Sandy Bridge, 2011) |
vpextrw | r32, xmm1, imm8r32/m16, xmm2, imm8 | VEX.128.66.0F.W0 C5 /r ibVEX.128.66.0F3A.W0 15 /r ib | Writes the word that imm8[2:0] names, zero-extended to a general register, or to memory with the second form | AVX (Intel Sandy Bridge, 2011) |
vpextrd | r32/m32, xmm2, imm8 | VEX.128.66.0F3A.W0 16 /r ib | Writes the doubleword that imm8[1:0] names | AVX (Intel Sandy Bridge, 2011) |
vpextrq | r64/m64, xmm2, imm8 | VEX.128.66.0F3A.W1 16 /r ib | Writes the quadword that imm8[0] names; in 64-bit mode only (elsewhere W1 is ignored and this is vpextrd) | AVX (Intel Sandy Bridge, 2011) |
vpinsrb | xmm1, xmm2, r32/m8, imm8 | VEX.128.66.0F3A.W0 20 /r ib | Copies the second operand and puts a byte (the low byte of a register) in the element imm8[3:0] names | AVX (Intel Sandy Bridge, 2011) |
vpinsrw | xmm1, xmm2, r32/m16, imm8 | VEX.128.66.0F.W0 C4 /r ib | The same with a word, in the element imm8[2:0] names | AVX (Intel Sandy Bridge, 2011) |
vpinsrd | xmm1, xmm2, r32/m32, imm8 | VEX.128.66.0F3A.W0 22 /r ib | The same with a doubleword, in the element imm8[1:0] names | AVX (Intel Sandy Bridge, 2011) |
vpinsrq | xmm1, xmm2, r64/m64, imm8 | VEX.128.66.0F3A.W1 22 /r ib | The same with a quadword, in the element imm8[0] names; in 64-bit mode only (elsewhere this is vpinsrd) | AVX (Intel Sandy Bridge, 2011) |
Integer sign and zero extension
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vpmovsxbw | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 20 /r | Sign-extends 8 bytes to words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovsxbd | xmm1, xmm2/m32 | VEX.128.66.0F38.WIG 21 /r | Sign-extends 4 bytes to doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovsxbq | xmm1, xmm2/m16 | VEX.128.66.0F38.WIG 22 /r | Sign-extends 2 bytes to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovsxwd | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 23 /r | Sign-extends 4 words to doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovsxwq | xmm1, xmm2/m32 | VEX.128.66.0F38.WIG 24 /r | Sign-extends 2 words to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovsxdq | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 25 /r | Sign-extends 2 doublewords to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxbw | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 30 /r | Zero-extends 8 bytes to words (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxbd | xmm1, xmm2/m32 | VEX.128.66.0F38.WIG 31 /r | Zero-extends 4 bytes to doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxbq | xmm1, xmm2/m16 | VEX.128.66.0F38.WIG 32 /r | Zero-extends 2 bytes to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxwd | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 33 /r | Zero-extends 4 words to doublewords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxwq | xmm1, xmm2/m32 | VEX.128.66.0F38.WIG 34 /r | Zero-extends 2 words to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
vpmovzxdq | xmm1, xmm2/m64 | VEX.128.66.0F38.WIG 35 /r | Zero-extends 2 doublewords to quadwords (256-bit form) | AVX (Intel Sandy Bridge, 2011) |
MXCSR
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vldmxcsr | m32 | VEX.LZ.0F.WIG AE /2 | Loads MXCSR from memory; setting a reserved bit faults (#GP) | AVX (Intel Sandy Bridge, 2011) |
vstmxcsr | m32 | VEX.LZ.0F.WIG AE /3 | Stores MXCSR to memory | AVX (Intel Sandy Bridge, 2011) |
Notes
- Alignment. Unlike their SSE forms, VEX instructions do not need aligned memory, except the moves that say so:
vmovaps,vmovapd,vmovdqa,vmovntps,vmovntpd,vmovntdqandvmovntdqa. - Mixing VEX and legacy SSE code. A legacy SSE instruction leaves bits 255:128 of its destination alone, while a VEX.128 instruction clears them. On many processors, running legacy SSE code while those bits are not zero is slow, so compilers put
vzeroupperbefore calls into such code. - Exceptions. The floating-point instructions raise the SIMD floating-point exceptions (invalid, denormal, divide by zero, overflow, underflow, precision), masked or not by MXCSR. Apart from
vcomiss,vucomiss, their double-precision forms,vptest,vtestps,vtestpdand the string compares, none of these instructions changes EFLAGS. - VEX.L. Where a row shows only 128-bit forms, VEX.L must be 0;
vbroadcastsd,vbroadcastf128,vinsertf128,vextractf128andvperm2f128have only VEX.256. The scalar forms ignore VEX.L (LIG). - VEX.W. WIG means W is ignored. For
vpextrb,vpextrw,vpinsrbandvpinsrw, Intel’s manual gives W0 (and says that VEX.W1 is ignored forvpextrb); we decode W1 the same way, as LLVM does. Outside 64-bit mode, VEX.W1 does not makevmovq,vpextrq,vpinsrq,vcvtsi2ssand the rest 64-bit: they act as their 32-bit forms, and we show them so. - The fourth register outside 64-bit mode. For
vblendvps,vblendvpdandvpblendvb, only xmm0–xmm7 exist there, so bit 7 of the/is4byte has no register to name. We ignore it, as GNU binutils does; LLVM does not. - 16-bit code. VEX instructions run in 16-bit protected mode, so we decode them in 16-bit code too. They are not available in real mode or virtual-8086 mode.
- The compare predicates. The predicate names are LLVM’s and GNU’s pseudo-mnemonics, one instruction with different immediates. Intel’s manual lists the same names as pseudo-ops of
VCMPPSand the rest. - Memory sizes.
vcvtpd2dq,vcvttpd2dqandvcvtpd2pswrite an xmm register from either an xmm or a ymm source, so their memory forms differ only in size. Intel syntax shows the size (xmmword ptrorymmword ptr); AT&T syntax writes the mnemonic with anxoryat the end.
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manual; volume 2 describes the VEX prefix and each AVX and F16C instruction, and volume 1 how to detect AVX
- AMD64 Architecture Programmer’s Manual, Volume 4 – AMD’s manual of the media instructions, with AVX and F16C
- x86 and amd64 instruction reference – Félix Cloutier’s unofficial HTML copy of volume 2 of Intel’s manual