XOP (från engelska eXtended Operations - extended operations [1] ) är en förlängning av x86 / AMD64- instruktionsuppsättningen , tillkännagiven av AMD Corporation den 1 maj 2009.
Det är en förlängning och utveckling av idéer implementerade i 128-bitars SSE - instruktioner i x86 / x86-64-arkitekturer . Implementerad från och med AMD Bulldozer- mikroprocessormikroarkitekturen (12 oktober 2011). [2] Stöds inte på AMD-processorer sedan Zen mikroarkitektur (Ryzen, EPIC; 2017) [3] .
XOP-instruktionsuppsättningen innehåller flera olika typer av vektorinstruktioner, eftersom den ursprungligen var tänkt som en större uppdatering av SSE . De flesta instruktionerna är heltal, men uppsättningen innehåller också instruktioner för att permutera flyttal och instruktioner för att extrahera bråkdelen.
XOP är en omarbetning av några av idéerna som ursprungligen var avsedda för SSE5 . Satsen har modifierats för att vara mer AVX- liknande , utan att duplicera instruktioner. Instruktioner som överlappar AVX har tagits bort eller flyttats till separata tillägg, till exempel FMA4 ( flyttalsvektor multiply -add ) och CVT16 ( halvprecisionskonverteringar , implementerade av Intel som F16C). [ett]
Alla SSE5-instruktioner, för vilka det fanns en analog eller motsvarande i AVX- och FMA3- uppsättningarna , använder kodningar som föreslagits av Intel. Heltalsinstruktioner utan motsvarigheter i AVX har klassificerats som en XOP-tillägg. [1] XOP-instruktioner är kodade med opkoder som börjar vid byte 0x8F ( hexadecimalt värde), men använder annars ett kodningsschema nästan identiskt med AVX med ett 3-byte VEX-prefix.
Vissa experter (Agner Fog) [4] tog detta som ett tecken på att Intel inte tillät AMD att använda någon del av det stora VEX-kodutrymmet. AMD var förmodligen tvungen att använda olika koder för att undvika alla kombinationer som Intel kunde använda i framtiden. XOP-kodningsschemat är så nära VEX som möjligt, men eliminerar risken för överlappning med framtida Intel-opkoder.
Användningen av byte 8F kräver att m-biten (se VEX-kodningsschema) är större än eller lika med 8 för att undvika att störa för närvarande definierade instruktioner. Byten 0xC4 som används i VEX-schemat har ingen sådan begränsning. På grund av detta kan användningen av m-bitar för andra ändamål i framtiden i XOP-schemat vara svårt (VEX har inga begränsningar för m-bitar). Ett annat möjligt problem är att pp-bitarna i XOP alltid är satta till 00, medan de i VEX är satta till 01 för att indikera att instruktionen inte har några föråldrade motsvarigheter. Detta kan göra det svårare att använda pp-bitarna för andra ändamål i framtiden.
Ett liknande kompatibilitetsproblem är skillnaden mellan implementeringarna av FMA3- och FMA4-tilläggen . Intel föreslog ursprungligen FMA4-förlängningen som en del av AVX/FMA version 3-specifikationen för att ersätta den 3-operand FMA-variant som föreslagits av AMD i SSE5. Efter att AMD implementerat FMA4, övergav Intel FMA4 och återgick till FMA3 i version 5 av AVX/FMA-specifikationen. [1] [5] [6]
I mars 2015 avslöjade AMD i en patchbeskrivning för GNU Binutils-paketet att Zen , den tredje generationen av x86-64-arkitekturen, i sin första utgåva (znver1 - Zen, version 1), inte kommer att stödja TBM, FMA4, XOP och LWP-instruktioner utvecklade av specifikt för "Bulldozer"-familjen av mikroarkitekturer. [7] [8]
Dessa instruktioner är heltalsmotsvarigheten till FMA-instruktionsuppsättningarna . De är alla fyra operandinstruktioner, liknande FMA4, och de fungerar alla på signerade heltal.
Instruktion | Beskrivning [9] | Drift |
---|---|---|
VPMACSWW
VPMACSSWW |
Multiplicera ackumulera (med mättnad) ord till ord | 2x8 ord (a0-a7, b0-b7) + 8 ord (c0-c7) → 4 ord (r0-r7)
r0 = a0 * b0 + c0, r1 = a1 * b1 + c1, .. |
VPMACSWD
VPMACSSWD |
Multiplicera ackumulera (med mättnad) lågord till dubbelord | 2x8 ord (a0-a7, b0-b7) + 4 dubbelord (c0-c3) → 4 dubbelord (r0-r3)
r0 = a0 * b0 + c0, r1 = a2 * b2 + cl, . [2] |
VPMACSDD
VPMACSSDD |
Multiplicera ackumulera (med mättnad) Doubleword till Doubleword | 2x4 dubbelord (a0-a3, b0-b3) + 4 dubbelord (c0-c3) → 4 dubbelord (r0-r3)
r0 = a0 * b0 + c0, r1 = a1 * b1 + c1, .. |
VPMACSDQL
VPMACSSDQL |
Multiplicera ackumulera (med mättnad) lågt dubbelord till fyrord | 2x4 dubbelord (a0-a3, b0-b3) + 2 kvaord (c0-c1) → 2 sökord (r0-r3)
r0 = a0 * b0 + c0, r1 = a2 * b2 + cl |
VPMACSDQH
VPMACSSDQH |
Multiplicera ackumulera (med mättnad) Hög dubbelord till fyrord | 2x4 dubbelord (a0-a3, b0-b3) + 2 kvaord (c0-c1) → 2 sökord (r0-r3)
r0 = a1 * b1 + c0, r1 = a3 * b3 + cl |
VPMADCSWD
VPMADCSSWD |
Multiplicera Lägg till Accumulate (med Saturation) Word till Doubleword | 2x8 ord (a0-a7, b0-b7) + 4 dubbelord (c0-c3) → 4 dubbelord (r0-r3)
r0 = a0 * b0 + a1 * b1 + c0, r1 = a2 * b2 + a3 * b3 + c1, .. |
Horisontella summainstruktioner lägger till intilliggande värden av ingångsvektorn till varandra. Utdatastorleken i instruktionerna nedan anger hur breda summeringsoperationerna ska vara. Till exempel lägger en horisontell byte-för-ord-summa till två byte åt gången och returnerar resultatet som en vektor av ord; "byte till quadword" lägger till åtta byte i ett steg och returnerar resultatet som en quadword-vektor. Sex ytterligare horisontella additions- och subtraktionsoperationer implementerades i SSSE3 , men de fungerar bara på två indatavektorer och utför två operationer vardera.
Instruktion | Beskrivning [9] | Drift |
---|---|---|
VPHADDBW
VPHADDUBW |
Horisontellt lägg till två signerade/osignerade byte till word | 16 byte (a0-a15) → 8 ord (r0-r7)
r0 = a0+a1, r1 = a2+a3, r2 = a4+a5, … |
VPHADDBD
VPHADDUBD |
Horisontellt lägg till fyra signerade/osignerade byte till dubbelord | 16 byte (a0-a15) → 4 dubbelord (r0-r3)
r0 = a0+a1+a2+a3, r1 = a4+a5+a6+a7, … |
VPHADDBQ
VPHADDUBQ |
Horisontellt lägg till åtta signerade/osignerade byte till quadword | 16 byte (a0-a15) → 2 kvaord (r0-r1)
r0 = a0+a1+a2+a3+a4+a5+a6+a7, … |
VPHADDWD
VPHADDUWD |
Horisontell lägg till två signerade/osignerade ord till dubbelord | 8 ord (a0-a7) → 4 dubbelord (r0-r3)
r0 = a0+a1, r1 = a2+a3, r2 = a4+a5, … |
VPHADDWQ
VPHADDUWQ |
Horisontell lägg till fyra signerade/osignerade ord till quadword | 8 ord (a0-a7) → 2 kvaord (r0-r1)
r0 = a0+a1+a2+a3, r1 = a4+a5+a6+a7 |
VPHADDDQ
VPHADDUDQ |
Horisontellt lägg till två signerade/osignerade dubbelord till fyrord | 4 dubbelord (a0-a3) → 2 kvaord (r0-r1)
ro = aO+al, rl = a2+a3 |
VPHSUBBW | Horisontell subtrahera två signerade byte till ord | 16 byte (a0-a15) → 8 ord (r0-r7)
r0 = a0-a1, r1 = a2-a3, r2 = a4-a5, … |
VPHSUBWD | Horisontell subtrahera två signerade ord till dubbelord | 8 ord (a0-a7) → 4 dubbelord (r0-r3)
r0 = a0-a1, r1 = a2-a3, r2 = a4-a5, … |
VPHSUBDQ | Horisontell subtrahera två signerade dubbelord till fyrord | 4 dubbelord (a0-a3) → 2 kvaord (r0-r1)
ro = aO-al, rl = a2-a3 |
Denna uppsättning vektorinstruktioner använder det omedelbara fältet för kodningen som ett ytterligare argument som bestämmer vilken jämförelse som ska utföras. Det finns åtta möjliga jämförelser för varje instruktion. Vektorerna jämförs och alla jämförelser som är sanna sätter alla bitar i det motsvarande destinationsregistret till 1, och falska jämförelser sätter bitarna till 0. Detta resultat kan direkt användas i VPCMOV-instruktionen, en vektoriserad villkorlig rörelse.
Instruktion | Beskrivning [9] | omedelbar | Jämförelse | |
---|---|---|---|---|
VPCOMB | Jämför Vector Signed Bytes | 000 | Mindre | |
VPCOMW | Jämför vektorsignerade ord | 001 | Mindre eller lika | |
VPCOMD | Jämför vektorsignerade dubbelord | 010 | Mer | |
VPCOMQ | Jämför Vector Signed Quadwords | 011 | Större än eller lika med | |
VPCOMUB | Jämför Vector Unsigned Bytes | 100 | Är jämlika | |
VPCOMUW | Jämför Vector osignerade ord | 101 | Inte lika med | |
VPCOMUD | Jämför Vector Unsigned Doublewords | 110 | Alltid falskt | |
VPCOMUQ | Jämför Vector Unsigned Quadwords | 111 | Alltid sant |
VPCMOV fungerar som en bitvis version av SSE4- blandningsinstruktionerna . För varje bit i väljaroperanden lika med 1, välj resultatbiten från den första källan, om biten i väljaren är 0, välj resultatbiten från den andra källan. När XOP används i kombination med vektorjämförelseoperationer kan du implementera en ternär vektoroperator, eller, om destinationsregistret är det andra argumentet, en vektorvillkorlig rörelse ( CMOV ).
Instruktion | Beskrivning [9] |
---|---|
VPCMOV | Vektor Villkorlig Flytta |
Skiftinstruktioner skiljer sig från de i SSE2-instruktionsuppsättningen genom att de kan skifta varje element med ett annat antal bitar med hjälp av packade tecken med heltal från ett vektorregister. Tecknet anger riktningen för växling eller sväng, positiva värden för växling åt vänster och negativa värden för växling åt höger [10] Intel har implementerat en annan, inkompatibel uppsättning vektorskift- och svängvariabler i AVX2. [elva]
Instruktion | Beskrivning [9] |
---|---|
VPROTB | Packade rotera bytes |
VPROTW | Packade rotera ord |
VPROTD | Packade rotera dubbelord |
VPROTQ | Packade Rotera Quaadwords |
VPSHAB | Packade skiftarithmetiska bytes |
VPSHAW | Packade skiftarithmetiska ord |
VPSHAD | Packade Shift Aritmetic Doublewords |
VPSHAQ | Packade Shift Arithmetic Quadwords |
VPSHLB | Packade skiftlogiska bytes |
VPSHLW | Packade skiftlogiska ord |
VPSHLD | Packade Shift Logical Doublewords |
VPSHLQ | Packad Shift Logical Quaadwords |
VPPERM är en enkel instruktion som kombinerar och utökar PALIGNR- och PSHUFB-instruktionerna från SSSE3 . Vissa jämför det med AltiVec VPERM-instruktionen. [12] Det tar tre register som ingång: två källor och en väljare (tredje). Varje byte i väljaren väljer en av byten i en av de två källorna för att skriva till utgångsregistret. Väljaren kan välja en nollbyte, vända ordningen på bitarna, upprepa den mest signifikanta biten. Alla effekter eller ingångar kan dessutom inverteras.
VPPERMIL2PD- och VPPERMIL2PS-instruktionerna är tvåoperandversioner av VPERMILPD- och VPERMILPS-instruktionerna från AVX-setet . De kan, liksom VPPPERM, välja ett utdatavärde från alla fält i de två ingångsregistren.
Instruktion | Beskrivning [9] |
---|---|
VPPERM | Packad Permute Byte |
VPPERMIL2PD | Permutera två-källor dubbel-precision flytande punkt |
VPPERMIL2PS | Permutera två källor Single-Precision Flytpunkt |
Dessa instruktioner extraherar bråkdelen från packade flyttal. En sådan del av numret kan gå förlorad när du konverterar dem till ett heltal.
Instruktion | Beskrivning [9] |
---|---|
VFRCZPD | Extrahera fraktion packad dubbelprecision flytande punkt |
VFRCZPS | Extrahera fraktion packad Single-Precision Flytpunkt |
VFRCZSD | Extrahera fraktion skalär dubbelprecision flytande punkt |
VFRCZSS | Extrahera fraktion skalär Single-Precision Flytpunkt |
x86-processorinstruktionsuppsättningar | |
---|---|
Intel | |
AMD | |
Cyrix |