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