x86: Rework opcode parsing to support 3 byte opcodes properly.
authorGabe Black <gabeblack@google.com>
Thu, 4 Dec 2014 23:53:54 +0000 (15:53 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 4 Dec 2014 23:53:54 +0000 (15:53 -0800)
Instead of counting the number of opcode bytes in an instruction and recording
each byte before the actual opcode, we can represent the path we took to get to
the actual opcode byte by using a type code. That has a couple of advantages.
First, we can disambiguate the properties of opcodes of the same length which
have different properties. Second, it reduces the amount of data stored in an
ExtMachInst, making them slightly easier/faster to create and process. This
also adds some flexibility as far as how different types of opcodes are
handled, which might come in handy if we decide to support VEX or XOP
instructions.

This change also adds tables to support properly decoding 3 byte opcodes.
Before we would fall off the end of some arrays, on top of the ambiguity
described above.

This change doesn't measureably affect performance on the twolf benchmark.

--HG--
rename : src/arch/x86/isa/decoder/three_byte_opcodes.isa => src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa
rename : src/arch/x86/isa/decoder/three_byte_opcodes.isa => src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa

14 files changed:
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/locked_opcodes.isa
src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa [new file with mode: 0644]
src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa [new file with mode: 0644]
src/arch/x86/isa/decoder/three_byte_opcodes.isa [deleted file]
src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/arch/x86/isa_traits.hh
src/arch/x86/types.cc
src/arch/x86/types.hh

index f42fb28bf48ec581ed410ee7daaabb035d759f79..59f2e0f4f38bdecbf49c99c5a5ca761b26978800 100644 (file)
@@ -48,9 +48,8 @@ Decoder::doResetState()
 
     emi.rex = 0;
     emi.legacy = 0;
-    emi.opcode.num = 0;
+    emi.opcode.type = BadOpcode;
     emi.opcode.op = 0;
-    emi.opcode.prefixA = emi.opcode.prefixB = 0;
 
     immediateCollected = 0;
     emi.immediate = 0;
@@ -94,8 +93,17 @@ Decoder::process()
           case PrefixState:
             state = doPrefixState(nextByte);
             break;
-          case OpcodeState:
-            state = doOpcodeState(nextByte);
+          case OneByteOpcodeState:
+            state = doOneByteOpcodeState(nextByte);
+            break;
+          case TwoByteOpcodeState:
+            state = doTwoByteOpcodeState(nextByte);
+            break;
+          case ThreeByte0F38OpcodeState:
+            state = doThreeByte0F38OpcodeState(nextByte);
+            break;
+          case ThreeByte0F3AOpcodeState:
+            state = doThreeByte0F3AOpcodeState(nextByte);
             break;
           case ModRMState:
             state = doModRMState(nextByte);
@@ -199,7 +207,7 @@ Decoder::doPrefixState(uint8_t nextByte)
         emi.rex = nextByte;
         break;
       case 0:
-        nextState = OpcodeState;
+        nextState = OneByteOpcodeState;
         break;
       default:
         panic("Unrecognized prefix %#x\n", nextByte);
@@ -207,79 +215,132 @@ Decoder::doPrefixState(uint8_t nextByte)
     return nextState;
 }
 
-//Load all the opcodes (currently up to 2) and then figure out
-//what immediate and/or ModRM is needed.
+// Load the first opcode byte. Determine if there are more opcode bytes, and
+// if not, what immediate and/or ModRM is needed.
 Decoder::State
-Decoder::doOpcodeState(uint8_t nextByte)
+Decoder::doOneByteOpcodeState(uint8_t nextByte)
 {
     State nextState = ErrorState;
-    emi.opcode.num++;
-    //We can't handle 3+ byte opcodes right now
-    assert(emi.opcode.num < 4);
     consumeByte();
-    if(emi.opcode.num == 1 && nextByte == 0x0f)
-    {
-        nextState = OpcodeState;
-        DPRINTF(Decoder, "Found two byte opcode.\n");
-        emi.opcode.prefixA = nextByte;
-    }
-    else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A))
-    {
-        nextState = OpcodeState;
-        DPRINTF(Decoder, "Found three byte opcode.\n");
-        emi.opcode.prefixB = nextByte;
+    if (nextByte == 0x0f) {
+        nextState = TwoByteOpcodeState;
+        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
+    } else {
+        DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte);
+        emi.opcode.type = OneByteOpcode;
+        emi.opcode.op = nextByte;
+
+        nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
+                                  nextByte >= 0xA0 && nextByte <= 0xA3);
     }
-    else
-    {
-        DPRINTF(Decoder, "Found opcode %#x.\n", nextByte);
+    return nextState;
+}
+
+// Load the second opcode byte. Determine if there are more opcode bytes, and
+// if not, what immediate and/or ModRM is needed.
+Decoder::State
+Decoder::doTwoByteOpcodeState(uint8_t nextByte)
+{
+    State nextState = ErrorState;
+    consumeByte();
+    if (nextByte == 0x38) {
+        nextState = ThreeByte0F38OpcodeState;
+        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
+    } else if (nextByte == 0x3a) {
+        nextState = ThreeByte0F3AOpcodeState;
+        DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
+    } else {
+        DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte);
+        emi.opcode.type = TwoByteOpcode;
         emi.opcode.op = nextByte;
 
-        //Figure out the effective operand size. This can be overriden to
-        //a fixed value at the decoder level.
-        int logOpSize;
-        if (emi.rex.w)
-            logOpSize = 3; // 64 bit operand size
-        else if (emi.legacy.op)
-            logOpSize = altOp;
-        else
-            logOpSize = defOp;
+        nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
+    }
+    return nextState;
+}
 
-        //Set the actual op size
-        emi.opSize = 1 << logOpSize;
+// Load the third opcode byte and determine what immediate and/or ModRM is
+// needed.
+Decoder::State
+Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte)
+{
+    consumeByte();
 
-        //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;
+    DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte);
+    emi.opcode.type = ThreeByte0F38Opcode;
+    emi.opcode.op = nextByte;
 
-        //Set the actual address size
-        emi.addrSize = 1 << logAddrSize;
+    return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38);
+}
 
