summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/decoder.cc191
-rw-r--r--src/arch/x86/decoder.hh29
-rw-r--r--src/arch/x86/decoder_tables.cc259
-rw-r--r--src/arch/x86/isa/bitfields.isa4
-rw-r--r--src/arch/x86/isa/decoder/decoder.isa10
-rw-r--r--src/arch/x86/isa/decoder/locked_opcodes.isa62
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa2
-rw-r--r--src/arch/x86/isa/decoder/three_byte_0f38_opcodes.isa110
-rw-r--r--src/arch/x86/isa/decoder/three_byte_0f3a_opcodes.isa65
-rw-r--r--src/arch/x86/isa/decoder/three_byte_opcodes.isa151
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa1858
-rw-r--r--src/arch/x86/isa_traits.hh2
-rw-r--r--src/arch/x86/types.cc9
-rw-r--r--src/arch/x86/types.hh62
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 &section,
machInst.rex = temp8;
// Opcode
- paramIn(cp, section, name + ".opcode.num", machInst.opcode.num);
- paramIn(cp, section, name + ".opcode.prefixA", machInst.opcode.prefixA);
- paramIn(cp, section, name + ".opcode.prefixB", machInst.opcode.prefixB);
+ paramIn(cp, section, name + ".opcode.type", temp8);
+ machInst.opcode.type = (OpcodeType)temp8;
paramIn(cp, section, name + ".opcode.op", temp8);
machInst.opcode.op = temp8;
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 ^