x86: Rework how VEX prefixes are decoded.
authorGabe Black <gabeblack@google.com>
Wed, 24 May 2017 10:09:56 +0000 (03:09 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 26 May 2017 20:01:03 +0000 (20:01 +0000)
Remove redundant information from the ExtMachInst, hash the vex
information to ensure the decode cache works properly, print the vex info
when printing an ExtMachInst, consider the vex info when comparing two
ExtMachInsts, fold the info from the vex prefixes into existing settings,
remove redundant decode code, handle vex prefixes one byte at a time and
don't bother building up the entire prefix, and let instructions that care
about vex use it in their implementation, instead of developing an entire
parallel decode tree.

This also eliminates the error prone vex immediate decode table which was
incomplete and would result in an out of bounds access for incorrectly
encoded instructions or when the CPU was mispeculating, as it was (as far
as I can tell) redundant with the tables that already existed for two and
three byte opcodes. There were differences, but I think those may have
been mistakes based on the documentation I found.

Also, in 32 bit mode, the VEX prefixes might actually be LDS or LES
instructions which are still legal in that mode. A valid VEX prefix would
look like an LDS/LES with an otherwise invalid modrm encoding, so use that
as a signal to abort processing the VEX and turn the instruction into an
LES/LDS as appropriate.

Change-Id: Icb367eaaa35590692df1c98862f315da4c139f5c
Reviewed-on: https://gem5-review.googlesource.com/3501
Reviewed-by: Joe Gross <joe.gross@amd.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>

src/arch/x86/decoder.cc
src/arch/x86/decoder.hh
src/arch/x86/decoder_tables.cc
src/arch/x86/isa/bitfields.isa
src/arch/x86/isa/decoder/decoder.isa
src/arch/x86/isa/decoder/vex_opcodes.isa [deleted file]
src/arch/x86/types.hh

index 324eb0219a6555cfd9610907c0314068c518a1a8..930c2b951054ca496804935bca45d87febee8187 100644 (file)
@@ -96,19 +96,18 @@ Decoder::process()
           case PrefixState:
             state = doPrefixState(nextByte);
             break;
-
-          case TwoByteVexState:
-            state = doTwoByteVexState(nextByte);
+          case Vex2Of2State:
+            state = doVex2Of2State(nextByte);
             break;
-
-          case ThreeByteVexFirstState:
-            state = doThreeByteVexFirstState(nextByte);
+          case Vex2Of3State:
+            state = doVex2Of3State(nextByte);
             break;
-
-          case ThreeByteVexSecondState:
-            state = doThreeByteVexSecondState(nextByte);
+          case Vex3Of3State:
+            state = doVex3Of3State(nextByte);
+            break;
+          case VexOpcodeState:
+            state = doVexOpcodeState(nextByte);
             break;
-
           case OneByteOpcodeState:
             state = doOneByteOpcodeState(nextByte);
             break;
@@ -222,19 +221,16 @@ Decoder::doPrefixState(uint8_t nextByte)
         DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte);
         emi.rex = nextByte;
         break;
-
       case Vex2Prefix:
         DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte);
-        emi.vex.zero = nextByte;
-        nextState = TwoByteVexState;
+        emi.vex.present = 1;
+        nextState = Vex2Of2State;
         break;
-
       case Vex3Prefix:
         DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte);
-        emi.vex.zero = nextByte;
-        nextState = ThreeByteVexFirstState;
+        emi.vex.present = 1;
+        nextState = Vex2Of3State;
         break;
-
       case 0:
         nextState = OneByteOpcodeState;
         break;
@@ -246,42 +242,132 @@ Decoder::doPrefixState(uint8_t nextByte)
 }
 
 Decoder::State
-Decoder::doTwoByteVexState(uint8_t nextByte)
+Decoder::doVex2Of2State(uint8_t nextByte)
 {
-    assert(emi.vex.zero == 0xc5);
     consumeByte();
-    TwoByteVex tbe = 0;
-    tbe.first = nextByte;
+    Vex2Of2 vex = nextByte;
+
+    emi.rex.r = !vex.r;
 
-    emi.vex.first.r = tbe.first.r;
-    emi.vex.first.x = 1;
-    emi.vex.first.b = 1;
-    emi.vex.first.map_select = 1;
+    emi.vex.l = vex.l;
+    emi.vex.v = ~vex.v;
+
+    switch (vex.p) {
+      case 0:
+        break;
+      case 1:
+        emi.legacy.op = 1;
+        break;
+      case 2:
+        emi.legacy.rep = 1;
+        break;
+      case 3:
+        emi.legacy.repne = 1;
+        break;
+    }
 
-    emi.vex.second.w = 0;
-    emi.vex.second.vvvv = tbe.first.vvvv;
-    emi.vex.second.l = tbe.first.l;
-    emi.vex.second.pp = tbe.first.pp;
+    emi.opcode.type = TwoByteOpcode;
 
-    emi.opcode.type = Vex;
-    return OneByteOpcodeState;
+    return VexOpcodeState;
 }
 
 Decoder::State
-Decoder::doThreeByteVexFirstState(uint8_t nextByte)
+Decoder::doVex2Of3State(uint8_t nextByte)
 {
+    if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
+        // This was actually an LDS instruction. Reroute to that path.
+        emi.vex.present = 0;
+        emi.opcode.type = OneByteOpcode;
+        emi.opcode.op = 0xC4;
+        return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
+                             nextByte >= 0xA0 && nextByte <= 0xA3);
+    }
+
     consumeByte();
