diff options
Diffstat (limited to 'src/arch/x86/types.hh')
-rw-r--r-- | src/arch/x86/types.hh | 62 |
1 files changed, 36 insertions, 26 deletions
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 ^ |