X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Farch%2Fx86%2Ftypes.hh;h=6fd36b487d80f2b8c9be736446464a235bde22b3;hb=931405da2f8828c23463d83f0b77b551d633565c;hp=ca4a15d243424704ca4308336507728a2bcd0154;hpb=e7bbd85ae614a4d7fc49b4a8b870fe30aea82b80;p=gem5.git diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index ca4a15d24..6fd36b487 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -58,11 +58,11 @@ #ifndef __ARCH_X86_TYPES_HH__ #define __ARCH_X86_TYPES_HH__ -#include #include -#include "base/bitfield.hh" +#include "base/bitunion.hh" #include "base/cprintf.hh" +#include "base/types.hh" namespace X86ISA { @@ -70,25 +70,32 @@ namespace X86ISA typedef uint64_t MachInst; enum Prefixes { - NoOverride = 0, - CSOverride = 1, - DSOverride = 2, - ESOverride = 3, - FSOverride = 4, - GSOverride = 5, - SSOverride = 6, - //The Rex prefix obviously doesn't fit in with the above, but putting - //it here lets us save double the space the enums take up. - RexPrefix = 7, + NoOverride, + ESOverride, + CSOverride, + SSOverride, + DSOverride, + FSOverride, + GSOverride, + RexPrefix, + OperandSizeOverride, + AddressSizeOverride, + Lock, + Rep, + Repne + }; + + BitUnion8(LegacyPrefixVector) + Bitfield<7, 4> decodeVal; + Bitfield<7> repne; + Bitfield<6> rep; + Bitfield<5> lock; + Bitfield<4> op; + Bitfield<3> addr; //There can be only one segment override, so they share the //first 3 bits in the legacyPrefixes bitfield. - SegmentOverride = 0x7, - OperandSizeOverride = 8, - AddressSizeOverride = 16, - Lock = 32, - Rep = 64, - Repne = 128 - }; + Bitfield<2,0> seg; + EndBitUnion(LegacyPrefixVector) BitUnion8(ModRM) Bitfield<7,6> mod; @@ -103,6 +110,9 @@ namespace X86ISA EndBitUnion(Sib) BitUnion8(Rex) + //This bit doesn't mean anything according to the ISA, but in + //this implementation, it being set means an REX prefix was present. + Bitfield<6> present; Bitfield<3> w; Bitfield<2> r; Bitfield<1> x; @@ -114,11 +124,29 @@ namespace X86ISA Bitfield<2,0> bottom3; EndBitUnion(Opcode) + BitUnion8(OperatingMode) + Bitfield<3> mode; + Bitfield<2,0> submode; + EndBitUnion(OperatingMode) + + enum X86Mode { + LongMode, + LegacyMode + }; + + enum X86SubMode { + SixtyFourBitMode, + CompatabilityMode, + ProtectedMode, + Virtual8086Mode, + RealMode + }; + //The intermediate structure the x86 predecoder returns. struct ExtMachInst { //Prefixes - uint8_t legacy; + LegacyPrefixVector legacy; Rex rex; //This holds all of the bytes of the opcode struct @@ -128,18 +156,32 @@ namespace X86ISA 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 0xF0 for - //3dnow instructions, or 0x38-0x3F for some SSE instructions. + //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; //The main opcode byte. The highest addressed byte in the opcode. Opcode op; } opcode; //Modifier bytes ModRM modRM; - uint8_t sib; + Sib sib; //Immediate fields uint64_t immediate; uint64_t displacement; + + //The effective operand size. + uint8_t opSize; + //The effective address size. + uint8_t addrSize; + //The effective stack size. + uint8_t stackSize; + //The size of the displacement + uint8_t dispSize; + + //Mode information + OperatingMode mode; }; inline static std::ostream & @@ -149,50 +191,55 @@ namespace X86ISA "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t" "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t" "modRM = %#x,\n\tsib = %#x,\n\t" - "immediate = %#x,\n\tdisplacement = %#x\n}\n", - emi.legacy, (uint8_t)emi.rex, - emi.opcode.num, emi.opcode.op, + "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, (uint8_t)emi.modRM, (uint8_t)emi.sib, - emi.immediate, emi.displacement); + emi.immediate, emi.displacement, emi.dispSize); return os; } inline static bool operator == (const ExtMachInst &emi1, const ExtMachInst &emi2) { - //Since this is empty, it's always equal + if(emi1.legacy != emi2.legacy) + return false; + if(emi1.rex != emi2.rex) + return false; + if(emi1.opcode.num != emi2.opcode.num) + 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) + return false; + if(emi1.immediate != emi2.immediate) + return false; + if(emi1.displacement != emi2.displacement) + return false; + if(emi1.mode != emi2.mode) + return false; + if(emi1.opSize != emi2.opSize) + return false; + if(emi1.addrSize != emi2.addrSize) + return false; + if(emi1.stackSize != emi2.stackSize) + return false; + if(emi1.dispSize != emi2.dispSize) + return false; return true; } - typedef uint64_t IntReg; - //XXX Should this be a 128 bit structure for XMM memory ops? - typedef uint64_t LargestRead; - typedef uint64_t MiscReg; - - //These floating point types are correct for mmx, but not - //technically for x87 (80 bits) or at all for xmm (128 bits) - typedef double FloatReg; - typedef uint64_t FloatRegBits; - typedef union - { - IntReg intReg; - FloatReg fpReg; - MiscReg ctrlReg; - } AnyReg; - - //XXX This is very hypothetical. X87 instructions would need to - //change their "context" constantly. It's also not clear how - //this would be handled as far as out of order execution. - //Maybe x87 instructions are in order? - enum RegContextParam - { - CONTEXT_X87_TOP + struct CoreSpecific { + int core_type; }; - - typedef int RegContextVal; - - typedef uint8_t RegIndex; }; #endif // __ARCH_X86_TYPES_HH__