-    emi.vex.first = nextByte;
-    return ThreeByteVexSecondState;
+    Vex2Of3 vex = nextByte;
+
+    emi.rex.r = !vex.r;
+    emi.rex.x = !vex.x;
+    emi.rex.b = !vex.b;
+
+    switch (vex.m) {
+      case 1:
+        emi.opcode.type = TwoByteOpcode;
+        break;
+      case 2:
+        emi.opcode.type = ThreeByte0F38Opcode;
+        break;
+      case 3:
+        emi.opcode.type = ThreeByte0F3AOpcode;
+        break;
+      default:
+        // These encodings are reserved. Pretend this was an undefined
+        // instruction so the main decoder will behave correctly, and stop
+        // trying to interpret bytes.
+        emi.opcode.type = TwoByteOpcode;
+        emi.opcode.op = 0x0B;
+        instDone = true;
+        return ResetState;
+    }
+    return Vex3Of3State;
 }
 
 Decoder::State
-Decoder::doThreeByteVexSecondState(uint8_t nextByte)
+Decoder::doVex3Of3State(uint8_t nextByte)
 {
+    if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
+        // This was actually an LES instruction. Reroute to that path.
+        emi.vex.present = 0;
+        emi.opcode.type = OneByteOpcode;
+        emi.opcode.op = 0xC5;
+        return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
+                             nextByte >= 0xA0 && nextByte <= 0xA3);
+    }
+
     consumeByte();
-    emi.vex.second = nextByte;
-    emi.opcode.type = Vex;
-    return OneByteOpcodeState;
+    Vex3Of3 vex = nextByte;
+
+    emi.rex.w = vex.w;
+
+    emi.vex.l = vex.l;
+    emi.vex.v = ~vex.v;
+
+    switch (vex.p) {
+      case 0:
+        break;
+      case 1:
+        emi.legacy.op = 1;
+        break;
+      case 2:
+        emi.legacy.rep = 1;
+        break;
+      case 3:
+        emi.legacy.repne = 1;
+        break;
+    }
+
+    return VexOpcodeState;
+}
+
+Decoder::State
+Decoder::doVexOpcodeState(uint8_t nextByte)
+{
+    DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte);
+
+    emi.opcode.op = nextByte;
+
+    switch (emi.opcode.type) {
+      case TwoByteOpcode:
+        return processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
+      case ThreeByte0F38Opcode:
+        return processOpcode(ImmediateTypeThreeByte0F38,
+                             UsesModRMThreeByte0F38);
+      case ThreeByte0F3AOpcode:
+        return processOpcode(ImmediateTypeThreeByte0F3A,
+                             UsesModRMThreeByte0F3A);
+      default:
+        panic("Unrecognized opcode type %d.\n", emi.opcode.type);
+    }
 }
 
 // Load the first opcode byte. Determine if there are more opcode bytes, and
@@ -292,14 +378,9 @@ Decoder::doOneByteOpcodeState(uint8_t nextByte)
     State nextState = ErrorState;
     consumeByte();
 
-    if (emi.vex.zero != 0) {
-        DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte);
-        emi.opcode.op = nextByte;
-        const uint8_t opcode_map = emi.vex.first.map_select;
-        nextState = processExtendedOpcode(ImmediateTypeVex[opcode_map]);
-    } else if (nextByte == 0x0f) {
-        nextState = TwoByteOpcodeState;
+    if (nextByte == 0x0f) {
         DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
+        nextState = TwoByteOpcodeState;
     } else {
         DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte);
         emi.opcode.type = OneByteOpcode;
@@ -421,54 +502,6 @@ Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
     return nextState;
 }
 
-Decoder::State
-Decoder::processExtendedOpcode(ByteTable &immTable)
-{
-    //Figure out the effective operand size. This can be overriden to
-    //a fixed value at the decoder level.
-    int logOpSize;
-    if (emi.vex.second.w)
-        logOpSize = 3; // 64 bit operand size
-    else if (emi.vex.second.pp == 1)
-        logOpSize = altOp;
-    else
-        logOpSize = defOp;
-
-    //Set the actual op size
-    emi.opSize = 1 << logOpSize;
-
-    //Figure out the effective address size. This can be overriden to
-    //a fixed value at the decoder level.
-    int logAddrSize;
-    if (emi.legacy.addr)
-        logAddrSize = altAddr;
-    else
-        logAddrSize = defAddr;
-
-    //Set the actual address size
-    emi.addrSize = 1 << logAddrSize;
-
-    //Figure out the effective stack width. This can be overriden to
-    //a fixed value at the decoder level.
-    emi.stackSize = 1 << stack;
-
-    //Figure out how big of an immediate we'll retreive based
-    //on the opcode.
-    const uint8_t opcode = emi.opcode.op;
-
-    if (emi.vex.zero == 0xc5 || emi.vex.zero == 0xc4) {
-        int immType = immTable[opcode];
-        // Assume 64-bit mode;
-        immediateSize = SizeTypeToSize[2][immType];
-    }
-
-    if (opcode == 0x77) {
-        instDone = true;
-        return ResetState;
-    }
-    return ModRMState;
-}
-
 //Get the ModRM byte and determine what displacement, if any, there is.
 //Also determine whether or not to get the SIB byte, displacement, or
 //immediate next.
index 2e5e837645e40d5d433a1b19ce56a6e55879c939..93e5955c80ad258a635b9f1569bf01cec777464a 100644 (file)
@@ -178,9 +178,10 @@ class Decoder
         ResetState,
         FromCacheState,
         PrefixState,
