diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/decoder.cc | 219 | ||||
-rw-r--r-- | src/arch/x86/decoder.hh | 14 | ||||
-rw-r--r-- | src/arch/x86/decoder_tables.cc | 70 | ||||
-rw-r--r-- | src/arch/x86/isa/bitfields.isa | 10 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/decoder.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/vex_opcodes.isa | 1431 | ||||
-rw-r--r-- | src/arch/x86/types.hh | 96 |
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) | |