-        //Figure out the effective stack width. This can be overriden to
-        //a fixed value at the decoder level.
-        emi.stackSize = 1 << stack;
+// Load the third opcode byte and determine what immediate and/or ModRM is
+// needed.
+Decoder::State
+Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte)
+{
+    consumeByte();
 
-        //Figure out how big of an immediate we'll retreive based
-        //on the opcode.
-        int immType = ImmediateType[emi.opcode.num - 1][nextByte];
-        if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3)
-            immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
-        else
-            immediateSize = SizeTypeToSize[logOpSize - 1][immType];
+    DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte);
+    emi.opcode.type = ThreeByte0F3AOpcode;
+    emi.opcode.op = nextByte;
+
+    return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A);
+}
+
+// Generic opcode processing which determines the immediate size, and whether
+// or not there's a modrm byte.
+Decoder::State
+Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
+                       bool addrSizedImm)
+{
+    State nextState = ErrorState;
+    const uint8_t opcode = emi.opcode.op;
+
+    //Figure out the effective operand size. This can be overriden to
+    //a fixed value at the decoder level.
+    int logOpSize;
+    if (emi.rex.w)
+        logOpSize = 3; // 64 bit operand size
+    else if (emi.legacy.op)
+        logOpSize = altOp;
+    else
+        logOpSize = defOp;
 
-        //Determine what to expect next
-        if (UsesModRM[emi.opcode.num - 1][nextByte]) {
-            nextState = ModRMState;
+    //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.
+    int immType = immTable[opcode];
+    if (addrSizedImm)
+        immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
+    else
+        immediateSize = SizeTypeToSize[logOpSize - 1][immType];
+
+    //Determine what to expect next
+    if (modrmTable[opcode]) {
+        nextState = ModRMState;
+    } else {
+        if(immediateSize) {
+            nextState = ImmediateState;
         } else {
-            if(immediateSize) {
-                nextState = ImmediateState;
-            } else {
-                instDone = true;
-                nextState = ResetState;
-            }
+            instDone = true;
+            nextState = ResetState;
         }
     }
     return nextState;
@@ -315,7 +376,7 @@ Decoder::doModRMState(uint8_t nextByte)
 
     // The "test" instruction in group 3 needs an immediate, even though
     // the other instructions with the same actual opcode don't.
-    if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) {
+    if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
        if (emi.opcode.op == 0xF6)
            immediateSize = 1;
        else if (emi.opcode.op == 0xF7)
index ca7ef96fe01403e419154fce71c573f88e3693e2..a37fccfb1308d2122314ddd734b7fbbdcedc8d66 100644 (file)
@@ -51,10 +51,19 @@ class Decoder
 {
   private:
     //These are defined and documented in decoder_tables.cc
-    static const uint8_t Prefixes[256];
-    static const uint8_t UsesModRM[2][256];
-    static const uint8_t ImmediateType[2][256];
     static const uint8_t SizeTypeToSize[3][10];
+    typedef const uint8_t ByteTable[256];
+    static ByteTable Prefixes;
+
+    static ByteTable UsesModRMOneByte;
+    static ByteTable UsesModRMTwoByte;
+    static ByteTable UsesModRMThreeByte0F38;
+    static ByteTable UsesModRMThreeByte0F3A;
+
+    static ByteTable ImmediateTypeOneByte;
+    static ByteTable ImmediateTypeTwoByte;
+    static ByteTable ImmediateTypeThreeByte0F38;
+    static ByteTable ImmediateTypeThreeByte0F3A;
 
   protected:
     struct InstBytes
@@ -166,7 +175,10 @@ class Decoder
         ResetState,
         FromCacheState,
         PrefixState,
-        OpcodeState,
+        OneByteOpcodeState,
+        TwoByteOpcodeState,
+        ThreeByte0F38OpcodeState,
+        ThreeByte0F3AOpcodeState,
         ModRMState,
         SIBState,
         DisplacementState,
@@ -181,12 +193,19 @@ class Decoder
     State doResetState();
     State doFromCacheState();
     State doPrefixState(uint8_t);
-    State doOpcodeState(uint8_t);
+    State doOneByteOpcodeState(uint8_t);
+    State doTwoByteOpcodeState(uint8_t);
+    State doThreeByte0F38OpcodeState(uint8_t);
+    State doThreeByte0F3AOpcodeState(uint8_t);
     State doModRMState(uint8_t);
     State doSIBState(uint8_t);
     State doDisplacementState();
     State doImmediateState();
 
+    //Process the actual opcode found earlier, using the supplied tables.
+    State processOpcode(ByteTable &immTable, ByteTable &modrmTable,
+                        bool addrSizedImm = false);
+
   protected:
     /// Caching for decoded instruction objects.
 
index a132cb8646feafebd4384afbd148c3ffdaadb23a..d5fcceef899b5ff5e3d93b39069d6cd252c4916b 100644 (file)
@@ -58,7 +58,7 @@ namespace X86ISA
 
     //This table identifies whether a byte is a prefix, and if it is,
     //which prefix it is.
-    const uint8_t Decoder::Prefixes[256] =
+    const Decoder::ByteTable Decoder::Prefixes =
     {    //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,
@@ -79,48 +79,89 @@ namespace X86ISA
 /*   F*/ LO, 0 , RN, RE, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
     };
 
-    //This table identifies whether a particular opcode uses the ModRM byte
-    const uint8_t Decoder::UsesModRM[2][256] =
-    {//For one byte instructions
-        {    //LSB
-//     MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-/*      0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
-/*      1 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
-/*      2 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
-/*      3 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 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 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0,
-/*      7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      8 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      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 */ 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      D */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      F */ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1
-        },
-    //For two byte instructions
-        {    //LSB
-//     MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-/*      0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1,
-/*      1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      5 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      6 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      7 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1,
-/*      8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      9 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      A */ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1,
-/*      B */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      C */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
-/*      D */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      E */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
-/*      F */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0
-        }
+    // These tables identify whether a particular opcode uses the ModRM byte.
+    const Decoder::ByteTable Decoder::UsesModRMOneByte =
+    {    //LSB
+// MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/*  0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/*  1 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/*  2 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/*  3 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 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 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0,
+/*  7 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  8 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  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 */ 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  D */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  F */ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1
+    };
+
+    const Decoder::ByteTable Decoder::UsesModRMTwoByte =
+    {    //LSB
+// MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/*  0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1,
+/*  1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  5 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  6 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  7 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1,
+/*  8 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  9 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  A */ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1,
+/*  B */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  C */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  D */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  E */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  F */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0
+    };
+
+    const Decoder::ByteTable Decoder::UsesModRMThreeByte0F38 =
+    {    //LSB
+// MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/*  0 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/*  1 */ 1 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0,
+/*  2 */ 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0,
+/*  3 */ 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  4 */ 1 , 1 , 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 , 1 , 1 , 1 , 1 , 1,
+/*  E */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  F */ 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+    };
+
+    const Decoder::ByteTable Decoder::UsesModRMThreeByte0F3A =
+    {    //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 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1,
+/*  1 */ 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+/*  2 */ 1 , 1 , 1 , 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 */ 1 , 1 , 1 , 0 , 1 , 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 */ 1 , 1 , 1 , 1 , 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 , 1,
+/*  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
     };
 
     enum SizeType {
@@ -140,7 +181,7 @@ namespace X86ISA
         VW = VWordImm,
         ZWordImm,
         ZW = ZWordImm,
-        //The enter instruction takes -2- immediates for a total of 3 bytes
+        // The enter instruction takes -2- immediates for a total of 3 bytes
         Enter,
         EN = Enter,
         Pointer,
@@ -155,50 +196,90 @@ namespace X86ISA
         {0,    1,   2,   4,    8,    16,   8,    4,    3,    0      }  //64 bit
     };
 
-    //This table determines the immediate type. The first index is the
-    //number of bytes in the instruction, and the second is the meaningful
-    //byte of the opcode. I didn't use the NI constant here for the sake
-    //of clarity.
-    const uint8_t Decoder::ImmediateType[2][256] =
-    {//For one byte instructions
-        {    //LSB
-//     MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-/*      0 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
-/*      1 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
-/*      2 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
-/*      3 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 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 , ZW, ZW, BY, BY, 0 , 0 , 0 , 0 ,
-/*      7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY,
-/*      8 */ BY, ZW, BY, BY, 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 */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
-/*      B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW,
-/*      C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 ,
-/*      D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-/*      E */ BY, BY, BY, BY, BY, BY, BY, BY, ZW, ZW, PO, BY, 0 , 0 , 0 , 0 ,
-/*      F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
-        },
-    //For two byte instructions
-        {    //LSB
-//     MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
-/*      0 */ 0 , 0 , 0 , 0 , WO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY ,
-/*      0 */ 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 */ ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW,
-/*      9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-/*      A */ 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 ,
-/*      B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, 0 , BY, 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
-        }
+    // These tables determines the immediate type. I didn't use the NI
+    // constant here for the sake
+    // of clarity.
+    const Decoder::ByteTable Decoder::ImmediateTypeOneByte =
+    {    //LSB
+// MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/*  0 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/*  1 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/*  2 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 ,
+/*  3 */ 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , BY, ZW, 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 , ZW, ZW, BY, BY, 0 , 0 , 0 , 0 ,
+/*  7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY,
+/*  8 */ BY, ZW, BY, BY, 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 */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
+/*  B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW,
+/*  C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 ,
+/*  D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/*  E */ BY, BY, BY, BY, BY, BY, BY, BY, ZW, ZW, PO, BY, 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::ImmediateTypeTwoByte =
+    {    //LSB
+// MSB   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
+/*  0 */ 0 , 0 , 0 , 0 , WO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY,
+/*  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 */ ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW, ZW,
+/*  9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+/*  A */ 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY, 0 , 0 , 0 ,
+/*  B */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ZW, 0 , BY, 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
+    };
+
+    const Decoder::ByteTable Decoder::ImmediateTypeThreeByte0F38 =
+    {    //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
+    };
+
+    const Decoder::ByteTable Decoder::ImmediateTypeThreeByte0F3A =
+    {    //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 , BY, BY, BY, BY, BY, BY, BY, BY,
+/*  1 */ 0 , 0 , 0 , 0 , BY, BY, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 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 a7753ba3d8b665ddaad8ca334c58405a4e046763..e2751a8efcb14a92d8a8222e9d80bc58e3ec0bc8 100644 (file)
@@ -59,9 +59,7 @@ def bitfield LEGACY_ADDR legacy.addr;
 def bitfield LEGACY_SEG legacy.seg;
 
 // Pieces of the opcode
-def bitfield OPCODE_NUM opcode.num;
-def bitfield OPCODE_PREFIXA opcode.prefixA;
-def bitfield OPCODE_PREFIXB opcode.prefixB;
+def bitfield OPCODE_TYPE opcode.type;
 def bitfield OPCODE_OP opcode.op;
 //The top 5 bits of the opcode tend to split the instructions into groups
 def bitfield OPCODE_OP_TOP5 opcode.op.top5;
index 9b2ce0ba0a4b9a68a255420b9f7c2846bc0e0794..eaa579817ab11650514e9a154e48bfd3cf38ddf9 100644 (file)
 decode LEGACY_LOCK default Unknown::unknown()
 {
     //No lock prefix
-    0x0: decode OPCODE_NUM default Unknown::unknown()
+    0x0: decode OPCODE_TYPE default Unknown::unknown()
     {
-        0x0: M5InternalError::error(
-            {{"Saw an ExtMachInst with zero opcode bytes!"}});
-        //1 byte opcodes
         ##include "one_byte_opcodes.isa"
-        //2 byte opcodes
         ##include "two_byte_opcodes.isa"
-        //3 byte opcodes
-        ##include "three_byte_opcodes.isa"
+        ##include "three_byte_0f38_opcodes.isa"
+        ##include "three_byte_0f3a_opcodes.isa"
     }
     //Lock prefix
     ##include "locked_opcodes.isa"
index e776d1320b7c3fe838cad8bac2f4a94c74f8137e..d2bfac57eea1f50bddada6a650db111246eae011 100644 (file)
@@ -38,8 +38,8 @@
 0x1: decode MODRM_MOD {
     format Inst {
         0x3: UD2();
-        default: decode OPCODE_NUM {
-            0x1: decode OPCODE_OP_TOP5 {
+        default: decode OPCODE_TYPE {
+            'X86ISA::OneByteOpcode': decode OPCODE_OP_TOP5 {
                 0x00: decode OPCODE_OP_BOTTOM3 {
                     default: MultiInst::ADD_LOCKED(OPCODE_OP_BOTTOM3,
                                             [Mb,Gb], [Mv,Gv]);
                     }
                 }
             }
-            0x2: decode OPCODE_PREFIXA {
-                0x0F: decode OPCODE_OP_TOP5 {
-                    0x04: decode OPCODE_OP_BOTTOM3 {
-                        0x0: WarnUnimpl::mov_Rd_CR8D();
-                        0x2: WarnUnimpl::mov_CR8D_Rd();
-                    }
-                    0x15: decode OPCODE_OP_BOTTOM3 {
-                        0x3: BTS_LOCKED(Mv,Gv);
-                    }
-                    0x16: decode OPCODE_OP_BOTTOM3 {
-                        0x0: CMPXCHG_LOCKED(Mb,Gb);
-                        0x1: CMPXCHG_LOCKED(Mv,Gv);
-                        0x3: BTR_LOCKED(Mv,Gv);
-                    }
-                    0x17: decode OPCODE_OP_BOTTOM3 {
-                        0x2: decode MODRM_REG {
-                            0x5: BTS_LOCKED(Mv,Ib);
-                            0x6: BTR_LOCKED(Mv,Ib);
-                            0x7: BTC_LOCKED(Mv,Ib);
-                        }
-                        0x3: BTC_LOCKED(Mv,Gv);
+            'X86ISA::TwoByteOpcode': decode OPCODE_OP_TOP5 {
+                0x04: decode OPCODE_OP_BOTTOM3 {
+                    0x0: WarnUnimpl::mov_Rd_CR8D();
+                    0x2: WarnUnimpl::mov_CR8D_Rd();
+                }
+                0x15: decode OPCODE_OP_BOTTOM3 {
+                    0x3: BTS_LOCKED(Mv,Gv);
+                }
+                0x16: decode OPCODE_OP_BOTTOM3 {
+                    0x0: CMPXCHG_LOCKED(Mb,Gb);
+                    0x1: CMPXCHG_LOCKED(Mv,Gv);
+                    0x3: BTR_LOCKED(Mv,Gv);
+                }
+                0x17: decode OPCODE_OP_BOTTOM3 {
+                    0x2: decode MODRM_REG {
+                        0x5: BTS_LOCKED(Mv,Ib);
+                        0x6: BTR_LOCKED(Mv,Ib);
+                        0x7: BTC_LOCKED(Mv,Ib);
                     }
-                    0x18: decode OPCODE_OP_BOTTOM3 {
-                        0x0: XADD_LOCKED(Mb,Gb);
-                        0x1: XADD_LOCKED(Mv,Gv);
-                        //0x7: group9();
-                        0x7: decode MODRM_REG {
-                            //Also CMPXCHG16B
-                            0x1: CMPXCHG8B_LOCKED(Mdp);
-                        }
+                    0x3: BTC_LOCKED(Mv,Gv);
+                }
+                0x18: decode OPCODE_OP_BOTTOM3 {
+                    0x0: XADD_LOCKED(Mb,Gb);
+                    0x1: XADD_LOCKED(Mv,Gv);
+                    //0x7: group9();
+                    0x7: decode MODRM_REG {
+                        //Also CMPXCHG16B
+                        0x1: CMPXCHG8B_LOCKED(Mdp);
                     }
                 }
-                default: M5InternalError::error(
-                    {{"Unexpected first opcode byte in two byte opcode!"}});
             }
         }
     }
index 92e5cd0a88390168da146bfe32cca344959c0ac6..859d1f1b437cc593df2e0451f94b1e04e74dd1f8 100644 (file)
@@ -40,7 +40,7 @@
 // Decode the one byte opcodes
 //
 
-0x1: decode OPCODE_OP_TOP5 {
+'X86ISA::OneByteOpcode': decode OPCODE_OP_TOP5 {
     format Inst {
         0x00: decode OPCODE_OP_BOTTOM3 {
             0x6: decode MODE_SUBMODE {
diff --git a/src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa b/src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa
new file mode 100644 (file)
index 0000000..d04f15e
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright (c) 2008 The Regents of The University of Michigan
+// 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: Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the three byte opcodes with the 0f38 prefix.
+//
+'X86ISA::ThreeByte0F38Opcode': decode LEGACY_OP {
+    format WarnUnimpl {
+        1: decode OPCODE_OP {
+            0x00: pshufb_Vdq_Wdq();
+            0x01: phaddw_Vdq_Wdq();
+            0x02: phaddd_Vdq_Wdq();
+            0x03: phaddsw_Vdq_Wdq();
+            0x04: pmaddubsw_Vdq_Wdq();
+            0x05: phsubw_Vdq_Wdq();
+            0x06: phsubd_Vdq_Wdq();
+            0x07: phsubsw_Vdq_Wdq();
+            0x08: psignb_Vdq_Wdq();
+            0x09: psignw_Vdq_Wdq();
+            0x0A: psignd_Vdq_Wdq();
+            0x0B: pmulhrsw_Vdq_Wdq();
+            0x10: pblendvb_Vdq_Wdq();
+            0x14: blendvps_Vdq_Wdq();
+            0x15: blendvpd_Vdq_Wdq();
+            0x17: ptest_Vdq_Wdq();
+            0x1C: pabsb_Vdq_Wdq();
+            0x1D: pabsw_Vdq_Wdq();
+            0x1E: pabsd_Vdq_Wdq();
+            0x20: pmovsxbw_Vdq_Udq_or_Mq();
+            0x21: pmovsxbd_Vdq_Udq_or_Md();
+            0x22: pmovsxbq_Vdq_Udq_or_Mw();
+            0x23: pmovsxwd_Vdq_Udq_or_Mq();
+            0x24: pmovsxwq_Vdq_Udq_or_Md();
+            0x25: pmovsxdq_Vdq_Udq_or_Mq();
+            0x28: pmuldq_Vdq_Wdq();
+            0x29: pcmpeqq_Vdq_Wdq();
+            0x2A: movntdqa_Vdq_Mdq();
+            0x2B: packusdw_Vdq_Wdq();
+            0x30: pmovzxbw_Vdq_Udq_or_Mq();
+            0x31: pmovzxbd_Vdq_Udq_or_Md();
+            0x32: pmovzxbq_Vdq_Udq_or_Mw();
+            0x33: pmovzxwd_Vdq_Udq_or_Mq();
+            0x34: pmovzxwq_Vdq_Udq_or_Md();
+            0x35: pmovzxdq_Vdq_Udq_or_Mq();
+            0x37: pcmpgtq_Vdq_Wdq();
+            0x38: pminsb_Vdq_Wdq();
+            0x39: pminsd_Vdq_Wdq();
+            0x3A: pminuw_Vdq_Wdq();
+            0x3B: pminud_Vdq_Wdq();
+            0x3C: pmaxsb_Vdq_Wdq();
+            0x3D: pmaxsd_Vdq_Wdq();
+            0x3E: pmaxuw_Vdq_Wdq();
+            0x3F: pmaxud_Vdq_Wdq();
+            0x40: pmulld_Vdq_Wdq();
+            0x41: phminposuw_Vdq_Wdq();
+            default: Inst::UD2();
+        }
+        default: decode LEGACY_REPNE {
+            1: decode OPCODE_OP {
+                0xF0: crc32_Gd_Eb();
+                0xF1: crc32_Gd_Ev();
+                default: Inst::UD2();
+            }
+            default: decode OPCODE_OP {
+                0x00: pshufb_Pq_Qq();
+                0x01: phaddw_Pq_Qq();
+                0x02: phaddd_Pq_Qq();
+                0x03: phaddsw_Pq_Qq();
+                0x04: pmaddubsw_Pq_Qq();
+                0x05: phsubw_Pq_Qq();
+                0x06: phsubd_Pq_Qq();
+                0x07: phsubsw_Pq_Qq();
+                0x08: psignb_Pq_Qq();
+                0x09: psignw_Pq_Qq();
+                0x0A: psignd_Pq_Qq();
+                0x0B: pmulhrsw_Pq_Qq();
+                0x1C: pabsb_Pq_Qq();
+                0x1D: pabsw_Pq_Qq();
+                0x1E: pabsd_Pq_Qq();
+                default: Inst::UD2();
+            }
+        }
+    }
+}
diff --git a/src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa b/src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa
new file mode 100644 (file)
index 0000000..5935fb6
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (c) 2008 The Regents of The University of Michigan
+// 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: Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Decode the three byte opcodes with the 0f3a prefix.
+//
+format WarnUnimpl {
+    'X86ISA::ThreeByte0F3AOpcode': decode LEGACY_OP {
+        1: decode OPCODE_OP {
+            0x08: roundps_Vdq_Wdq_Ib();
+            0x09: roundpd_Vdq_Wdq_Ib();
+            0x0A: roundss_Vss_Wss_Ib();
+            0x0B: roundsd_Vsd_Wsd_Ib();
+            0x0C: blendps_Vdq_Wdq_Ib();
+            0x0D: blendpd_Vdq_Wdq_Ib();
+            0x0E: pblendw_Vdq_Wdq_Ib();
+            0x0F: palignr_Vdq_Wdq_Ib();
+            0x14: pextrb_Rd_or_Mb_Vdq_Ib();
+            0x15: decode MODRM_MOD {
+                0x3: Inst::PEXTRW(Rd,Vdq,Ib);
+                default: pextrw_Mw_Vdq_Ib();
+            }
+            0x16: pextrd_pextrq_Ed_or_Eq_Vdq_Ib();
+            0x17: extractps_Ed_Vdq_Ib();
+            0x20: pinsrb_Vdq_Rd_or_Rq_or_Mb_Ib();
+            0x21: insertps_Vdq_Udq_or_Md_Ib();
+            0x22: pinsrd_pinsrq_Vdq_Ed_or_Eq_Ib();
+            0x40: dpps_Vdq_Wdq_Ib();
+            0x41: dppd_Vdq_Wdq_Ib();
+            0x42: pcmpistrm_Vdq_Wdq_Ib();
+            0x43: pcmpistri_Vdq_Wdq_Ib();
+            default: Inst::UD2();
+        }
+        default: decode OPCODE_OP {
+            0x0F: palignr_Pq_Qq_Ib();
+            default: Inst::UD2();
+        }
+    }
+}
diff --git a/src/arch/x86/isa/decoder/three_byte_opcodes.isa b/src/arch/x86/isa/decoder/three_byte_opcodes.isa
deleted file mode 100644 (file)
index 7587e3d..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2008 The Regents of The University of Michigan
-// 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: Gabe Black
-
-////////////////////////////////////////////////////////////////////
-//
-// Decode the three byte opcodes
-//
-0x3: decode OPCODE_PREFIXA {
-    0x0F: decode OPCODE_PREFIXB {
-        0x38: decode LEGACY_OP {
-            format WarnUnimpl {
-                1: decode OPCODE_OP {
-                    0x00: pshufb_Vdq_Wdq();
-                    0x01: phaddw_Vdq_Wdq();
-                    0x02: phaddd_Vdq_Wdq();
-                    0x03: phaddsw_Vdq_Wdq();
-                    0x04: pmaddubsw_Vdq_Wdq();
-                    0x05: phsubw_Vdq_Wdq();
-                    0x06: phsubd_Vdq_Wdq();
-                    0x07: phsubsw_Vdq_Wdq();
-                    0x08: psignb_Vdq_Wdq();
-                    0x09: psignw_Vdq_Wdq();
-                    0x0A: psignd_Vdq_Wdq();
-                    0x0B: pmulhrsw_Vdq_Wdq();
-                    0x10: pblendvb_Vdq_Wdq();
-                    0x14: blendvps_Vdq_Wdq();
-                    0x15: blendvpd_Vdq_Wdq();
-                    0x17: ptest_Vdq_Wdq();
-                    0x1C: pabsb_Vdq_Wdq();
-                    0x1D: pabsw_Vdq_Wdq();
-                    0x1E: pabsd_Vdq_Wdq();
-                    0x20: pmovsxbw_Vdq_Udq_or_Mq();
-                    0x21: pmovsxbd_Vdq_Udq_or_Md();
-                    0x22: pmovsxbq_Vdq_Udq_or_Mw();
-                    0x23: pmovsxwd_Vdq_Udq_or_Mq();
-                    0x24: pmovsxwq_Vdq_Udq_or_Md();
-                    0x25: pmovsxdq_Vdq_Udq_or_Mq();
-                    0x28: pmuldq_Vdq_Wdq();
-                    0x29: pcmpeqq_Vdq_Wdq();
-                    0x2A: movntdqa_Vdq_Mdq();
-                    0x2B: packusdw_Vdq_Wdq();
-                    0x30: pmovzxbw_Vdq_Udq_or_Mq();
-                    0x31: pmovzxbd_Vdq_Udq_or_Md();
-                    0x32: pmovzxbq_Vdq_Udq_or_Mw();
-                    0x33: pmovzxwd_Vdq_Udq_or_Mq();
-                    0x34: pmovzxwq_Vdq_Udq_or_Md();
-                    0x35: pmovzxdq_Vdq_Udq_or_Mq();
-                    0x37: pcmpgtq_Vdq_Wdq();
-                    0x38: pminsb_Vdq_Wdq();
-                    0x39: pminsd_Vdq_Wdq();
-                    0x3A: pminuw_Vdq_Wdq();
-                    0x3B: pminud_Vdq_Wdq();
-                    0x3C: pmaxsb_Vdq_Wdq();
-                    0x3D: pmaxsd_Vdq_Wdq();
-                    0x3E: pmaxuw_Vdq_Wdq();
-                    0x3F: pmaxud_Vdq_Wdq();
-                    0x40: pmulld_Vdq_Wdq();
-                    0x41: phminposuw_Vdq_Wdq();
-                    default: Inst::UD2();
-                }
-                default: decode LEGACY_REPNE {
-                    1: decode OPCODE_OP {
-                        0xF0: crc32_Gd_Eb();
-                        0xF1: crc32_Gd_Ev();
-                        default: Inst::UD2();
-                    }
-                    default: decode OPCODE_OP {
-                        0x00: pshufb_Pq_Qq();
-                        0x01: phaddw_Pq_Qq();
-                        0x02: phaddd_Pq_Qq();
-                        0x03: phaddsw_Pq_Qq();
-                        0x04: pmaddubsw_Pq_Qq();
-                        0x05: phsubw_Pq_Qq();
-                        0x06: phsubd_Pq_Qq();
-                        0x07: phsubsw_Pq_Qq();
-                        0x08: psignb_Pq_Qq();
-                        0x09: psignw_Pq_Qq();
-                        0x0A: psignd_Pq_Qq();
-                        0x0B: pmulhrsw_Pq_Qq();
-                        0x1C: pabsb_Pq_Qq();
-                        0x1D: pabsw_Pq_Qq();
-                        0x1E: pabsd_Pq_Qq();
-                        default: Inst::UD2();
-                    }
-                }
-            }
-        }
-        0x3A: decode LEGACY_OP {
-            format WarnUnimpl {
-                1: decode OPCODE_OP {
-                    0x08: roundps_Vdq_Wdq_Ib();
-                    0x09: roundpd_Vdq_Wdq_Ib();
-                    0x0A: roundss_Vss_Wss_Ib();
-                    0x0B: roundsd_Vsd_Wsd_Ib();
-                    0x0C: blendps_Vdq_Wdq_Ib();
-                    0x0D: blendpd_Vdq_Wdq_Ib();
-                    0x0E: pblendw_Vdq_Wdq_Ib();
-                    0x0F: palignr_Vdq_Wdq_Ib();
-                    0x14: pextrb_Rd_or_Mb_Vdq_Ib();
-                    0x15: decode MODRM_MOD {
-                        0x3: Inst::PEXTRW(Rd,Vdq,Ib);
-                        default: pextrw_Mw_Vdq_Ib();
-                    }
-                    0x16: pextrd_pextrq_Ed_or_Eq_Vdq_Ib();
-                    0x17: extractps_Ed_Vdq_Ib();
-                    0x20: pinsrb_Vdq_Rd_or_Rq_or_Mb_Ib();
-                    0x21: insertps_Vdq_Udq_or_Md_Ib();
-                    0x22: pinsrd_pinsrq_Vdq_Ed_or_Eq_Ib();
-                    0x40: dpps_Vdq_Wdq_Ib();
-                    0x41: dppd_Vdq_Wdq_Ib();
-                    0x42: pcmpistrm_Vdq_Wdq_Ib();
-                    0x43: pcmpistri_Vdq_Wdq_Ib();
-                    default: Inst::UD2();
-                }
-                default: decode OPCODE_OP {
-                    0x0F: palignr_Pq_Qq_Ib();
-                    default: Inst::UD2();
-                }
-            }
-        }
-        default: M5InternalError::error(
-            {{"Unexpected second opcode byte in three byte opcode!"}});
-    }
-    default: M5InternalError::error(
-        {{"Unexpected first opcode byte in three byte opcode!"}});
-}
index 081bad97139880ca18ec89de07c2ed51f31741bf..e1b20feb1244f03b84183594a34d1cbdb2b3cd85 100644 (file)
 //
 // Decode the two byte opcodes
 //
-0x2: decode OPCODE_PREFIXA {
-    0x0F: decode OPCODE_OP_TOP5 {
-        format WarnUnimpl {
-            0x00: decode OPCODE_OP_BOTTOM3 {
-                //0x00: group6();
-                0x00: decode MODRM_REG {
-                    0x0: sldt_Mw_or_Rv();
-                    0x1: str_Mw_or_Rv();
-                    0x2: Inst::LLDT(Ew);
-                    0x3: Inst::LTR(Ew);
-                    0x4: verr_Mw_or_Rv();
-                    0x5: verw_Mw_or_Rv();
-                    //0x6: jmpe_Ev(); // IA-64
-                    default: Inst::UD2();
-                }
-                //0x01: group7(); // Ugly, ugly, ugly...
-                0x01: decode MODRM_REG {
-                    0x0: decode MODRM_MOD {
-                        0x3: decode MODRM_RM {
-                            0x1: vmcall();
-                            0x2: vmlaunch();
-                            0x3: vmresume();
-                            0x4: vmxoff();
-                            default: Inst::UD2();
-                        }
-                        default: sgdt_Ms();
-                    }
-                    0x1: decode MODRM_MOD {
-                        0x3: decode MODRM_RM {
-                            0x0: MonitorInst::monitor({{
-                               xc->armMonitor(Rax);
-                            }});
-                            0x1: MwaitInst::mwait({{
-                               uint64_t m = 0;          //mem
-                               unsigned s = 0x8;        //size
-                               unsigned f = 0;          //flags
-                               readMemAtomic(xc, traceData,
-                                             xc->getAddrMonitor()->vAddr,
-                                             m, s, f);
-                               xc->mwaitAtomic(xc->tcBase());
-                               MicroHalt hltObj(machInst, mnemonic, 0x0);
-                               hltObj.execute(xc, traceData);
-                            }});
-                            default: Inst::UD2();
-                        }
-                        default: sidt_Ms();
+'X86ISA::TwoByteOpcode': decode OPCODE_OP_TOP5 {
+    format WarnUnimpl {
+        0x00: decode OPCODE_OP_BOTTOM3 {
+            //0x00: group6();
+            0x00: decode MODRM_REG {
+                0x0: sldt_Mw_or_Rv();
+                0x1: str_Mw_or_Rv();
+                0x2: Inst::LLDT(Ew);
+                0x3: Inst::LTR(Ew);
+                0x4: verr_Mw_or_Rv();
+                0x5: verw_Mw_or_Rv();
+                //0x6: jmpe_Ev(); // IA-64
+                default: Inst::UD2();
+            }
+            //0x01: group7(); // Ugly, ugly, ugly...
+            0x01: decode MODRM_REG {
+                0x0: decode MODRM_MOD {
+                    0x3: decode MODRM_RM {
+                        0x1: vmcall();
+                        0x2: vmlaunch();
+                        0x3: vmresume();
+                        0x4: vmxoff();
+                        default: Inst::UD2();
                     }
-                    0x2: decode MODRM_MOD {
-                        0x3: decode MODRM_RM {
-                            0x0: xgetbv();
-                            0x1: xsetbv();
-                        }
-                        default: decode MODE_SUBMODE {
-                            0x0: Inst::LGDT(M);
-                            default: decode OPSIZE {
-                                // 16 bit operand sizes are special, but only
-                                // in legacy and compatability modes.
-                                0x2: Inst::LGDT_16(M);
-                                default: Inst::LGDT(M);
-                            }
-                        }
+                    default: sgdt_Ms();
+                }
+                0x1: decode MODRM_MOD {
+                    0x3: decode MODRM_RM {
+                        0x0: MonitorInst::monitor({{
+                           xc->armMonitor(Rax);
+                        }});
+                        0x1: MwaitInst::mwait({{
+                           uint64_t m = 0;          //mem
+                           unsigned s = 0x8;        //size
+                           unsigned f = 0;          //flags
+                           readMemAtomic(xc, traceData,
+                                         xc->getAddrMonitor()->vAddr,
+                                         m, s, f);
+                           xc->mwaitAtomic(xc->tcBase());
+                           MicroHalt hltObj(machInst, mnemonic, 0x0);
+                           hltObj.execute(xc, traceData);
+                        }});
+                        default: Inst::UD2();
                     }
-                    0x3: decode MODRM_MOD {
-                        0x3: decode MODRM_RM {
-                            0x0: vmrun();
-                            0x1: vmmcall();
-                            0x2: vmload();
-                            0x3: vmsave();
-                            0x4: stgi();
-                            0x5: clgi();
-                            0x6: skinit();
-                            0x7: invlpga();
-                        }
-                        default: decode MODE_SUBMODE {
-                            0x0: Inst::LIDT(M);
-                            default: decode OPSIZE {
-                                // 16 bit operand sizes are special, but only
-                                // in legacy and compatability modes.
-                                0x2: Inst::LIDT_16(M);
-                                default: Inst::LIDT(M);
-                            }
+                    default: sidt_Ms();
+                }
+                0x2: decode MODRM_MOD {
+                    0x3: decode MODRM_RM {
+                        0x0: xgetbv();
+                        0x1: xsetbv();
+                    }
+                    default: decode MODE_SUBMODE {
+                        0x0: Inst::LGDT(M);
+                        default: decode OPSIZE {
+                            // 16 bit operand sizes are special, but only
+                            // in legacy and compatability modes.
+                            0x2: Inst::LGDT_16(M);
+                            default: Inst::LGDT(M);
                         }
                     }
-                    0x4: decode MODRM_MOD {
-                        0x3: Inst::SMSW(Rv);
-                        default: Inst::SMSW(Mw);
-                    }
-                    0x6: Inst::LMSW(Ew);
-                    0x7: decode MODRM_MOD {
-                        0x3: decode MODRM_RM {
-                            0x0: Inst::SWAPGS();
-                            0x1: rdtscp();
-                            default: Inst::UD2();
+                }
+                0x3: decode MODRM_MOD {
+                    0x3: decode MODRM_RM {
+                        0x0: vmrun();
+                        0x1: vmmcall();
+                        0x2: vmload();
+                        0x3: vmsave();
+                        0x4: stgi();
+                        0x5: clgi();
+                        0x6: skinit();
+                        0x7: invlpga();
+                    }
+                    default: decode MODE_SUBMODE {
+                        0x0: Inst::LIDT(M);
+                        default: decode OPSIZE {
+                            // 16 bit operand sizes are special, but only
+                            // in legacy and compatability modes.
+                            0x2: Inst::LIDT_16(M);
+                            default: Inst::LIDT(M);
                         }
-                        default: Inst::INVLPG(M);
                     }
                 }
-                0x02: lar_Gv_Ew();
-                0x03: lsl_Gv_Ew();
-                // sandpile.org doesn't seem to know what this is...? We'll
-                // use it for pseudo instructions. We've got 16 bits of space
-                // to play with so there can be quite a few pseudo
-                // instructions.
-                //0x04: loadall_or_reset_or_hang();
-                0x4: decode IMMEDIATE {
-                    format BasicOperate {
-                        0x00: m5arm({{
-                            PseudoInst::arm(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x01: m5quiesce({{
-                            PseudoInst::quiesce(xc->tcBase());
-                        }}, IsNonSpeculative, IsQuiesce);
-                        0x02: m5quiesceNs({{
-                            PseudoInst::quiesceNs(xc->tcBase(), Rdi);
-                        }}, IsNonSpeculative, IsQuiesce);
-                        0x03: m5quiesceCycle({{
-                            PseudoInst::quiesceCycles(xc->tcBase(), Rdi);
-                        }}, IsNonSpeculative, IsQuiesce);
-                        0x04: m5quiesceTime({{
-                            Rax = PseudoInst::quiesceTime(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x07: m5rpns({{
-                            Rax = PseudoInst::rpns(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x21: m5exit({{
-                            PseudoInst::m5exit(xc->tcBase(), Rdi);
-                        }}, IsNonSpeculative);
-                        0x22: m5fail({{
-                            PseudoInst::m5fail(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x30: m5initparam({{
-                            Rax = PseudoInst::initParam(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x31: m5loadsymbol({{
-                            PseudoInst::loadsymbol(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x40: m5resetstats({{
-                            PseudoInst::resetstats(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x41: m5dumpstats({{
-                            PseudoInst::dumpstats(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x42: m5dumpresetstats({{
-                            PseudoInst::dumpresetstats(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x43: m5checkpoint({{
-                            PseudoInst::m5checkpoint(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x50: m5readfile({{
-                            Rax = PseudoInst::readfile(
-                                xc->tcBase(), Rdi, Rsi, Rdx);
-                        }}, IsNonSpeculative);
-                        0x51: m5debugbreak({{
-                            PseudoInst::debugbreak(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x52: m5switchcpu({{
-                            PseudoInst::switchcpu(xc->tcBase());
-                        }}, IsNonSpeculative);
-                        0x53: m5addsymbol({{
-                            PseudoInst::addsymbol(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x54: m5panic({{
-                            panic("M5 panic instruction called at pc = %#x.\n",
-                                  RIP);
-                        }}, IsNonSpeculative);
-                        0x55: m5reserved1({{
-                            warn("M5 reserved opcode 1 ignored.\n");
-                        }}, IsNonSpeculative);
-                        0x56: m5reserved2({{
-                            warn("M5 reserved opcode 2 ignored.\n");
-                        }}, IsNonSpeculative);
-                        0x57: m5reserved3({{
-                            warn("M5 reserved opcode 3 ignored.\n");
-                        }}, IsNonSpeculative);
-                        0x58: m5reserved4({{
-                            warn("M5 reserved opcode 4 ignored.\n");
-                        }}, IsNonSpeculative);
-                        0x59: m5reserved5({{
-                            warn("M5 reserved opcode 5 ignored.\n");
-                        }}, IsNonSpeculative);
-                        0x5a: m5_work_begin({{
-                            PseudoInst::workbegin(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
-                        0x5b: m5_work_end({{
-                            PseudoInst::workend(xc->tcBase(), Rdi, Rsi);
-                        }}, IsNonSpeculative);
+                0x4: decode MODRM_MOD {
+                    0x3: Inst::SMSW(Rv);
+                    default: Inst::SMSW(Mw);
+                }
+                0x6: Inst::LMSW(Ew);
+                0x7: decode MODRM_MOD {
+                    0x3: decode MODRM_RM {
+                        0x0: Inst::SWAPGS();
+                        0x1: rdtscp();
                         default: Inst::UD2();
                     }
+                    default: Inst::INVLPG(M);
                 }
-                0x05: decode FullSystemInt {
-                    0: SyscallInst::syscall('xc->syscall(Rax)',
-                            IsSyscall, IsNonSpeculative, IsSerializeAfter);
-                    default: decode MODE_MODE {
-                        0x0: decode MODE_SUBMODE {
-                            0x0: Inst::SYSCALL_64();
-                            0x1: Inst::SYSCALL_COMPAT();
-                        }
-                        0x1: Inst::SYSCALL_LEGACY();
-                    }
+            }
+            0x02: lar_Gv_Ew();
+            0x03: lsl_Gv_Ew();
+            // sandpile.org doesn't seem to know what this is...? We'll
+            // use it for pseudo instructions. We've got 16 bits of space
+            // to play with so there can be quite a few pseudo
+            // instructions.
+            //0x04: loadall_or_reset_or_hang();
+            0x4: decode IMMEDIATE {
+                format BasicOperate {
+                    0x00: m5arm({{
+                        PseudoInst::arm(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x01: m5quiesce({{
+                        PseudoInst::quiesce(xc->tcBase());
+                    }}, IsNonSpeculative, IsQuiesce);
+                    0x02: m5quiesceNs({{
+                        PseudoInst::quiesceNs(xc->tcBase(), Rdi);
+                    }}, IsNonSpeculative, IsQuiesce);
+                    0x03: m5quiesceCycle({{
+                        PseudoInst::quiesceCycles(xc->tcBase(), Rdi);
+                    }}, IsNonSpeculative, IsQuiesce);
+                    0x04: m5quiesceTime({{
+                        Rax = PseudoInst::quiesceTime(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x07: m5rpns({{
+                        Rax = PseudoInst::rpns(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x21: m5exit({{
+                        PseudoInst::m5exit(xc->tcBase(), Rdi);
+                    }}, IsNonSpeculative);
+                    0x22: m5fail({{
+                        PseudoInst::m5fail(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x30: m5initparam({{
+                        Rax = PseudoInst::initParam(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x31: m5loadsymbol({{
+                        PseudoInst::loadsymbol(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x40: m5resetstats({{
+                        PseudoInst::resetstats(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x41: m5dumpstats({{
+                        PseudoInst::dumpstats(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x42: m5dumpresetstats({{
+                        PseudoInst::dumpresetstats(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x43: m5checkpoint({{
+                        PseudoInst::m5checkpoint(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x50: m5readfile({{
+                        Rax = PseudoInst::readfile(
+                            xc->tcBase(), Rdi, Rsi, Rdx);
+                    }}, IsNonSpeculative);
+                    0x51: m5debugbreak({{
+                        PseudoInst::debugbreak(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x52: m5switchcpu({{
+                        PseudoInst::switchcpu(xc->tcBase());
+                    }}, IsNonSpeculative);
+                    0x53: m5addsymbol({{
+                        PseudoInst::addsymbol(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x54: m5panic({{
+                        panic("M5 panic instruction called at pc = %#x.\n",
+                              RIP);
+                    }}, IsNonSpeculative);
+                    0x55: m5reserved1({{
+                        warn("M5 reserved opcode 1 ignored.\n");
+                    }}, IsNonSpeculative);
+                    0x56: m5reserved2({{
+                        warn("M5 reserved opcode 2 ignored.\n");
+                    }}, IsNonSpeculative);
+                    0x57: m5reserved3({{
+                        warn("M5 reserved opcode 3 ignored.\n");
+                    }}, IsNonSpeculative);
+                    0x58: m5reserved4({{
+                        warn("M5 reserved opcode 4 ignored.\n");
+                    }}, IsNonSpeculative);
+                    0x59: m5reserved5({{
+                        warn("M5 reserved opcode 5 ignored.\n");
+                    }}, IsNonSpeculative);
+                    0x5a: m5_work_begin({{
+                        PseudoInst::workbegin(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    0x5b: m5_work_end({{
+                        PseudoInst::workend(xc->tcBase(), Rdi, Rsi);
+                    }}, IsNonSpeculative);
+                    default: Inst::UD2();
                 }
-                0x06: Inst::CLTS();
-                0x07: decode MODE_SUBMODE {
-                    0x0: decode OPSIZE {
-                        // Return to 64 bit mode.
-                        0x8: Inst::SYSRET_TO_64();
-                        // Return to compatibility mode.
-                        default: Inst::SYSRET_TO_COMPAT();
-                    }
-                    default: Inst::SYSRET_NON_64();
+            }
+            0x05: decode FullSystemInt {
+                0: SyscallInst::syscall('xc->syscall(Rax)',
+                        IsSyscall, IsNonSpeculative, IsSerializeAfter);
+                default: decode MODE_MODE {
+                    0x0: decode MODE_SUBMODE {
+                        0x0: Inst::SYSCALL_64();
+                        0x1: Inst::SYSCALL_COMPAT();
+                    }
+                    0x1: Inst::SYSCALL_LEGACY();
                 }
             }
-            0x01: decode OPCODE_OP_BOTTOM3 {
-                0x0: invd();
-                0x1: wbinvd();
-                0x2: Inst::UD2();
-                0x3: Inst::UD2();
-                0x4: Inst::UD2();
-                0x5: Inst::PREFETCH(Mb);
-                0x6: FailUnimpl::femms();
-                0x7: decode IMMEDIATE {
-                    0x0C: pi2fw_Pq_Qq();
-                    0x0D: pi2fd_Pq_Qq();
-                    0x1C: pf2iw_Pq_Qq();
-                    0x1D: pf2id_Pq_Qq();
-                    0x8A: pfnacc_Pq_Qq();
-                    0x8E: pfpnacc_Pq_Qq();
-                    0x90: pfcmpge_Pq_Qq();
-                    0x94: pfmin_Pq_Qq();
-                    0x96: pfrcp_Pq_Qq();
-                    0x97: pfrsqrt_Pq_Qq();
-                    0x9A: Inst::PFSUB(Pq,Qq);
-                    0x9E: pfadd_Pq_Qq();
-                    0xA0: pfcmpgt_Pq_Qq();
-                    0xA4: pfmax_Pq_Qq();
-                    0xA6: pfrcpit1_Pq_Qq();
-                    0xA7: pfrsqit1_Pq_Qq();
-                    0xAA: Inst::PFSUBR(Pq,Qq);
-                    0xAE: pfacc_Pq_Qq();
-                    0xB0: pfcmpeq_Pq_Qq();
-                    0xB4: Inst::PFMUL(Pq,Qq);
-                    0xB6: pfrcpit2_Pq_Qq();
-                    0xB7: Inst::PMULHRW(Pq,Qq);
-                    0xBB: pswapd_Pq_Qq();
-                    0xBF: pavgusb_Pq_Qq();
-                    default: Inst::UD2();
+            0x06: Inst::CLTS();
+            0x07: decode MODE_SUBMODE {
+                0x0: decode OPSIZE {
+                    // Return to 64 bit mode.
+                    0x8: Inst::SYSRET_TO_64();
+                    // Return to compatibility mode.
+                    default: Inst::SYSRET_TO_COMPAT();
                 }
+                default: Inst::SYSRET_NON_64();
             }
-            format Inst{
-                0x02: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVUPS(Vo,Wo);
-                        0x1: MOVUPS(Wo,Vo);
-                        0x2: decode MODRM_MOD {
-                            0x3: MOVHLPS(Vps,VRq);
-                            default: MOVLPS(Vps,Mq);
-                        }
-                        0x3: MOVLPS(Mq,Vps);
-                        0x4: UNPCKLPS(Vps,Wq);
-                        0x5: UNPCKHPS(Vps,Wq);
-                        0x6: decode MODRM_MOD {
-                            0x3: MOVLHPS(Vps,VRq);
-                            default: MOVHPS(Vps,Mq);
-                        }
-                        0x7: MOVHPS(Mq,Vq);
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVSS(Vd,Wd);
-                        0x1: MOVSS(Wd,Vd);
-                        0x2: WarnUnimpl::movsldup_Vo_Wo();
-                        0x6: WarnUnimpl::movshdup_Vo_Wo();
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVUPD(Vo,Wo);
-                        0x1: MOVUPD(Wo,Vo);
-                        0x2: MOVLPD(Vq,Mq);
-                        0x3: MOVLPD(Mq,Vq);
-                        0x4: UNPCKLPD(Vo,Wq);
-                        0x5: UNPCKHPD(Vo,Wo);
-                        0x6: MOVHPD(Vq,Mq);
-                        0x7: MOVHPD(Mq,Vq);
+        }
+        0x01: decode OPCODE_OP_BOTTOM3 {
+            0x0: invd();
+            0x1: wbinvd();
+            0x2: Inst::UD2();
+            0x3: Inst::UD2();
+            0x4: Inst::UD2();
+            0x5: Inst::PREFETCH(Mb);
+            0x6: FailUnimpl::femms();
+            0x7: decode IMMEDIATE {
+                0x0C: pi2fw_Pq_Qq();
+                0x0D: pi2fd_Pq_Qq();
+                0x1C: pf2iw_Pq_Qq();
+                0x1D: pf2id_Pq_Qq();
+                0x8A: pfnacc_Pq_Qq();
+                0x8E: pfpnacc_Pq_Qq();
+                0x90: pfcmpge_Pq_Qq();
+                0x94: pfmin_Pq_Qq();
+                0x96: pfrcp_Pq_Qq();
+                0x97: pfrsqrt_Pq_Qq();
+                0x9A: Inst::PFSUB(Pq,Qq);
+                0x9E: pfadd_Pq_Qq();
+                0xA0: pfcmpgt_Pq_Qq();
+                0xA4: pfmax_Pq_Qq();
+                0xA6: pfrcpit1_Pq_Qq();
+                0xA7: pfrsqit1_Pq_Qq();
+                0xAA: Inst::PFSUBR(Pq,Qq);
+                0xAE: pfacc_Pq_Qq();
+                0xB0: pfcmpeq_Pq_Qq();
+                0xB4: Inst::PFMUL(Pq,Qq);
+                0xB6: pfrcpit2_Pq_Qq();
+                0xB7: Inst::PMULHRW(Pq,Qq);
+                0xBB: pswapd_Pq_Qq();
+                0xBF: pavgusb_Pq_Qq();
+                default: Inst::UD2();
+            }
+        }
+        format Inst{
+            0x02: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVUPS(Vo,Wo);
+                    0x1: MOVUPS(Wo,Vo);
+                    0x2: decode MODRM_MOD {
+                        0x3: MOVHLPS(Vps,VRq);
+                        default: MOVLPS(Vps,Mq);
                     }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVSD(Vq,Wq);
-                        0x1: MOVSD(Wq,Vq);
-                        0x2: MOVDDUP(Vo,Wq);
-                        default: UD2();
+                    0x3: MOVLPS(Mq,Vps);
+                    0x4: UNPCKLPS(Vps,Wq);
+                    0x5: UNPCKHPS(Vps,Wq);
+                    0x6: decode MODRM_MOD {
+                        0x3: MOVLHPS(Vps,VRq);
+                        default: MOVHPS(Vps,Mq);
                     }
-                    default: UD2();
+                    0x7: MOVHPS(Mq,Vq);
                 }
-                0x03: decode OPCODE_OP_BOTTOM3 {
-                    //group16();
-                    0x0: decode MODRM_REG {
-                        0x0: WarnUnimpl::prefetch_nta();
-                        0x1: PREFETCH_T0(Mb);
-                        0x2: WarnUnimpl::prefetch_t1();
-                        0x3: WarnUnimpl::prefetch_t2();
-                        default: HINT_NOP();
-                    }
-                    0x1: HINT_NOP();
-                    0x2: HINT_NOP();
-                    0x3: HINT_NOP();
-                    0x4: HINT_NOP();
-                    0x5: HINT_NOP();
-                    0x6: HINT_NOP();
-                    0x7: HINT_NOP();
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVSS(Vd,Wd);
+                    0x1: MOVSS(Wd,Vd);
+                    0x2: WarnUnimpl::movsldup_Vo_Wo();
+                    0x6: WarnUnimpl::movshdup_Vo_Wo();
+                    default: UD2();
                 }
-                0x04: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOV(Rd,Cd);
-                        0x1: MOV(Rd,Dd);
-                        0x2: MOV(Cd,Rd);
-                        0x3: MOV(Dd,Rd);
-                        default: UD2();
-                    }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVUPD(Vo,Wo);
+                    0x1: MOVUPD(Wo,Vo);
+                    0x2: MOVLPD(Vq,Mq);
+                    0x3: MOVLPD(Mq,Vq);
+                    0x4: UNPCKLPD(Vo,Wq);
+                    0x5: UNPCKHPD(Vo,Wo);
+                    0x6: MOVHPD(Vq,Mq);
+                    0x7: MOVHPD(Mq,Vq);
+            }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVSD(Vq,Wq);
+                    0x1: MOVSD(Wq,Vq);
+                    0x2: MOVDDUP(Vo,Wq);
                     default: UD2();
                 }
-                0x05: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        //These moves should really use size o (octword), but
-                        //because they are split in two, they use q (quadword).
-                        0x0: MOVAPS(Vq,Wq);
-                        0x1: MOVAPS(Wq,Vq);
-                        0x2: CVTPI2PS(Vq,Qq);
-                        0x3: WarnUnimpl::movntps_Mo_Vo();
-                        0x4: CVTTPS2PI(Pq,Wq);
-                        0x5: CVTPS2PI(Pq,Wq);
-                        0x6: UCOMISS(Vd,Wd);
-                        0x7: COMISS(Vd,Wd);
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x2: CVTSI2SS(Vd,Ed);
-                        0x4: CVTTSS2SI(Gd,Wd);
-                        0x5: CVTSS2SI(Gd,Wd);
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVAPD(Vo,Wo);
-                        0x1: MOVAPD(Wo,Vo);
-                        0x2: CVTPI2PD(Vo,Qq);
-                        0x3: WarnUnimpl::movntpd_Mo_Vo();
-                        0x4: CVTTPD2PI(Pq,Wo);
-                        0x5: CVTPD2PI(Pq,Wo);
-                        0x6: UCOMISD(Vq,Wq);
-                        0x7: COMISD(Vq,Wq);
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        // The size of the V operand should be q, not dp
-                        0x2: CVTSI2SD(Vdp,Edp);
-                        // The size of the W operand should be q, not dp
-                        0x4: CVTTSD2SI(Gdp,Wdp);
-                        0x5: CVTSD2SI(Gd,Wq);
-                        default: UD2();
-                    }
+                default: UD2();
+            }
+            0x03: decode OPCODE_OP_BOTTOM3 {
+                //group16();
+                0x0: decode MODRM_REG {
+                    0x0: WarnUnimpl::prefetch_nta();
+                    0x1: PREFETCH_T0(Mb);
+                    0x2: WarnUnimpl::prefetch_t1();
+                    0x3: WarnUnimpl::prefetch_t2();
+                    default: HINT_NOP();
+                }
+                0x1: HINT_NOP();
+                0x2: HINT_NOP();
+                0x3: HINT_NOP();
+                0x4: HINT_NOP();
+                0x5: HINT_NOP();
+                0x6: HINT_NOP();
+                0x7: HINT_NOP();
+            }
+            0x04: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOV(Rd,Cd);
+                    0x1: MOV(Rd,Dd);
+                    0x2: MOV(Cd,Rd);
+                    0x3: MOV(Dd,Rd);
                     default: UD2();
                 }
+                default: UD2();
             }
-            0x06: decode OPCODE_OP_BOTTOM3 {
-                0x0: Inst::WRMSR();
-                0x1: Inst::RDTSC();
-                0x2: Inst::RDMSR();
-                0x3: rdpmc();
-                0x4: decode FullSystemInt {
-                    0: SyscallInst::sysenter('xc->syscall(Rax)',
-                            IsSyscall, IsNonSpeculative, IsSerializeAfter);
-                    default: sysenter();
+            0x05: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    //These moves should really use size o (octword), but
+                    //because they are split in two, they use q (quadword).
+                    0x0: MOVAPS(Vq,Wq);
+                    0x1: MOVAPS(Wq,Vq);
+                    0x2: CVTPI2PS(Vq,Qq);
+                    0x3: WarnUnimpl::movntps_Mo_Vo();
+                    0x4: CVTTPS2PI(Pq,Wq);
+                    0x5: CVTPS2PI(Pq,Wq);
+                    0x6: UCOMISS(Vd,Wd);
+                    0x7: COMISS(Vd,Wd);
+                }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x2: CVTSI2SS(Vd,Ed);
+                    0x4: CVTTSS2SI(Gd,Wd);
+                    0x5: CVTSS2SI(Gd,Wd);
+                    default: UD2();
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVAPD(Vo,Wo);
+                    0x1: MOVAPD(Wo,Vo);
+                    0x2: CVTPI2PD(Vo,Qq);
+                    0x3: WarnUnimpl::movntpd_Mo_Vo();
+                    0x4: CVTTPD2PI(Pq,Wo);
+                    0x5: CVTPD2PI(Pq,Wo);
+                    0x6: UCOMISD(Vq,Wq);
+                    0x7: COMISD(Vq,Wq);
                 }
-                0x5: sysexit();
-                0x6: Inst::UD2();
-                0x7: getsec();
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    // The size of the V operand should be q, not dp
+                    0x2: CVTSI2SD(Vdp,Edp);
+                    // The size of the W operand should be q, not dp
+                    0x4: CVTTSD2SI(Gdp,Wdp);
+                    0x5: CVTSD2SI(Gd,Wq);
+                    default: UD2();
+                }
+                default: UD2();
+            }
+        }
+        0x06: decode OPCODE_OP_BOTTOM3 {
+            0x0: Inst::WRMSR();
+            0x1: Inst::RDTSC();
+            0x2: Inst::RDMSR();
+            0x3: rdpmc();
+            0x4: decode FullSystemInt {
+                0: SyscallInst::sysenter('xc->syscall(Rax)',
+                        IsSyscall, IsNonSpeculative, IsSerializeAfter);
+                default: sysenter();
             }
-            0x07: decode OPCODE_OP_BOTTOM3 {
-                0x0: M5InternalError::error(
-                    {{"Three byte opcode shouldn't be handled by "
-                      "two_byte_opcodes.isa!"}});
-                0x2: M5InternalError::error(
-                    {{"Three byte opcode shouldn't be handled by "
-                      "two_byte_opcodes.isa!"}});
+            0x5: sysexit();
+            0x6: Inst::UD2();
+            0x7: getsec();
+        }
+        0x07: decode OPCODE_OP_BOTTOM3 {
+            0x0: M5InternalError::error(
+                {{"Three byte opcode shouldn't be handled by "
+                  "two_byte_opcodes.isa!"}});
+            0x2: M5InternalError::error(
+                {{"Three byte opcode shouldn't be handled by "
+                  "two_byte_opcodes.isa!"}});
+            default: UD2();
+        }
+        format Inst {
+            0x08: decode OPCODE_OP_BOTTOM3 {
+                0x0: CMOVO(Gv,Ev);
+                0x1: CMOVNO(Gv,Ev);
+                0x2: CMOVB(Gv,Ev);
+                0x3: CMOVNB(Gv,Ev);
+                0x4: CMOVZ(Gv,Ev);
+                0x5: CMOVNZ(Gv,Ev);
+                0x6: CMOVBE(Gv,Ev);
+                0x7: CMOVNBE(Gv,Ev);
+            }
+            0x09: decode OPCODE_OP_BOTTOM3 {
+                0x0: CMOVS(Gv,Ev);
+                0x1: CMOVNS(Gv,Ev);
+                0x2: CMOVP(Gv,Ev);
+                0x3: CMOVNP(Gv,Ev);
+                0x4: CMOVL(Gv,Ev);
+                0x5: CMOVNL(Gv,Ev);
+                0x6: CMOVLE(Gv,Ev);
+                0x7: CMOVNLE(Gv,Ev);
+            }
+            0x0A: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVMSKPS(Gd,VRo);
+                    0x1: SQRTPS(Vo,Wo);
+                    0x2: WarnUnimpl::rqsrtps_Vo_Wo();
+                    0x3: WarnUnimpl::rcpps_Vo_Wo();
+                    0x4: ANDPS(Vo,Wo);
+                    0x5: ANDNPS(Vo,Wo);
+                    0x6: ORPS(Vo,Wo);
+                    0x7: XORPS(Vo,Wo);
+                }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x1: SQRTSS(Vd,Wd);
+                    0x2: WarnUnimpl::rsqrtss_Vd_Wd();
+                    0x3: WarnUnimpl::rcpss_Vd_Wd();
+                    default: UD2();
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: MOVMSKPD(Gd,VRo);
+                    0x1: SQRTPD(Vo,Wo);
+                    0x4: ANDPD(Vo,Wo);
+                    0x5: ANDNPD(Vo,Wo);
+                    0x6: ORPD(Vo,Wo);
+                    0x7: XORPD(Vo,Wo);
+                    default: UD2();
+                }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x1: SQRTSD(Vq,Wq);
+                    default: UD2();
+                }
                 default: UD2();
             }
-            format Inst {
-                0x08: decode OPCODE_OP_BOTTOM3 {
-                    0x0: CMOVO(Gv,Ev);
-                    0x1: CMOVNO(Gv,Ev);
-                    0x2: CMOVB(Gv,Ev);
-                    0x3: CMOVNB(Gv,Ev);
-                    0x4: CMOVZ(Gv,Ev);
-                    0x5: CMOVNZ(Gv,Ev);
-                    0x6: CMOVBE(Gv,Ev);
-                    0x7: CMOVNBE(Gv,Ev);
+            0x0B: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: ADDPS(Vo,Wo);
+                    0x1: MULPS(Vo,Wo);
+                    0x2: CVTPS2PD(Vo,Wq);
+                    0x3: CVTDQ2PS(Vo,Wo);
+                    0x4: SUBPS(Vo,Wo);
+                    0x5: MINPS(Vo,Wo);
+                    0x6: DIVPS(Vo,Wo);
+                    0x7: MAXPS(Vo,Wo);
                 }
-                0x09: decode OPCODE_OP_BOTTOM3 {
-                    0x0: CMOVS(Gv,Ev);
-                    0x1: CMOVNS(Gv,Ev);
-                    0x2: CMOVP(Gv,Ev);
-                    0x3: CMOVNP(Gv,Ev);
-                    0x4: CMOVL(Gv,Ev);
-                    0x5: CMOVNL(Gv,Ev);
-                    0x6: CMOVLE(Gv,Ev);
-                    0x7: CMOVNLE(Gv,Ev);
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x0: ADDSS(Vd,Wd);
+                    0x1: MULSS(Vd,Wd);
+                    0x2: CVTSS2SD(Vq,Wd);
+                    0x3: CVTTPS2DQ(Vo,Wo);
+                    0x4: SUBSS(Vd,Wd);
+                    0x5: MINSS(Vd,Wd);
+                    0x6: DIVSS(Vd,Wd);
+                    0x7: MAXSS(Vd,Wd);
                 }
-                0x0A: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVMSKPS(Gd,VRo);
-                        0x1: SQRTPS(Vo,Wo);
-                        0x2: WarnUnimpl::rqsrtps_Vo_Wo();
-                        0x3: WarnUnimpl::rcpps_Vo_Wo();
-                        0x4: ANDPS(Vo,Wo);
-                        0x5: ANDNPS(Vo,Wo);
-                        0x6: ORPS(Vo,Wo);
-                        0x7: XORPS(Vo,Wo);
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x1: SQRTSS(Vd,Wd);
-                        0x2: WarnUnimpl::rsqrtss_Vd_Wd();
-                        0x3: WarnUnimpl::rcpss_Vd_Wd();
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: MOVMSKPD(Gd,VRo);
-                        0x1: SQRTPD(Vo,Wo);
-                        0x4: ANDPD(Vo,Wo);
-                        0x5: ANDNPD(Vo,Wo);
-                        0x6: ORPD(Vo,Wo);
-                        0x7: XORPD(Vo,Wo);
-                        default: UD2();
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x1: SQRTSD(Vq,Wq);
-                        default: UD2();
-                    }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: ADDPD(Vo,Wo);
+                    0x1: MULPD(Vo,Wo);
+                    0x2: CVTPD2PS(Vo,Wo);
+                    0x3: CVTPS2DQ(Vo,Wo);
+                    0x4: SUBPD(Vo,Wo);
+                    0x5: MINPD(Vo,Wo);
+                    0x6: DIVPD(Vo,Wo);
+                    0x7: MAXPD(Vo,Wo);
+                }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x0: ADDSD(Vq,Wq);
+                    0x1: MULSD(Vq,Wq);
+                    0x2: CVTSD2SS(Vd,Wq);
+                    0x4: SUBSD(Vq,Wq);
+                    0x5: MINSD(Vq,Wq);
+                    0x6: DIVSD(Vq,Wq);
+                    0x7: MAXSD(Vq,Wq);
                     default: UD2();
                 }
-                0x0B: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: ADDPS(Vo,Wo);
-                        0x1: MULPS(Vo,Wo);
-                        0x2: CVTPS2PD(Vo,Wq);
-                        0x3: CVTDQ2PS(Vo,Wo);
-                        0x4: SUBPS(Vo,Wo);
-                        0x5: MINPS(Vo,Wo);
-                        0x6: DIVPS(Vo,Wo);
-                        0x7: MAXPS(Vo,Wo);
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x0: ADDSS(Vd,Wd);
-                        0x1: MULSS(Vd,Wd);
-                        0x2: CVTSS2SD(Vq,Wd);
-                        0x3: CVTTPS2DQ(Vo,Wo);
-                        0x4: SUBSS(Vd,Wd);
-                        0x5: MINSS(Vd,Wd);
-                        0x6: DIVSS(Vd,Wd);
-                        0x7: MAXSS(Vd,Wd);
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: ADDPD(Vo,Wo);
-                        0x1: MULPD(Vo,Wo);
-                        0x2: CVTPD2PS(Vo,Wo);
-                        0x3: CVTPS2DQ(Vo,Wo);
-                        0x4: SUBPD(Vo,Wo);
-                        0x5: MINPD(Vo,Wo);
-                        0x6: DIVPD(Vo,Wo);
-                        0x7: MAXPD(Vo,Wo);
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x0: ADDSD(Vq,Wq);
-                        0x1: MULSD(Vq,Wq);
-                        0x2: CVTSD2SS(Vd,Wq);
-                        0x4: SUBSD(Vq,Wq);
-                        0x5: MINSD(Vq,Wq);
-                        0x6: DIVSD(Vq,Wq);
-                        0x7: MAXSD(Vq,Wq);
-                        default: UD2();
-                    }
+                default: UD2();
+            }
+            0x0C: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PUNPCKLBW(Pq,Qd);
+                    0x1: PUNPCKLWD(Pq,Qd);
+                    0x2: PUNPCKLDQ(Pq,Qd);
+                    0x3: PACKSSWB(Pq,Qq);
+                    0x4: PCMPGTB(Pq,Qq);
+                    0x5: PCMPGTW(Pq,Qq);
+                    0x6: PCMPGTD(Pq,Qq);
+                    0x7: PACKUSWB(Pq,Qq);
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PUNPCKLBW(Vo,Wq);
+                    0x1: PUNPCKLWD(Vo,Wq);
+                    0x2: PUNPCKLDQ(Vo,Wq);
+                    0x3: PACKSSWB(Vo,Wo);
+                    0x4: PCMPGTB(Vo,Wo);
+                    0x5: PCMPGTW(Vo,Wo);
+                    0x6: PCMPGTD(Vo,Wo);
+                    0x7: PACKUSWB(Vo,Wo);
+                }
+                default: UD2();
+            }
+            0x0D: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PUNPCKHBW(Pq,Qq);
+                    0x1: PUNPCKHWD(Pq,Qq);
+                    0x2: PUNPCKHDQ(Pq,Qq);
+                    0x3: PACKSSDW(Pq,Qq);
+                    0x6: MOVD(Pq,Edp);
+                    0x7: MOVQ(Pq,Qq);
                     default: UD2();
                 }
-                0x0C: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PUNPCKLBW(Pq,Qd);
-                        0x1: PUNPCKLWD(Pq,Qd);
-                        0x2: PUNPCKLDQ(Pq,Qd);
-                        0x3: PACKSSWB(Pq,Qq);
-                        0x4: PCMPGTB(Pq,Qq);
-                        0x5: PCMPGTW(Pq,Qq);
-                        0x6: PCMPGTD(Pq,Qq);
-                        0x7: PACKUSWB(Pq,Qq);
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PUNPCKLBW(Vo,Wq);
-                        0x1: PUNPCKLWD(Vo,Wq);
-                        0x2: PUNPCKLDQ(Vo,Wq);
-                        0x3: PACKSSWB(Vo,Wo);
-                        0x4: PCMPGTB(Vo,Wo);
-                        0x5: PCMPGTW(Vo,Wo);
-                        0x6: PCMPGTD(Vo,Wo);
-                        0x7: PACKUSWB(Vo,Wo);
-                    }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x7: MOVDQU(Vo,Wo);
                     default: UD2();
                 }
-                0x0D: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PUNPCKHBW(Pq,Qq);
-                        0x1: PUNPCKHWD(Pq,Qq);
-                        0x2: PUNPCKHDQ(Pq,Qq);
-                        0x3: PACKSSDW(Pq,Qq);
-                        0x6: MOVD(Pq,Edp);
-                        0x7: MOVQ(Pq,Qq);
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PUNPCKHBW(Vo,Wo);
+                    0x1: PUNPCKHWD(Vo,Wo);
+                    0x2: PUNPCKHDQ(Vo,Wo);
+                    0x3: PACKSSDW(Vo,Wo);
+                    0x4: PUNPCKLQDQ(Vo,Wq);
+                    0x5: PUNPCKHQDQ(Vo,Wq);
+                    0x6: MOVD(Vo,Edp);
+                    0x7: MOVDQA(Vo,Wo);
+                }
+                default: UD2();
+            }
+            0x0E: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSHUFW(Pq,Qq,Ib);
+                    //0x1: group12_pshimw();
+                    0x1: decode MODRM_REG {
+                        0x2: PSRLW(PRq,Ib);
+                        0x4: PSRAW(PRq,Ib);
+                        0x6: PSLLW(PRq,Ib);
                         default: UD2();
                     }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x7: MOVDQU(Vo,Wo);
+                    //0x2: group13_pshimd();
+                    0x2: decode MODRM_REG {
+                        0x2: PSRLD(PRq,Ib);
+                        0x4: PSRAD(PRq,Ib);
+                        0x6: PSLLD(PRq,Ib);
                         default: UD2();
                     }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PUNPCKHBW(Vo,Wo);
-                        0x1: PUNPCKHWD(Vo,Wo);
-                        0x2: PUNPCKHDQ(Vo,Wo);
-                        0x3: PACKSSDW(Vo,Wo);
-                        0x4: PUNPCKLQDQ(Vo,Wq);
-                        0x5: PUNPCKHQDQ(Vo,Wq);
-                        0x6: MOVD(Vo,Edp);
-                        0x7: MOVDQA(Vo,Wo);
+                    //0x3: group14_pshimq();
+                    0x3: decode MODRM_REG {
+                        0x2: PSRLQ(PRq,Ib);
+                        0x6: PSLLQ(PRq,Ib);
+                        default: Inst::UD2();
                     }
+                    0x4: Inst::PCMPEQB(Pq,Qq);
+                    0x5: Inst::PCMPEQW(Pq,Qq);
+                    0x6: Inst::PCMPEQD(Pq,Qq);
+                    0x7: Inst::EMMS();
+                }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSHUFHW(Vo,Wo,Ib);
                     default: UD2();
                 }
-                0x0E: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSHUFW(Pq,Qq,Ib);
-                        //0x1: group12_pshimw();
-                        0x1: decode MODRM_REG {
-                            0x2: PSRLW(PRq,Ib);
-                            0x4: PSRAW(PRq,Ib);
-                            0x6: PSLLW(PRq,Ib);
-                            default: UD2();
-                        }
-                        //0x2: group13_pshimd();
-                        0x2: decode MODRM_REG {
-                            0x2: PSRLD(PRq,Ib);
-                            0x4: PSRAD(PRq,Ib);
-                            0x6: PSLLD(PRq,Ib);
-                            default: UD2();
-                        }
-                        //0x3: group14_pshimq();
-                        0x3: decode MODRM_REG {
-                            0x2: PSRLQ(PRq,Ib);
-                            0x6: PSLLQ(PRq,Ib);
-                            default: Inst::UD2();
-                        }
-                        0x4: Inst::PCMPEQB(Pq,Qq);
-                        0x5: Inst::PCMPEQW(Pq,Qq);
-                        0x6: Inst::PCMPEQD(Pq,Qq);
-                        0x7: Inst::EMMS();
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSHUFHW(Vo,Wo,Ib);
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSHUFD(Vo,Wo,Ib);
-                        //0x1: group12_pshimw();
-                        0x1: decode MODRM_REG {
-                            0x2: PSRLW(VRo,Ib);
-                            0x4: PSRAW(VRo,Ib);
-                            0x6: PSLLW(VRo,Ib);
-                        }
-                        //0x2: group13_pshimd();
-                        0x2: decode MODRM_REG {
-                            0x2: PSRLD(VRo,Ib);
-                            0x4: PSRAD(VRo,Ib);
-                            0x6: PSLLD(VRo,Ib);
-                            default: UD2();
-                        }
-                        //0x3: group14_pshimq();
-                        0x3: decode MODRM_REG {
-                            0x2: PSRLQ(VRo,Ib);
-                            0x3: PSRLDQ(VRo,Ib);
-                            0x6: PSLLQ(VRo,Ib);
-                            0x7: PSLLDQ(VRo,Ib);
-                            default: UD2();
-                        }
-                        0x4: PCMPEQB(Vo,Wo);
-                        0x5: PCMPEQW(Vo,Wo);
-                        0x6: PCMPEQD(Vo,Wo);
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSHUFD(Vo,Wo,Ib);
+                    //0x1: group12_pshimw();
+                    0x1: decode MODRM_REG {
+                        0x2: PSRLW(VRo,Ib);
+                        0x4: PSRAW(VRo,Ib);
+                        0x6: PSLLW(VRo,Ib);
+                    }
+                    //0x2: group13_pshimd();
+                    0x2: decode MODRM_REG {
+                        0x2: PSRLD(VRo,Ib);
+                        0x4: PSRAD(VRo,Ib);
+                        0x6: PSLLD(VRo,Ib);
                         default: UD2();
                     }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSHUFLW(Vo,Wo,Ib);
+                    //0x3: group14_pshimq();
+                    0x3: decode MODRM_REG {
+                        0x2: PSRLQ(VRo,Ib);
+                        0x3: PSRLDQ(VRo,Ib);
+                        0x6: PSLLQ(VRo,Ib);
+                        0x7: PSLLDQ(VRo,Ib);
                         default: UD2();
                     }
+                    0x4: PCMPEQB(Vo,Wo);
+                    0x5: PCMPEQW(Vo,Wo);
+                    0x6: PCMPEQD(Vo,Wo);
                     default: UD2();
                 }
-                0x0F: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: WarnUnimpl::vmread_Edp_Gdp();
-                        0x1: WarnUnimpl::vmwrite_Gdp_Edp();
-                        0x6: MOVD(Edp,Pdp);
-                        0x7: MOVQ(Qq,Pq);
-                        default: UD2();
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x6: MOVQ(Vq,Wq);
-                        0x7: MOVDQU(Wo,Vo);
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x4: HADDPD(Vo,Wo);
-                        0x5: WarnUnimpl::hsubpd_Vo_Wo();
-                        0x6: MOVD(Edp,Vd);
-                        0x7: MOVDQA(Wo,Vo);
-                        default: UD2();
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x4: HADDPS(Vo,Wo);
-                        0x5: WarnUnimpl::hsubps_Vo_Wo();
-                        default: UD2();
-                    }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSHUFLW(Vo,Wo,Ib);
                     default: UD2();
                 }
-                0x10: decode OPCODE_OP_BOTTOM3 {
-                    0x0: JO(Jz);
-                    0x1: JNO(Jz);
-                    0x2: JB(Jz);
-                    0x3: JNB(Jz);
-                    0x4: JZ(Jz);
-                    0x5: JNZ(Jz);
-                    0x6: JBE(Jz);
-                    0x7: JNBE(Jz);
+                default: UD2();
+            }
+            0x0F: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: WarnUnimpl::vmread_Edp_Gdp();
+                    0x1: WarnUnimpl::vmwrite_Gdp_Edp();
+                    0x6: MOVD(Edp,Pdp);
+                    0x7: MOVQ(Qq,Pq);
+                    default: UD2();
                 }
-                0x11: decode OPCODE_OP_BOTTOM3 {
-                    0x0: JS(Jz);
-                    0x1: JNS(Jz);
-                    0x2: JP(Jz);
-                    0x3: JNP(Jz);
-                    0x4: JL(Jz);
-                    0x5: JNL(Jz);
-                    0x6: JLE(Jz);
-                    0x7: JNLE(Jz);
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x6: MOVQ(Vq,Wq);
+                    0x7: MOVDQU(Wo,Vo);
+                    default: UD2();
                 }
-                0x12: decode OPCODE_OP_BOTTOM3 {
-                    0x0: SETO(Eb);
-                    0x1: SETNO(Eb);
-                    0x2: SETB(Eb);
-                    0x3: SETNB(Eb);
-                    0x4: SETZ(Eb);
-                    0x5: SETNZ(Eb);
-                    0x6: SETBE(Eb);
-                    0x7: SETNBE(Eb);
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x4: HADDPD(Vo,Wo);
+                    0x5: WarnUnimpl::hsubpd_Vo_Wo();
+                    0x6: MOVD(Edp,Vd);
+                    0x7: MOVDQA(Wo,Vo);
+                    default: UD2();
                 }
-                0x13: decode OPCODE_OP_BOTTOM3 {
-                    0x0: SETS(Eb);
-                    0x1: SETNS(Eb);
-                    0x2: SETP(Eb);
-                    0x3: SETNP(Eb);
-                    0x4: SETL(Eb);
-                    0x5: SETNL(Eb);
-                    0x6: SETLE(Eb);
-                    0x7: SETNLE(Eb);
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x4: HADDPS(Vo,Wo);
+                    0x5: WarnUnimpl::hsubps_Vo_Wo();
+                    default: UD2();
                 }
+                default: UD2();
             }
-            0x14: decode OPCODE_OP_BOTTOM3 {
-                0x0: push_fs();
-                0x1: pop_fs();
-                0x2: CPUIDInst::CPUID({{
-                    CpuidResult result;
-                    bool success = doCpuid(xc->tcBase(), bits(Rax, 31, 0),
-                        bits(Rcx, 31, 0), result);
-                    if (success) {
-                        Rax = result.rax;
-                        Rbx = result.rbx;
-                        Rcx = result.rcx;
-                        Rdx = result.rdx;
-                    } else {
-                        Rax = Rax;
-                        Rbx = Rbx;
-                        Rcx = Rcx;
-                        Rdx = Rdx;
-                    }
-                    }});
-                0x3: Inst::BT(Ev,Gv);
-                0x4: Inst::SHLD(Ev,Gv,Ib);
-                0x5: Inst::SHLD(Ev,Gv);
-                default: Inst::UD2();
+            0x10: decode OPCODE_OP_BOTTOM3 {
+                0x0: JO(Jz);
+                0x1: JNO(Jz);
+                0x2: JB(Jz);
+                0x3: JNB(Jz);
+                0x4: JZ(Jz);
+                0x5: JNZ(Jz);
+                0x6: JBE(Jz);
+                0x7: JNBE(Jz);
             }
-            0x15: decode OPCODE_OP_BOTTOM3 {
-                0x0: push_gs();
-                0x1: pop_gs();
-                0x2: rsm_smm();
-                0x3: Inst::BTS(Ev,Gv);
-                0x4: Inst::SHRD(Ev,Gv,Ib);
-                0x5: Inst::SHRD(Ev,Gv);
-                //0x6: group15();
-                0x6: decode MODRM_MOD {
-                    0x3: decode MODRM_REG {
-                        0x5: BasicOperate::LFENCE(
-                                     {{/*Nothing*/}}, IsReadBarrier);
-                        0x6: BasicOperate::MFENCE(
-                                     {{/*Nothing*/}}, IsMemBarrier);
-                        0x7: BasicOperate::SFENCE(
-                                     {{/*Nothing*/}}, IsWriteBarrier);
-                        default: Inst::UD2();
-                    }
-                    default: decode MODRM_REG {
-                        0x0: decode OPSIZE {
-                            4: Inst::FXSAVE(M);
-                            8: Inst::FXSAVE64(M);
-                            default: fxsave();
-                        }
-                        0x1: decode OPSIZE {
-                            4: Inst::FXRSTOR(M);
-                            8: Inst::FXRSTOR64(M);
-                            default: fxrstor();
-                        }
-                        0x2: Inst::LDMXCSR(Md);
-                        0x3: Inst::STMXCSR(Md);
-                        0x4: xsave();
-                        0x5: xrstor();
-                        0x6: Inst::UD2();
-                        0x7: clflush();
-                    }
+            0x11: decode OPCODE_OP_BOTTOM3 {
+                0x0: JS(Jz);
+                0x1: JNS(Jz);
+                0x2: JP(Jz);
+                0x3: JNP(Jz);
+                0x4: JL(Jz);
+                0x5: JNL(Jz);
+                0x6: JLE(Jz);
+                0x7: JNLE(Jz);
+            }
+            0x12: decode OPCODE_OP_BOTTOM3 {
+                0x0: SETO(Eb);
+                0x1: SETNO(Eb);
+                0x2: SETB(Eb);
+                0x3: SETNB(Eb);
+                0x4: SETZ(Eb);
+                0x5: SETNZ(Eb);
+                0x6: SETBE(Eb);
+                0x7: SETNBE(Eb);
+            }
+            0x13: decode OPCODE_OP_BOTTOM3 {
+                0x0: SETS(Eb);
+                0x1: SETNS(Eb);
+                0x2: SETP(Eb);
+                0x3: SETNP(Eb);
+                0x4: SETL(Eb);
+                0x5: SETNL(Eb);
+                0x6: SETLE(Eb);
+                0x7: SETNLE(Eb);
+            }
+        }
+        0x14: decode OPCODE_OP_BOTTOM3 {
+            0x0: push_fs();
+            0x1: pop_fs();
+            0x2: CPUIDInst::CPUID({{
+                CpuidResult result;
+                bool success = doCpuid(xc->tcBase(), bits(Rax, 31, 0),
+                    bits(Rcx, 31, 0), result);
+                if (success) {
+                    Rax = result.rax;
+                    Rbx = result.rbx;
+                    Rcx = result.rcx;
+                    Rdx = result.rdx;
+                } else {
+                    Rax = Rax;
+                    Rbx = Rbx;
+                    Rcx = Rcx;
+                    Rdx = Rdx;
+                }
+                }});
+            0x3: Inst::BT(Ev,Gv);
+            0x4: Inst::SHLD(Ev,Gv,Ib);
+            0x5: Inst::SHLD(Ev,Gv);
+            default: Inst::UD2();
+        }
+        0x15: decode OPCODE_OP_BOTTOM3 {
+            0x0: push_gs();
+            0x1: pop_gs();
+            0x2: rsm_smm();
+            0x3: Inst::BTS(Ev,Gv);
+            0x4: Inst::SHRD(Ev,Gv,Ib);
+            0x5: Inst::SHRD(Ev,Gv);
+            //0x6: group15();
+            0x6: decode MODRM_MOD {
+                0x3: decode MODRM_REG {
+                    0x5: BasicOperate::LFENCE(
+                                 {{/*Nothing*/}}, IsReadBarrier);
+                    0x6: BasicOperate::MFENCE(
+                                 {{/*Nothing*/}}, IsMemBarrier);
+                    0x7: BasicOperate::SFENCE(
+                                 {{/*Nothing*/}}, IsWriteBarrier);
+                    default: Inst::UD2();
+                }
+                default: decode MODRM_REG {
+                    0x0: decode OPSIZE {
+                        4: Inst::FXSAVE(M);
+                        8: Inst::FXSAVE64(M);
+                        default: fxsave();
+                    }
+                    0x1: decode OPSIZE {
+                        4: Inst::FXRSTOR(M);
+                        8: Inst::FXRSTOR64(M);
+                        default: fxrstor();
+                    }
+                    0x2: Inst::LDMXCSR(Md);
+                    0x3: Inst::STMXCSR(Md);
+                    0x4: xsave();
+                    0x5: xrstor();
+                    0x6: Inst::UD2();
+                    0x7: clflush();
                 }
-                0x7: Inst::IMUL(Gv,Ev);
             }
-            format Inst {
-                0x16: decode OPCODE_OP_BOTTOM3 {
-                    0x0: CMPXCHG(Eb,Gb);
-                    0x1: CMPXCHG(Ev,Gv);
-                    0x2: WarnUnimpl::lss_Gz_Mp();
-                    0x3: BTR(Ev,Gv);
-                    0x4: WarnUnimpl::lfs_Gz_Mp();
-                    0x5: WarnUnimpl::lgs_Gz_Mp();
-                    //The size of the second operand in these instructions
-                    //should really be "b" or "w", but it's set to v in order
-                    //to have a consistent register size. This shouldn't
-                    //affect behavior.
-                    0x6: MOVZX_B(Gv,Ev);
-                    0x7: MOVZX_W(Gv,Ev);
+            0x7: Inst::IMUL(Gv,Ev);
+        }
+        format Inst {
+            0x16: decode OPCODE_OP_BOTTOM3 {
+                0x0: CMPXCHG(Eb,Gb);
+                0x1: CMPXCHG(Ev,Gv);
+                0x2: WarnUnimpl::lss_Gz_Mp();
+                0x3: BTR(Ev,Gv);
+                0x4: WarnUnimpl::lfs_Gz_Mp();
+                0x5: WarnUnimpl::lgs_Gz_Mp();
+                //The size of the second operand in these instructions
+                //should really be "b" or "w", but it's set to v in order
+                //to have a consistent register size. This shouldn't
+                //affect behavior.
+                0x6: MOVZX_B(Gv,Ev);
+                0x7: MOVZX_W(Gv,Ev);
+            }
+            0x17: decode OPCODE_OP_BOTTOM3 {
+                0x0: decode LEGACY_REP {
+                    0x0: WarnUnimpl::jmpe_Jz();
+                    0x1: WarnUnimpl::popcnt_Gv_Ev();
                 }
-                0x17: decode OPCODE_OP_BOTTOM3 {
-                    0x0: decode LEGACY_REP {
-                        0x0: WarnUnimpl::jmpe_Jz();
-                        0x1: WarnUnimpl::popcnt_Gv_Ev();
-                    }
-                    //0x1: group10_UD2();
-                    0x1: UD2();
-                    //0x2: group8_Ev_Ib();
-                    0x2: decode MODRM_REG {
-                        0x4: BT(Ev,Ib);
-                        0x5: BTS(Ev,Ib);
-                        0x6: BTR(Ev,Ib);
-                        0x7: BTC(Ev,Ib);
-                        default: UD2();
-                    }
-                    0x3: BTC(Ev,Gv);
-                    0x4: BSF(Gv,Ev);
-                    0x5: BSR(Gv,Ev);
-                    //The size of the second operand in these instructions
-                    //should really be "b" or "w", but it's set to v in order
-                    //to have a consistent register size. This shouldn't
-                    //affect behavior.
-                    0x6: MOVSX_B(Gv,Ev);
-                    0x7: MOVSX_W(Gv,Ev);
+                //0x1: group10_UD2();
+                0x1: UD2();
+                //0x2: group8_Ev_Ib();
+                0x2: decode MODRM_REG {
+                    0x4: BT(Ev,Ib);
+                    0x5: BTS(Ev,Ib);
+                    0x6: BTR(Ev,Ib);
+                    0x7: BTC(Ev,Ib);
+                    default: UD2();
                 }
-                0x18: decode OPCODE_OP_BOTTOM3 {
-                    0x0: XADD(Eb,Gb);
-                    0x1: XADD(Ev,Gv);
-                    //0x7: group9();
-                    0x7: decode MODRM_REG {
-                        //Also CMPXCHG16B
-                        0x1: CMPXCHG8B(Mdp);
-                        0x6: decode LEGACY_OP {
-                            0x1: WarnUnimpl::vmclear_Mq();
-                            default: decode LEGACY_REP {
-                                0x1: WarnUnimpl::vmxon_Mq();
-                                0x0: WarnUnimpl::vmptrld_Mq();
-                            }
-                        }
-                        0x7: WarnUnimpl::vmptrst_Mq();
-                        default: UD2();
-                    }
-                    default: decode LEGACY_DECODEVAL {
-                        // no prefix
-                        0x0: decode OPCODE_OP_BOTTOM3 {
-                            0x2: CMPPS(Vo,Wo,Ib);
-                            0x3: MOVNTI(Mdp,Gdp);
-                            0x4: PINSRW(Pq,Ew,Ib);
-                            0x5: PEXTRW(Gd,PRq,Ib);
-                            0x6: SHUFPS(Vps,Wps,Ib);
-                        }
-                        // repe (0xF3)
-                        0x4: decode OPCODE_OP_BOTTOM3 {
-                            0x2: CMPSS(Vd,Wd,Ib);
-                            default: UD2();
-                        }
-                        // operand size (0x66)
-                        0x1: decode OPCODE_OP_BOTTOM3 {
-                            0x2: CMPPD(Vo,Wo,Ib);
-                            0x4: PINSRW(Vdw,Ew,Ib);
-                            0x5: PEXTRW(Gd,VRdq,Ib);
-                            0x6: SHUFPD(Vpd,Wpd,Ib);
-                            default: UD2();
-                        }
-                        // repne (0xF2)
-                        0x8: decode OPCODE_OP_BOTTOM3 {
-                            0x2: CMPSD(Vq,Wq,Ib);
-                            default: UD2();
+                0x3: BTC(Ev,Gv);
+                0x4: BSF(Gv,Ev);
+                0x5: BSR(Gv,Ev);
+                //The size of the second operand in these instructions
+                //should really be "b" or "w", but it's set to v in order
+                //to have a consistent register size. This shouldn't
+                //affect behavior.
+                0x6: MOVSX_B(Gv,Ev);
+                0x7: MOVSX_W(Gv,Ev);
+            }
+            0x18: decode OPCODE_OP_BOTTOM3 {
+                0x0: XADD(Eb,Gb);
+                0x1: XADD(Ev,Gv);
+                //0x7: group9();
+                0x7: decode MODRM_REG {
+                    //Also CMPXCHG16B
+                    0x1: CMPXCHG8B(Mdp);
+                    0x6: decode LEGACY_OP {
+                        0x1: WarnUnimpl::vmclear_Mq();
+                        default: decode LEGACY_REP {
+                            0x1: WarnUnimpl::vmxon_Mq();
+                            0x0: WarnUnimpl::vmptrld_Mq();
                         }
-                        default: UD2();
                     }
-                }
-                0x19: decode OPSIZE {
-                    4: BSWAP_D(Bd);
-                    8: BSWAP_Q(Bq);
+                    0x7: WarnUnimpl::vmptrst_Mq();
                     default: UD2();
                 }
-                0x1A: decode LEGACY_DECODEVAL {
+                default: decode LEGACY_DECODEVAL {
                     // no prefix
                     0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x1: PSRLW(Pq,Qq);
-                        0x2: PSRLD(Pq,Qq);
-                        0x3: PSRLQ(Pq,Qq);
-                        0x4: PADDQ(Pq,Qq);
-                        0x5: PMULLW(Pq,Qq);
-                        0x7: PMOVMSKB(Gd,PRq);
-                        default: UD2();
+                        0x2: CMPPS(Vo,Wo,Ib);
+                        0x3: MOVNTI(Mdp,Gdp);
+                        0x4: PINSRW(Pq,Ew,Ib);
+                        0x5: PEXTRW(Gd,PRq,Ib);
+                        0x6: SHUFPS(Vps,Wps,Ib);
                     }
                     // repe (0xF3)
                     0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x6: MOVQ2DQ(Vo,PRq);
+                        0x2: CMPSS(Vd,Wd,Ib);
                         default: UD2();
                     }
                     // operand size (0x66)
                     0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: WarnUnimpl::addsubpd_Vo_Wo();
-                        0x1: PSRLW(Vo,Wo);
-                        0x2: PSRLD(Vo,Wo);
-                        0x3: PSRLQ(Vo,Wo);
-                        0x4: PADDQ(Vo,Wo);
-                        0x5: PMULLW(Vo,Wo);
-                        0x6: MOVQ(Wq,Vq);
-                        0x7: PMOVMSKB(Gd,VRo);
+                        0x2: CMPPD(Vo,Wo,Ib);
+                        0x4: PINSRW(Vdw,Ew,Ib);
+                        0x5: PEXTRW(Gd,VRdq,Ib);
+                        0x6: SHUFPD(Vpd,Wpd,Ib);
+                        default: UD2();
                     }
                     // repne (0xF2)
                     0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x0: WarnUnimpl::addsubps_Vo_Wo();
-                        0x6: MOVDQ2Q(Pq,VRq);
+                        0x2: CMPSD(Vq,Wq,Ib);
                         default: UD2();
                     }
                     default: UD2();
                 }
-                0x1B: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBUSB(Pq,Qq);
-                        0x1: PSUBUSW(Pq,Qq);
-                        0x2: PMINUB(Pq,Qq);
-                        0x3: PAND(Pq,Qq);
-                        0x4: PADDUSB(Pq,Qq);
-                        0x5: PADDUSW(Pq,Qq);
-                        0x6: PMAXUB(Pq,Qq);
-                        0x7: PANDN(Pq,Qq);
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBUSB(Vo,Wo);
-                        0x1: PSUBUSW(Vo,Wo);
-                        0x2: PMINUB(Vo,Wo);
-                        0x3: PAND(Vo,Wo);
-                        0x4: PADDUSB(Vo,Wo);
-                        0x5: PADDUSW(Vo,Wo);
-                        0x6: PMAXUB(Vo,Wo);
-                        0x7: PANDN(Vo,Wo);
-                    }
+            }
+            0x19: decode OPSIZE {
+                4: BSWAP_D(Bd);
+                8: BSWAP_Q(Bq);
+                default: UD2();
+            }
+            0x1A: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x1: PSRLW(Pq,Qq);
+                    0x2: PSRLD(Pq,Qq);
+                    0x3: PSRLQ(Pq,Qq);
+                    0x4: PADDQ(Pq,Qq);
+                    0x5: PMULLW(Pq,Qq);
+                    0x7: PMOVMSKB(Gd,PRq);
                     default: UD2();
                 }
-                0x1C: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PAVGB(Pq,Qq);
-                        0x1: PSRAW(Pq,Qq);
-                        0x2: PSRAD(Pq,Qq);
-                        0x3: PAVGW(Pq,Qq);
-                        0x4: PMULHUW(Pq,Qq);
-                        0x5: PMULHW(Pq,Qq);
-                        0x7: WarnUnimpl::movntq_Mq_Pq();
-                        default: UD2();
-                    }
-                    // repe (0xF3)
-                    0x4: decode OPCODE_OP_BOTTOM3 {
-                        0x6: CVTDQ2PD(Vo,Wq);
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PAVGB(Vo,Wo);
-                        0x1: PSRAW(Vo,Wo);
-                        0x2: PSRAD(Vo,Wo);
-                        0x3: PAVGW(Vo,Wo);
-                        0x4: PMULHUW(Vo,Wo);
-                        0x5: PMULHW(Vo,Wo);
-                        0x6: CVTTPD2DQ(Vo,Wo);
-                        0x7: WarnUnimpl::movntdq_Mo_Vo();
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x6: CVTPD2DQ(Vo,Wo);
-                        default: UD2();
-                    }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x6: MOVQ2DQ(Vo,PRq);
                     default: UD2();
                 }
-                0x1D: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBSB(Pq,Qq);
-                        0x1: PSUBSW(Pq,Qq);
-                        0x2: PMINSW(Pq,Qq);
-                        0x3: POR(Pq,Qq);
-                        0x4: PADDSB(Pq,Qq);
-                        0x5: PADDSW(Pq,Qq);
-                        0x6: PMAXSW(Pq,Qq);
-                        0x7: PXOR(Pq,Qq);
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBSB(Vo,Wo);
-                        0x1: PSUBSW(Vo,Wo);
-                        0x2: PMINSW(Vo,Wo);
-                        0x3: POR(Vo,Wo);
-                        0x4: PADDSB(Vo,Wo);
-                        0x5: PADDSW(Vo,Wo);
-                        0x6: PMAXSW(Vo,Wo);
-                        0x7: PXOR(Vo,Wo);
-                    }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: WarnUnimpl::addsubpd_Vo_Wo();
+                    0x1: PSRLW(Vo,Wo);
+                    0x2: PSRLD(Vo,Wo);
+                    0x3: PSRLQ(Vo,Wo);
+                    0x4: PADDQ(Vo,Wo);
+                    0x5: PMULLW(Vo,Wo);
+                    0x6: MOVQ(Wq,Vq);
+                    0x7: PMOVMSKB(Gd,VRo);
+                }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x0: WarnUnimpl::addsubps_Vo_Wo();
+                    0x6: MOVDQ2Q(Pq,VRq);
                     default: UD2();
                 }
-                0x1E: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x1: PSLLW(Pq,Qq);
-                        0x2: PSLLD(Pq,Qq);
-                        0x3: PSLLQ(Pq,Qq);
-                        0x4: PMULUDQ(Pq,Qq);
-                        0x5: PMADDWD(Pq,Qq);
-                        0x6: PSADBW(Pq,Qq);
-                        0x7: MASKMOVQ(Pq,PRq);
-                        default: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x1: PSLLW(Vo,Wo);
-                        0x2: PSLLD(Vo,Wo);
-                        0x3: PSLLQ(Vo,Wo);
-                        0x4: PMULUDQ(Vo,Wo);
-                        0x5: PMADDWD(Vo,Wo);
-                        0x6: PSADBW(Vo,Wo);
-                        0x7: MASKMOVDQU(Vo,VRo);
-                        default: UD2();
-                    }
-                    // repne (0xF2)
-                    0x8: decode OPCODE_OP_BOTTOM3 {
-                        0x0: WarnUnimpl::lddqu_Vo_Mo();
-                        default: UD2();
-                    }
+                default: UD2();
+            }
+            0x1B: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBUSB(Pq,Qq);
+                    0x1: PSUBUSW(Pq,Qq);
+                    0x2: PMINUB(Pq,Qq);
+                    0x3: PAND(Pq,Qq);
+                    0x4: PADDUSB(Pq,Qq);
+                    0x5: PADDUSW(Pq,Qq);
+                    0x6: PMAXUB(Pq,Qq);
+                    0x7: PANDN(Pq,Qq);
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBUSB(Vo,Wo);
+                    0x1: PSUBUSW(Vo,Wo);
+                    0x2: PMINUB(Vo,Wo);
+                    0x3: PAND(Vo,Wo);
+                    0x4: PADDUSB(Vo,Wo);
+                    0x5: PADDUSW(Vo,Wo);
+                    0x6: PMAXUB(Vo,Wo);
+                    0x7: PANDN(Vo,Wo);
+                }
+                default: UD2();
+            }
+            0x1C: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PAVGB(Pq,Qq);
+                    0x1: PSRAW(Pq,Qq);
+                    0x2: PSRAD(Pq,Qq);
+                    0x3: PAVGW(Pq,Qq);
+                    0x4: PMULHUW(Pq,Qq);
+                    0x5: PMULHW(Pq,Qq);
+                    0x7: WarnUnimpl::movntq_Mq_Pq();
                     default: UD2();
                 }
-                0x1F: decode LEGACY_DECODEVAL {
-                    // no prefix
-                    0x0: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBB(Pq,Qq);
-                        0x1: PSUBW(Pq,Qq);
-                        0x2: PSUBD(Pq,Qq);
-                        0x3: PSUBQ(Pq,Qq);
-                        0x4: PADDB(Pq,Qq);
-                        0x5: PADDW(Pq,Qq);
-                        0x6: PADDD(Pq,Qq);
-                        0x7: UD2();
-                    }
-                    // operand size (0x66)
-                    0x1: decode OPCODE_OP_BOTTOM3 {
-                        0x0: PSUBB(Vo,Wo);
-                        0x1: PSUBW(Vo,Wo);
-                        0x2: PSUBD(Vo,Wo);
-                        0x3: PSUBQ(Vo,Wo);
-                        0x4: PADDB(Vo,Wo);
-                        0x5: PADDW(Vo,Wo);
-                        0x6: PADDD(Vo,Wo);
-                        0x7: UD2();
-                    }
+                // repe (0xF3)
+                0x4: decode OPCODE_OP_BOTTOM3 {
+                    0x6: CVTDQ2PD(Vo,Wq);
                     default: UD2();
                 }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PAVGB(Vo,Wo);
+                    0x1: PSRAW(Vo,Wo);
+                    0x2: PSRAD(Vo,Wo);
+                    0x3: PAVGW(Vo,Wo);
+                    0x4: PMULHUW(Vo,Wo);
+                    0x5: PMULHW(Vo,Wo);
+                    0x6: CVTTPD2DQ(Vo,Wo);
+                    0x7: WarnUnimpl::movntdq_Mo_Vo();
+                }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x6: CVTPD2DQ(Vo,Wo);
+                    default: UD2();
+                }
+                default: UD2();
+            }
+            0x1D: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBSB(Pq,Qq);
+                    0x1: PSUBSW(Pq,Qq);
+                    0x2: PMINSW(Pq,Qq);
+                    0x3: POR(Pq,Qq);
+                    0x4: PADDSB(Pq,Qq);
+                    0x5: PADDSW(Pq,Qq);
+                    0x6: PMAXSW(Pq,Qq);
+                    0x7: PXOR(Pq,Qq);
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBSB(Vo,Wo);
+                    0x1: PSUBSW(Vo,Wo);
+                    0x2: PMINSW(Vo,Wo);
+                    0x3: POR(Vo,Wo);
+                    0x4: PADDSB(Vo,Wo);
+                    0x5: PADDSW(Vo,Wo);
+                    0x6: PMAXSW(Vo,Wo);
+                    0x7: PXOR(Vo,Wo);
+                }
+                default: UD2();
+            }
+            0x1E: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x1: PSLLW(Pq,Qq);
+                    0x2: PSLLD(Pq,Qq);
+                    0x3: PSLLQ(Pq,Qq);
+                    0x4: PMULUDQ(Pq,Qq);
+                    0x5: PMADDWD(Pq,Qq);
+                    0x6: PSADBW(Pq,Qq);
+                    0x7: MASKMOVQ(Pq,PRq);
+                    default: UD2();
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x1: PSLLW(Vo,Wo);
+                    0x2: PSLLD(Vo,Wo);
+                    0x3: PSLLQ(Vo,Wo);
+                    0x4: PMULUDQ(Vo,Wo);
+                    0x5: PMADDWD(Vo,Wo);
+                    0x6: PSADBW(Vo,Wo);
+                    0x7: MASKMOVDQU(Vo,VRo);
+                    default: UD2();
+                }
+                // repne (0xF2)
+                0x8: decode OPCODE_OP_BOTTOM3 {
+                    0x0: WarnUnimpl::lddqu_Vo_Mo();
+                    default: UD2();
+                }
+                default: UD2();
+            }
+            0x1F: decode LEGACY_DECODEVAL {
+                // no prefix
+                0x0: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBB(Pq,Qq);
+                    0x1: PSUBW(Pq,Qq);
+                    0x2: PSUBD(Pq,Qq);
+                    0x3: PSUBQ(Pq,Qq);
+                    0x4: PADDB(Pq,Qq);
+                    0x5: PADDW(Pq,Qq);
+                    0x6: PADDD(Pq,Qq);
+                    0x7: UD2();
+                }
+                // operand size (0x66)
+                0x1: decode OPCODE_OP_BOTTOM3 {
+                    0x0: PSUBB(Vo,Wo);
+                    0x1: PSUBW(Vo,Wo);
+                    0x2: PSUBD(Vo,Wo);
+                    0x3: PSUBQ(Vo,Wo);
+                    0x4: PADDB(Vo,Wo);
+                    0x5: PADDW(Vo,Wo);
+                    0x6: PADDD(Vo,Wo);
+                    0x7: UD2();
+                }
+                default: UD2();
             }
-            default: FailUnimpl::twoByteOps();
         }
+        default: FailUnimpl::twoByteOps();
     }
-    default: M5InternalError::error(
-        {{"Unexpected first opcode byte in two byte opcode!"}});
 }
index a9e274eccb522620f23e35406e5ed98a83b6f6b0..f4fdb59e546f4b50b78e7942d791b3dce91c44bf 100644 (file)
@@ -71,7 +71,7 @@ namespace X86ISA
     const ExtMachInst NoopMachInst = {
         0x0,                            // No legacy prefixes.
         0x0,                            // No rex prefix.
-        { 1, 0x0, 0x0, 0x90 },          // One opcode byte, 0x90.
+        { OneByteOpcode, 0x90 },          // One opcode byte, 0x90.
         0x0, 0x0,                       // No modrm or sib.
         0, 0,                           // No immediate or displacement.
         8, 8, 8,                        // All sizes are 8.
index 73177f467f186af6641f0a98d804c079dc408a18..830a131e50cae10e20fb64e5da31916c91f50051 100644 (file)
@@ -43,9 +43,7 @@ paramOut(ostream &os, const string &name, ExtMachInst const &machInst)
     paramOut(os, name + ".rex", (uint8_t)machInst.rex);
 
     // Opcode
-    paramOut(os, name + ".opcode.num", machInst.opcode.num);
-    paramOut(os, name + ".opcode.prefixA", machInst.opcode.prefixA);
-    paramOut(os, name + ".opcode.prefixB", machInst.opcode.prefixB);
+    paramOut(os, name + ".opcode.type", (uint8_t)machInst.opcode.type);
     paramOut(os, name + ".opcode.op", (uint8_t)machInst.opcode.op);
 
     // Modifier bytes
@@ -79,9 +77,8 @@ paramIn(Checkpoint *cp, const string &section,
     machInst.rex = temp8;
 
     // Opcode
-    paramIn(cp, section, name + ".opcode.num", machInst.opcode.num);
-    paramIn(cp, section, name + ".opcode.prefixA", machInst.opcode.prefixA);
-    paramIn(cp, section, name + ".opcode.prefixB", machInst.opcode.prefixB);
+    paramIn(cp, section, name + ".opcode.type", temp8);
+    machInst.opcode.type = (OpcodeType)temp8;
     paramIn(cp, section, name + ".opcode.op", temp8);
     machInst.opcode.op = temp8;
 
index a604c3efc5752053d6b9d36fcc07575dcbea16e7..dd60c0aecaae0a2e35f23db7cd997fa2f59a08dc 100644 (file)
@@ -104,6 +104,33 @@ namespace X86ISA
         Bitfield<0> b;
     EndBitUnion(Rex)
 
+    enum OpcodeType {
+        BadOpcode,
+        OneByteOpcode,
+        TwoByteOpcode,
+        ThreeByte0F38Opcode,
+        ThreeByte0F3AOpcode
+    };
+
+    static inline const char *
+    opcodeTypeToStr(OpcodeType type)
+    {
+        switch (type) {
+          case BadOpcode:
+            return "bad";
+          case OneByteOpcode:
+            return "one byte";
+          case TwoByteOpcode:
+            return "two byte";
+          case ThreeByte0F38Opcode:
+            return "three byte 0f38";
+          case ThreeByte0F3AOpcode:
+            return "three byte 0f3a";
+          default:
+            return "unrecognized!";
+        }
+    }
+
     BitUnion8(Opcode)
         Bitfield<7,3> top5;
         Bitfield<2,0> bottom3;
@@ -136,16 +163,7 @@ namespace X86ISA
         //This holds all of the bytes of the opcode
         struct
         {
-            //The number of bytes in this opcode. Right now, we ignore that
-            //this can be 3 in some cases
-            uint8_t num;
-            //The first byte detected in a 2+ byte opcode. Should be 0xF0.
-            uint8_t prefixA;
-            //The second byte detected in a 3+ byte opcode. Could be 0x38-0x3F
-            //for some SSE instructions. 3dNow! instructions are handled as
-            //two byte opcodes and then split out further by the immediate
-            //byte.
-            uint8_t prefixB;
+            OpcodeType type;
             //The main opcode byte. The highest addressed byte in the opcode.
             Opcode op;
         } opcode;
@@ -173,14 +191,12 @@ namespace X86ISA
         operator << (std::ostream & os, const ExtMachInst & emi)
     {
         ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t"
-                     "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t"
-                           "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t"
+                     "op = {\n\t\ttype = %s,\n\t\top = %#x,\n\t\t},\n\t"
                      "modRM = %#x,\n\tsib = %#x,\n\t"
                      "immediate = %#x,\n\tdisplacement = %#x\n\t"
                      "dispSize = %d}\n",
                      (uint8_t)emi.legacy, (uint8_t)emi.rex,
-                     emi.opcode.num, (uint8_t)emi.opcode.op,
-                     emi.opcode.prefixA, emi.opcode.prefixB,
+                     opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op,
                      (uint8_t)emi.modRM, (uint8_t)emi.sib,
                      emi.immediate, emi.displacement, emi.dispSize);
         return os;
@@ -193,14 +209,10 @@ namespace X86ISA
             return false;
         if(emi1.rex != emi2.rex)
             return false;
-        if(emi1.opcode.num != emi2.opcode.num)
+        if(emi1.opcode.type != emi2.opcode.type)
             return false;
         if(emi1.opcode.op != emi2.opcode.op)
             return false;
-        if(emi1.opcode.prefixA != emi2.opcode.prefixA)
-            return false;
-        if(emi1.opcode.prefixB != emi2.opcode.prefixB)
-            return false;
         if(emi1.modRM != emi2.modRM)
             return false;
         if(emi1.sib != emi2.sib)
@@ -284,13 +296,11 @@ __hash_namespace_begin
     template<>
     struct hash<X86ISA::ExtMachInst> {
         size_t operator()(const X86ISA::ExtMachInst &emi) const {
-            return (((uint64_t)emi.legacy << 56) |
-                    ((uint64_t)emi.rex  << 48) |
-                    ((uint64_t)emi.modRM << 40) |
-                    ((uint64_t)emi.sib << 32) |
-                    ((uint64_t)emi.opcode.num << 24) |
-                    ((uint64_t)emi.opcode.prefixA << 16) |
-                    ((uint64_t)emi.opcode.prefixB << 8) |
+            return (((uint64_t)emi.legacy << 40) |
+                    ((uint64_t)emi.rex  << 32) |
+                    ((uint64_t)emi.modRM << 24) |
+                    ((uint64_t)emi.sib << 16) |
+                    ((uint64_t)emi.opcode.type << 8) |
                     ((uint64_t)emi.opcode.op)) ^
                     emi.immediate ^ emi.displacement ^
                     emi.mode ^