-        TwoByteVexState,
-        ThreeByteVexFirstState,
-        ThreeByteVexSecondState,
+        Vex2Of2State,
+        Vex2Of3State,
+        Vex3Of3State,
+        VexOpcodeState,
         OneByteOpcodeState,
         TwoByteOpcodeState,
         ThreeByte0F38OpcodeState,
@@ -199,9 +200,10 @@ class Decoder
     State doResetState();
     State doFromCacheState();
     State doPrefixState(uint8_t);
-    State doTwoByteVexState(uint8_t);
-    State doThreeByteVexFirstState(uint8_t);
-    State doThreeByteVexSecondState(uint8_t);
+    State doVex2Of2State(uint8_t);
+    State doVex2Of3State(uint8_t);
+    State doVex3Of3State(uint8_t);
+    State doVexOpcodeState(uint8_t);
     State doOneByteOpcodeState(uint8_t);
     State doTwoByteOpcodeState(uint8_t);
     State doThreeByte0F38OpcodeState(uint8_t);
index 58160756c5c767ebda9fe86d86188de1d085339a..28034b6ce82cc8f27a2c42edee930024a85fa406 100644 (file)
@@ -284,74 +284,4 @@ namespace X86ISA
 /*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
 /*  F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
     };
-
-    const Decoder::ByteTable Decoder::ImmediateTypeVex[10] =
-    {
-        // Table for opcode map 1
-        {
-            //LSB
-    // MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-    /*  0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  1 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  7 */ BY, BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  A */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  C */ 0 , 0 , BY, 0 , BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  D */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
-        },
-
-        // Table for opcode map 2
-        {
-            //LSB
-    // MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-    /*  0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  1 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  4 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  6 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  A */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  C */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  D */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
-        },
-
-        // Table for opcode map 3
-        {
-            //LSB
-    // MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-    /*  0 */ 0 , 0 , 0 , 0 , BY, BY, BY, 0 , BY, BY, BY, BY, BY, BY, BY, BY,
-    /*  1 */ 0 , 0 , 0 , 0 , BY, BY, BY, BY, BY, BY, 0 , 0 , 0 , BY, 0 , 0 ,
-    /*  2 */ BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  4 */ BY, BY, BY, 0 , BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  5 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  6 */ BY, BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  A */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  C */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  D */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY,
-    /*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-    /*  F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
-        },
-        {}, {}, {}, {}, {}, {}, {}
-    };
 }
index b5121f4e36a8453ce9e8a6b0928aa07b7dc02c43..8f2dec6e70423e55969760fb13320f27f409aea0 100644 (file)
@@ -88,11 +88,5 @@ def bitfield MODE mode;
 def bitfield MODE_MODE mode.mode;
 def bitfield MODE_SUBMODE mode.submode;
 
-def bitfield VEX_R vex.first.r;
-def bitfield VEX_X vex.first.x;
-def bitfield VEX_B vex.first.b;
-def bitfield VEX_MAP vex.first.map_select;
-def bitfield VEX_W vex.second.w;
-def bitfield VEX_VVVV vex.second.vvvv;
-def bitfield VEX_L vex.second.l;
-def bitfield VEX_PP vex.second.pp;
+def bitfield VEX_V vex.v;
+def bitfield VEX_L vex.l;
index 07006fe1adeacf1f2c2bc19ac8bf035d7a7d6679..eaa579817ab11650514e9a154e48bfd3cf38ddf9 100644 (file)
@@ -49,7 +49,6 @@ decode LEGACY_LOCK default Unknown::unknown()
         ##include "two_byte_opcodes.isa"
         ##include "three_byte_0f38_opcodes.isa"
         ##include "three_byte_0f3a_opcodes.isa"
-        ##include "vex_opcodes.isa"
     }
     //Lock prefix
     ##include "locked_opcodes.isa"
diff --git a/src/arch/x86/isa/decoder/vex_opcodes.isa b/src/arch/x86/isa/decoder/vex_opcodes.isa
deleted file mode 100644 (file)
index 0f412fe..0000000
+++ /dev/null
@@ -1,1431 +0,0 @@
-// Copyright (c) 2015 Mark D. Hill and David A. Wood
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met: redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer;
-// redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution;
-// neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: Nilay Vaish
-
-////////////////////////////////////////////////////////////////////
-//
-// Decode the opcodes with vex prefix.
-//
-format WarnUnimpl {
-    'X86ISA::Vex': decode VEX_MAP {
-        0x01: decode OPCODE_OP_TOP5 {
-            0x02: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vmovups();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_VVVV {
-                        0x15: vmovups();
-                        default: Inst::UD2();
-                    }
-                    0x2: decode VEX_L {
-                        0x0: decode MODRM_MOD {
-                            0x03: vmovhlps();
-                            default: decode VEX_VVVV {
-                                0x15: vmovlps();
-                                default: Inst::UD2();
-                            }
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x3: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vmovlps();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x4: vunpcklps();
-                    0x5: vunpckhps();
-                    0x6: decode VEX_L {
-                        0x0: decode MODRM_MOD {
-                            0x03: vmovlhps();
-                            0x0: vmovhps();
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_L {
-                        0x0: vmovhps();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vmovupd();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_VVVV {
-                        0x15: vmovupd();
-                        default: Inst::UD2();
-                    }
-                    0x2: decode VEX_L {
-                        0x0: vmovlpd();
-                        default: Inst::UD2();
-                    }
-                    0x3: decode VEX_L {
-                        0x0: vmovlpd();
-                        default: Inst::UD2();
-                    }
-                    0x4: vunpcklpd();
-                    0x5: vunpckhpd();
-                    0x6: decode VEX_L {
-                        0x0: vmovhpd();
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_L {
-                        0x0: vmovhpd();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode MODRM_MOD {
-                        0x03: vmovss();
-                        default: vmovss();
-                    }
-                    0x1: decode MODRM_MOD {
-                        0x03: vmovss();
-                        default: vmovss();
-                    }
-                    0x2: decode VEX_VVVV {
-                        0x15: vmovsldup();
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_VVVV {
-                        0x15: vmovshdup();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode MODRM_MOD {
-                        0x03: vmovsd();
-                        default: vmovsd();
-                    }
-                    0x1: decode MODRM_MOD {
-                        0x03: vmovsd();
-                        default: vmovsd();
-                    }
-                    0x2: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vmovddup();
-                            default: vmovddup();
-                        }
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0A: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vmovmskps();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_VVVV {
-                        0x015: vsqrtps();
-                        default: Inst::UD2();
-                    }
-                    0x2: decode VEX_VVVV {
-                        0x15: vrsqrtps();
-                        default: Inst::UD2();
-                    }
-                    0x3: decode VEX_VVVV {
-                        0x15: vrcpps();
-                        default: Inst::UD2();
-                    }
-                    0x4: vandps();
-                    0x5: vandnps();
-                    0x6: vorps();
-                    0x7: vxorps();
-                    default: Inst::UD2();
-                }
-
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vmovmskpd();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_VVVV {
-                        0x15: vsqrtpd();
-                        default: Inst::UD2();
-                    }
-                    0x4: vandpd();
-                    0x5: vandnpd();
-                    0x6: vorpd();
-                    0x7: vxorpd();
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x1: vsqrtss();
-                    0x2: vrsqrtss();
-                    0x3: vrcpss();
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x1: vsqrtsd();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0C: decode VEX_PP {
-                0x1: decode VEX_L {
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: vpunpcklbw();
-                        0x1: vpunpcklwd();
-                        0x2: vpunpckldq();
-                        0x3: vpacksswb();
-                        0x4: vpcmpgtb();
-                        0x5: vpcmpgtw();
-                        0x6: vpcmpgtd();
-                        0x7: vpackuswb();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                default: Inst::UD2();
-            }
-
-            0x0E: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x7: decode VEX_L {
-                        0x0: vzeroupper();
-                        0x1: vzeroall();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vpshufd();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_L {
-                        0x0: decode MODRM_REG {
-                            0x2: vpsrlw();
-                            0x4: vpsraw();
-                            0x6: vpsllw();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_L {
-                        0x0: decode MODRM_REG {
-                            0x2: vpsrld();
-                            0x4: vpsrad();
-                            0x6: vpslld();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_L {
-                        0x0: decode MODRM_REG {
-                            0x2: vpsrlq();
-                            0x3: vpsrldq();
-                            0x6: vpsllq();
-                            0x7: vpslldq();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_L {
-                        0x0: vpcmpeqb();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_L {
-                        0x0: vpcmpeqw();
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_L {
-                        0x0: vpcmpeqd();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vpshufhw();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vpshuflw();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                default: Inst::UD2();
-            }
-
-            0x18: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcmpccps();
-                    0x6: vshufps();
-                    default: Inst::UD2();
-                }
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcmpccpd();
-                    0x4: decode MODRM_MOD {
-                        0x03: vpinsrw();
-                        default: vpinsrw();
-                    }
-                    0x5: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vpextrw();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x6: vshufpd();
-                    default: Inst::UD2();
-                }
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcmpccss();
-                    default: Inst::UD2();
-                }
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcmpccsd();
-                    default: Inst::UD2();
-                }
-                default: Inst::UD2();
-            }
-
-            0x1A: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddsubpd();
-                    0x1: decode VEX_L {
-                        0x0: vpsrlw();
-                        default: Inst::UD2();
-                    }
-                    0x2: decode VEX_L {
-                        0x0: vpsrld();
-                        default: Inst::UD2();
-                    }
-                    0x3: decode VEX_L {
-                        0x0: vpsrlq();
-                        default: Inst::UD2();
-                    }
-                    0x4: decode VEX_L {
-                        0x0: vpaddq();
-                        default: Inst::UD2();
-                    }
-                    0x5: decode VEX_L {
-                        0x0: vpmullw();
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: vmovq();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_VVVV {
-                        0x15: vpmovmskb();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddsubps();
-                    default: Inst::UD2();
-                }
-                default: Inst::UD2();
-            }
-
-            0x1C: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_L {
-                        0x0: vpavgb();
-                        default: Inst::UD2();
-                    }
-                    0x1: vpsraw();
-                    0x2: vpsrad();
-                    0x3: decode VEX_L {
-                        0x0: vpavgw();
-                        default: Inst::UD2();
-                    }
-                    0x4: vpmulhuw();
-                    0x5: vpmulhw();
-                    0x6: vcvttpd2dq();
-                    0x7: decode VEX_VVVV {
-                        0x015: decode VEX_L {
-                            0x0: vmovntdq();
-                            default: vmovntdq();
-                        }
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x6: vcvtdq2pd();
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x6: vcvtpd2dq();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1E: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x1: vpsllw();
-                    0x2: vpslld();
-                    0x3: vpsllq();
-                    0x4: vpmuludq();
-                    0x5: vpmaddwd();
-                    0x6: vpsadbw();
-                    0x7: decode VEX_L {
-                        0x0: vmaskmovdqu();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_L {
-                        0x0: vlddqu();
-                        default: vlddqu();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x05: decode VEX_PP {
-                0x0: decode VEX_VVVV {
-                    0x15: decode OPCODE_OP_BOTTOM3 {
-                        0x0: vmovaps();
-                        0x1: vmovaps();
-                        0x3: vmovntps();
-                        0x6: vucomiss();
-                        0x7: vcomiss();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x1: decode VEX_VVVV {
-                    0x15: decode OPCODE_OP_BOTTOM3 {
-                        0x0: vmovapd();
-                        0x1: vmovapd();
-                        0x3: vmovntpd();
-                        0x6: vucomisd();
-                        0x7: vcomisd();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcvtsi2ss();
-                    0x4: vcvttss2si();
-                    0x5: vcvtss2si();
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vcvtsi2sd();
-                    0x4: vcvttsd2si();
-                    0x5: vcvtsd2si();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0B: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddps();
-                    0x1: vmulps();
-                    0x2: vcvtps2pd();
-                    0x3: vcvtdq2ps();
-                    0x4: vsubps();
-                    0x5: vminps();
-                    0x6: vdivps();
-                    0x7: vmaxps();
-                    default: Inst::UD2();
-                }
-
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddpd();
-                    0x1: vmulpd();
-                    0x2: vcvtpd2ps();
-                    0x3: vcvtps2dq();
-                    0x4: vsubpd();
-                    0x5: vminpd();
-                    0x6: vdivpd();
-                    0x7: vmaxpd();
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddss();
-                    0x1: vmulss();
-                    0x2: vcvtss2sd();
-                    0x3: vcvttps2dq();
-                    0x4: vsubss();
-                    0x5: vminss();
-                    0x6: vdivss();
-                    0x7: vmaxss();
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vaddsd();
-                    0x1: vmulsd();
-                    0x2: vcvtsd2ss();
-                    0x4: vsubsd();
-                    0x5: vminsd();
-                    0x6: vdivsd();
-                    0x7: vmaxsd();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0D: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpunpckhbw();
-                    0x1: vpunpckhbd();
-                    0x2: vpunpckhdq();
-                    0x3: decode VEX_L {
-                        0x0: vpackssdw();
-                        default: Inst::UD2();
-                    }
-                    0x4: vpunpcklqdq();
-                    0x5: vpunpckhqdq();
-                    0x6: decode VEX_L {
-                        0x0: vmovdvmovq();
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_VVVV {
-                        0x15: vmovdqa();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x7: vmovdqu();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0F: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x4: vhaddpd();
-                    0x5: vhsubpd();
-                    0x6: decode VEX_L {
-                        0x1: vmovdvmovq();
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_VVVV {
-                        0x15: vmovdqa();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                0x2: decode OPCODE_OP_BOTTOM3 {
-                    0x6: decode VEX_L {
-                        0x0: vmovq();
-                        default: Inst::UD2();
-                    }
-                    0x7: vmovdqu();
-                    default: Inst::UD2();
-                }
-
-                0x3: decode OPCODE_OP_BOTTOM3 {
-                    0x4: vhaddps();
-                    0x5: vhsubps();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x15: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x6: decode MODRM_REG {
-                        0x2: vldmxcsr();
-                        0x3: vstmxcsr();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-                default: Inst::UD2();
-            }
-
-            0x1B: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpsubusb();
-                    0x1: vpsubusw();
-                    0x2: vpminub();
-                    0x3: decode VEX_L {
-                        0x0: vpand();
-                        default: Inst::UD2();
-                    }
-                    0x4: vpaddusb();
-                    0x5: decode VEX_L {
-                        0x0: vpaddusw();
-                        default: Inst::UD2();
-                    }
-                    0x6: vpmaxub();
-                    0x7: decode VEX_L {
-                        0x0: vpandn();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1D: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpsubsb();
-                    0x1: vpsubsw();
-                    0x2: vpminsw();
-                    0x3: vpor();
-                    0x4: decode VEX_L {
-                        0x0: vpaddsb();
-                        default: Inst::UD2();
-                    }
-                    0x5: decode VEX_L {
-                        0x0: vpaddsw();
-                        default: Inst::UD2();
-                    }
-                    0x6: vpmaxsw();
-                    0x7: vpxor();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1F: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpsubb();
-                    0x1: vpsubw();
-                    0x2: vpsubd();
-                    0x3: vpsubq();
-                    0x4: vpaddb();
-                    0x5: decode VEX_L {
-                        0x0: vpaddw();
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_L {
-                        0x0: vpaddd();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            default: Inst::UD2();
-        }
-
-        0x02: decode OPCODE_OP_TOP5 {
-            0x00: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpshufb();
-                    0x1: vphaddw();
-                    0x2: vphaddd();
-                    0x3: vphaddsw();
-                    0x4: vpmaddubsw();
-                    0x5: vphsubw();
-                    0x6: vphsubd();
-                    0x7: vphsubsw();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x02: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x3: vcvtph2ps();
-                    0x7: vptest();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x04: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpmovsxbw();
-                    0x1: vpmovsxbd();
-                    0x2: vpmovsxbq();
-                    0x3: vpmovsxwd();
-                    0x4: vpmovsxwq();
-                    0x5: vpmovsxdq();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x06: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpmovzxbw();
-                    0x1: vpmovzxbd();
-                    0x2: vpmovzxbq();
-                    0x3: vpmovzxwd();
-                    0x4: vpmovzxwq();
-                    0x5: vpmovzxdq();
-                    0x7: vpcmpgtq();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x08: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpmulld();
-                    0x1: vphminposuw();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x12: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x6: decode VEX_W {
-                        0x0: vfmaddsub132ps();
-                        0x1: vfmaddsub132pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfmsubadd132ps();
-                        0x1: vfmaddsub132pd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x14: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x6: decode VEX_W {
-                        0x0: vfmaddsub213ps();
-                        0x1: vfmaddsub213pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfmsubadd213ps();
-                        0x1: vfmaddsub213pd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x16: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x6: decode VEX_W {
-                        0x0: vfmaddsub231ps();
-                        0x1: vfmaddsub231pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfmsubadd231ps();
-                        0x1: vfmaddsub231pd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1E: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x2: andn();
-                    0x3: decode MODRM_REG {
-                        0x1: blsr();
-                        0x2: blsmsk();
-                        0x3: blsi();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: bextr();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x01: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpsignb();
-                    0x1: vpsignw();
-                    0x2: vpsignd();
-                    0x3: vpmulhrsw();
-                    0x4: vpermilps();
-                    0x5: vpermilpd();
-                    0x6: vtestps();
-                    0x7: vtestpd();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x03: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vbroadcastss();
-                    0x1: decode VEX_L {
-                        0x1: vbroadcastsd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_L {
-                        0x1: vbroadcastF128();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_L {
-                        0x0: vpabsb();
-                        default: Inst::UD2();
-                    }
-                    0x5: decode VEX_L {
-                        0x0: vpabsw();
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_L {
-                        0x0: vpabsd();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x05: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpmuldq();
-                    0x1: vpcmpeqq();
-                    0x2: decode VEX_VVVV {
-                        0x15: vmovntdqa();
-                        default: Inst::UD2();
-                    }
-                    0x3: decode VEX_L {
-                        0x0: vpackusdw();
-                        default: Inst::UD2();
-                    }
-                    0x4: vmaskmovps();
-                    0x5: vmaskmovpd();
-                    0x6: vmaskmovps();
-                    0x7: vmaskmovpd();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x07: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpminsb();
-                    0x1: vpminsd();
-                    0x2: vpminuw();
-                    0x3: vpminud();
-                    0x4: vpmaxsb();
-                    0x5: vpmaxsd();
-                    0x6: vpmaxuw();
-                    0x7: vpmaxud();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0B: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x2: vbroadcasti128();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x13: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_W {
-                        0x0: vfmadd132ps();
-                        0x1: vfmadd132pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x1: decode VEX_W {
-                        0x0: vfmadd132ss();
-                        0x1: vfmadd132sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_W {
-                        0x0: vfmsub132ps();
-                        0x1: vfmsub132pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_W {
-                        0x0: vfmsub132ss();
-                        0x1: vfmsub132sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_W {
-                        0x0: vfnmadd132ps();
-                        0x1: vfnmadd132pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfnmadd132ss();
-                        0x1: vfnmadd132sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfnsub132ps();
-                        0x1: vfnsub132pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfnsub132ss();
-                        0x1: vfnsub132sd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x15: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_W {
-                        0x0: vfmadd213ps();
-                        0x1: vfmadd213pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x1: decode VEX_W {
-                        0x0: vfmadd213ss();
-                        0x1: vfmadd213sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_W {
-                        0x0: vfmsub213ps();
-                        0x1: vfmsub213pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_W {
-                        0x0: vfmsub213ss();
-                        0x1: vfmsub213sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_W {
-                        0x0: vfnmadd213ps();
-                        0x1: vfnmadd213pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfnmadd213ss();
-                        0x1: vfnmadd213sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfnsub213ps();
-                        0x1: vfnsub213pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfnsub213ss();
-                        0x1: vfnsub213sd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x17: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_W {
-                        0x0: vfmadd231ps();
-                        0x1: vfmadd231pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x1: decode VEX_W {
-                        0x0: vfmadd231ss();
-                        0x1: vfmadd231sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_W {
-                        0x0: vfmsub231ps();
-                        0x1: vfmsub231pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_W {
-                        0x0: vfmsub231ss();
-                        0x1: vfmsub231sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_W {
-                        0x0: vfnmadd231ps();
-                        0x1: vfnmadd231pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfnmadd231ss();
-                        0x1: vfnmadd231sd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfnsub231ps();
-                        0x1: vfnsub231pd();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfnsub231ss();
-                        0x1: vfnsub231sd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1B: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x3: vaesimc();
-                    0x4: vaesenc();
-                    0x5: vaesenclast();
-                    0x6: vaesdec();
-                    0x7: vaesdeclast();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            default: Inst::UD2();
-        }
-
-        0x03: decode OPCODE_OP_TOP5 {
-            0x00: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x4: vpermilps();
-                    0x5: vpermilpd();
-                    0x6: vperm2f128();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x02: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x4: decode MODRM_MOD {
-                        0x03: vpextrb();
-                        default: vpextrb();
-                    }
-
-                    0x5: decode VEX_VVVV {
-                        0x15: decode VEX_L {
-                            0x0: decode MODRM_MOD {
-                                0x03: vpextrw();
-                                default: vpextrw();
-                            }
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    0x6: decode VEX_W {
-                        0x0: vpextrd();
-                        0x1: vpextrq();
-                        default: Inst::UD2();
-                    }
-                    0x7: decode MODRM_MOD {
-                        0x03: vextractps();
-                        default: vextractps();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x04: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode MODRM_MOD {
-                        0x03: vpinsrb();
-                        default: vpinsrb();
-                    }
-                    0x1: decode MODRM_MOD {
-                        0x03: vinsertps();
-                        default: vinsertps();
-                    }
-                    0x2: decode VEX_W {
-                        0x0: vpinsrd();
-                        0x1: vpinsrq();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x08: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vdpps();
-                    0x1: vdppd();
-                    0x2: decode VEX_L {
-                        0x0: vmpsadbw();
-                        default: Inst::UD2();
-                    }
-                    0x4: vpclmulqdq();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0C: decode VEX_PP {
-                0x1: decode VEX_L {
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: decode VEX_VVVV {
-                            0x15: vpcmpestrm();
-                            default: Inst::UD2();
-                        }
-                        0x1: decode VEX_VVVV {
-                            0x15: vpcmpestri();
-                            default: Inst::UD2();
-                        }
-                        0x2: vpcmpistrm();
-                        0x3: vpcmpistri();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x01: decode VEX_PP {
-                0x0: decode OPCODE_OP_BOTTOM3 {
-                    0x7: palignr();
-                    default: Inst::UD2();
-                }
-
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_VVVV {
-                        0x15: vroundps();
-                        default: Inst::UD2();
-                    }
-                    0x1: decode VEX_VVVV {
-                        0x15: vroundpd();
-                        default: Inst::UD2();
-                    }
-                    0x2: vroundss();
-                    0x3: vroundsd();
-                    0x4: vblendps();
-                    0x5: vblendpd();
-                    0x6: decode VEX_L {
-                        0x0: vpblendw();
-                        default: Inst::UD2();
-                    }
-                    0x7: decode VEX_L {
-                        0x0: vpalignr();
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x03: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vinsertf128();
-                    0x1: vextractf128();
-                    0x5: vcvtps2ph();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x09: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: vpermil2ps();
-                    0x1: vpermil2pd();
-                    0x2: vblendvps();
-                    0x3: vblendvpd();
-                    0x4: decode VEX_L {
-                        0x0: decode VEX_W {
-                            0x0: vpblendvb();
-                            default: Inst::UD2();
-                        }
-                        default: Inst::UD2();
-                    }
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0B: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x4: decode VEX_W {
-                        0x0: vfmaddsubps();
-                        0x1: vfmaddsubps();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfmaddsubpd();
-                        0x1: vfmaddsubpd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfmsubaddps();
-                        0x1: vfmsubaddps();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfmsubaddpd();
-                        0x1: vfmsubaddpd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0D: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_W {
-                        0x0: vfmaddps();
-                        0x1: vfmaddps();
-                        default: Inst::UD2();
-                    }
-
-                    0x1: decode VEX_W {
-                        0x0: vfmaddpd();
-                        0x1: vfmaddpd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_W {
-                        0x0: vfmaddss();
-                        0x1: vfmaddss();
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_W {
-                        0x0: vfmaddsd();
-                        0x1: vfmaddsd();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_W {
-                        0x0: vfmsubps();
-                        0x1: vfmsubps();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfmsubpd();
-                        0x1: vfmsubpd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfmsubss();
-                        0x1: vfmsubss();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfmsubsd();
-                        0x1: vfmsubsd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x0F: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode VEX_W {
-                        0x0: vfnmaddps();
-                        0x1: vfnmaddps();
-                        default: Inst::UD2();
-                    }
-
-                    0x1: decode VEX_W {
-                        0x0: vfnmaddpd();
-                        0x1: vfnmaddpd();
-                        default: Inst::UD2();
-                    }
-
-                    0x2: decode VEX_W {
-                        0x0: vfnmaddss();
-                        0x1: vfnmaddss();
-                        default: Inst::UD2();
-                    }
-
-                    0x3: decode VEX_W {
-                        0x0: vfnmaddsd();
-                        0x1: vfnmaddsd();
-                        default: Inst::UD2();
-                    }
-
-                    0x4: decode VEX_W {
-                        0x0: vfnmsubps();
-                        0x1: vfnmsubps();
-                        default: Inst::UD2();
-                    }
-
-                    0x5: decode VEX_W {
-                        0x0: vfnmsubpd();
-                        0x1: vfnmsubpd();
-                        default: Inst::UD2();
-                    }
-
-                    0x6: decode VEX_W {
-                        0x0: vfnmsubss();
-                        0x1: vfnmsubss();
-                        default: Inst::UD2();
-                    }
-
-                    0x7: decode VEX_W {
-                        0x0: vfnmsubsd();
-                        0x1: vfnmsubsd();
-                        default: Inst::UD2();
-                    }
-
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            0x1B: decode VEX_PP {
-                0x1: decode OPCODE_OP_BOTTOM3 {
-                    0x7: vaeskeygenassist();
-                    default: Inst::UD2();
-                }
-
-                default: Inst::UD2();
-            }
-
-            default: Inst::UD2();
-        }
-
-        default: Inst::UD2();
-    }
-}
index 8d47b7efb12238c8e0a740768a8d49e4a776baba..6e1b1cf2fee458d6f90255883b6d60a901e410a3 100644 (file)
@@ -106,47 +106,45 @@ namespace X86ISA
         Bitfield<0> b;
     EndBitUnion(Rex)
 
-    BitUnion(uint32_t, ThreeByteVex)
-        Bitfield<7,0> zero;
-        SubBitUnion(first, 15, 8)
-            // Inverted one-bit extension of ModRM reg field
-            Bitfield<15> r;
-            // Inverted one-bit extension of SIB index field
-            Bitfield<14> x;
-            // Inverted one-bit extension, r/m field or SIB base field
-            Bitfield<13> b;
-            // Opcode map select
-            Bitfield<12, 8> map_select;
-        EndSubBitUnion(first)
-        SubBitUnion(second, 23, 16)
-            // Default operand size override for a general purpose register to
-            // 64-bit size in 64-bit mode; operand configuration specifier for
-            // certain YMM/XMM-based operations.
-            Bitfield<23> w;
-            // Source or destination register selector, in ones' complement
-            // format
-            Bitfield<22, 19>  vvvv;
-            // Vector length specifier
-            Bitfield<18> l;
-            // Implied 66, F2, or F3 opcode extension
-            Bitfield<17, 16> pp;
-        EndSubBitUnion(second)
-    EndBitUnion(ThreeByteVex)
-
-    BitUnion16(TwoByteVex)
-        Bitfield<7,0> zero;
-        SubBitUnion(first, 15, 8)
-            // Inverted one-bit extension of ModRM reg field
-            Bitfield<15> r;
-            // Source or destination register selector, in ones' complement
-            // format
-            Bitfield<14, 11>  vvvv;
-            // Vector length specifier
-            Bitfield<10> l;
-            // Implied 66, F2, or F3 opcode extension
-            Bitfield<9, 8> pp;
-        EndSubBitUnion(first)
-    EndBitUnion(TwoByteVex)
+    BitUnion8(Vex2Of3)
+        // Inverted bits from the REX prefix.
+        Bitfield<7> r;
+        Bitfield<6> x;
+        Bitfield<5> b;
+        // Selector for what would be two or three byte opcode types.
+        Bitfield<4, 0> m;
+    EndBitUnion(Vex2Of3)
+
+    BitUnion8(Vex3Of3)
+        // Bit from the REX prefix.
+        Bitfield<7> w;
+        // Inverted extra register index.
+        Bitfield<6, 3>  v;
+        // Vector length specifier.
+        Bitfield<2> l;
+        // Implied 66, F2, or F3 opcode prefix.
+        Bitfield<1, 0> p;
+    EndBitUnion(Vex3Of3)
+
+    BitUnion8(Vex2Of2)
+        // Inverted bit from the REX prefix.
+        Bitfield<7> r;
+        // Inverted extra register index.
+        Bitfield<6, 3>  v;
+        // Vector length specifier
+        Bitfield<2> l;
+        // Implied 66, F2, or F3 opcode prefix.
+        Bitfield<1, 0> p;
+    EndBitUnion(Vex2Of2)
+
+    BitUnion8(VexInfo)
+        // Extra register index.
+        Bitfield<6, 3> v;
+        // Vector length specifier.
+        Bitfield<2> l;
+        // Whether the VEX prefix was used.
+        Bitfield<0> present;
+    EndBitUnion(VexInfo)
 
     enum OpcodeType {
         BadOpcode,
@@ -154,7 +152,6 @@ namespace X86ISA
         TwoByteOpcode,
         ThreeByte0F38Opcode,
         ThreeByte0F3AOpcode,
-        Vex,
     };
 
     static inline const char *
@@ -171,8 +168,6 @@ namespace X86ISA
             return "three byte 0f38";
           case ThreeByte0F3AOpcode:
             return "three byte 0f3a";
-          case Vex:
-            return "vex";
           default:
             return "unrecognized!";
         }
@@ -207,9 +202,7 @@ namespace X86ISA
         //Prefixes
         LegacyPrefixVector legacy;
         Rex rex;
-        // We use the following field for encoding both two byte and three byte
-        // escape sequences
-        ThreeByteVex vex;
+        VexInfo vex;
 
         //This holds all of the bytes of the opcode
         struct
@@ -248,7 +241,7 @@ namespace X86ISA
                      "immediate = %#x,\n\tdisplacement = %#x\n\t"
                      "dispSize = %d}\n",
                      (uint8_t)emi.legacy, (uint8_t)emi.rex,
-                     (uint32_t)emi.vex,
+                     (uint8_t)emi.vex,
                      opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op,
                      (uint8_t)emi.modRM, (uint8_t)emi.sib,
                      emi.immediate, emi.displacement, emi.dispSize);
@@ -262,6 +255,8 @@ namespace X86ISA
             return false;
         if (emi1.rex != emi2.rex)
             return false;
+        if (emi1.vex != emi2.vex)
+            return false;
         if (emi1.opcode.type != emi2.opcode.type)
             return false;
         if (emi1.opcode.op != emi2.opcode.op)
@@ -357,8 +352,9 @@ namespace std {
     template<>
     struct hash<X86ISA::ExtMachInst> {
         size_t operator()(const X86ISA::ExtMachInst &emi) const {
-            return (((uint64_t)emi.legacy << 40) |
-                    ((uint64_t)emi.rex  << 32) |
+            return (((uint64_t)emi.legacy << 48) |
+                    ((uint64_t)emi.rex << 40) |
+                    ((uint64_t)emi.vex << 32) |
                     ((uint64_t)emi.modRM << 24) |
                     ((uint64_t)emi.sib << 16) |
                     ((uint64_t)emi.opcode.type << 8) |