diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/decoder.cc | 191 | ||||
-rw-r--r-- | src/arch/x86/decoder.hh | 29 | ||||
-rw-r--r-- | src/arch/x86/decoder_tables.cc | 259 | ||||
-rw-r--r-- | src/arch/x86/isa/bitfields.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/decoder.isa | 10 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/locked_opcodes.isa | 62 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa | 110 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa | 65 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/three_byte_opcodes.isa | 151 | ||||
-rw-r--r-- | src/arch/x86/isa/decoder/two_byte_opcodes.isa | 1858 | ||||
-rw-r--r-- | src/arch/x86/isa_traits.hh | 2 | ||||
-rw-r--r-- | src/arch/x86/types.cc | 9 | ||||
-rw-r--r-- | src/arch/x86/types.hh | 62 |
14 files changed, 1496 insertions, 1318 deletions
diff --git a/src/arch/x86/decoder.cc b/src/arch/x86/decoder.cc index f42fb28bf..59f2e0f4f 100644 --- a/src/arch/x86/decoder.cc +++ b/src/arch/x86/decoder.cc @@ -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) diff --git a/src/arch/x86/decoder.hh b/src/arch/x86/decoder.hh index ca7ef96fe..a37fccfb1 100644 --- a/src/arch/x86/decoder.hh +++ b/src/arch/x86/decoder.hh @@ -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. diff --git a/src/arch/x86/decoder_tables.cc b/src/arch/x86/decoder_tables.cc index a132cb864..d5fcceef8 100644 --- a/src/arch/x86/decoder_tables.cc +++ b/src/arch/x86/decoder_tables.cc @@ -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 }; } diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa index a7753ba3d..e2751a8ef 100644 --- a/src/arch/x86/isa/bitfields.isa +++ b/src/arch/x86/isa/bitfields.isa @@ -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; diff --git a/src/arch/x86/isa/decoder/decoder.isa b/src/arch/x86/isa/decoder/decoder.isa index 9b2ce0ba0..eaa579817 100644 --- a/src/arch/x86/isa/decoder/decoder.isa +++ b/src/arch/x86/isa/decoder/decoder.isa @@ -43,16 +43,12 @@ 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" diff --git a/src/arch/x86/isa/decoder/locked_opcodes.isa b/src/arch/x86/isa/decoder/locked_opcodes.isa index e776d1320..d2bfac57e 100644 --- a/src/arch/x86/isa/decoder/locked_opcodes.isa +++ b/src/arch/x86/isa/decoder/locked_opcodes.isa @@ -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]); @@ -137,40 +137,36 @@ } } } - 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!"}}); } } } diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 92e5cd0a8..859d1f1b4 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -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 index 000000000..d04f15ec3 --- /dev/null +++ b/src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa @@ -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 index 000000000..5935fb6a5 --- /dev/null +++ b/src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa @@ -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 index 7587e3dad..000000000 --- a/src/arch/x86/isa/decoder/three_byte_opcodes.isa +++ /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!"}}); -} diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 081bad971..e1b20feb1 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -42,1029 +42,1025 @@ // // 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!"}}); } diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index a9e274ecc..f4fdb59e5 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -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. diff --git a/src/arch/x86/types.cc b/src/arch/x86/types.cc index 73177f467..830a131e5 100644 --- a/src/arch/x86/types.cc +++ b/src/arch/x86/types.cc @@ -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 §ion, 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; diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index a604c3efc..dd60c0aec 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -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 ^ |