From c8836142807e512beff11e16fbe4cc734c27d66d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 28 Jan 2021 22:34:40 -0800 Subject: [PATCH] arch-x86: Fix style in arch/x86/types.hh. Change-Id: I5e32eea9b843d4f68adf5430516d0636317c8a57 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40103 Tested-by: kokoro Reviewed-by: Daniel Carvalho Maintainer: Gabe Black --- src/arch/x86/types.hh | 607 +++++++++++++++++++++--------------------- 1 file changed, 305 insertions(+), 302 deletions(-) diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 890a9e5cf..9b0b0343b 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -48,336 +48,339 @@ namespace X86ISA { - //This really determines how many bytes are passed to the decoder. - typedef uint64_t MachInst; - - enum Prefixes { - NoOverride, - ESOverride, - CSOverride, - SSOverride, - DSOverride, - FSOverride, - GSOverride, - RexPrefix, - OperandSizeOverride, - AddressSizeOverride, - Lock, - Rep, - Repne, - Vex2Prefix, - Vex3Prefix, - XopPrefix, - }; - 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. - Bitfield<2,0> seg; - EndBitUnion(LegacyPrefixVector) - - BitUnion8(ModRM) - Bitfield<7,6> mod; - Bitfield<5,3> reg; - Bitfield<2,0> rm; - EndBitUnion(ModRM) - - BitUnion8(Sib) - Bitfield<7,6> scale; - Bitfield<5,3> index; - Bitfield<2,0> base; - 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; - Bitfield<0> b; - EndBitUnion(Rex) - - BitUnion8(Vex2Of3) - // Inverted bits from the REX prefix. - Bitfield<7> r; - Bitfield<6> x; - Bitfield<5> b; - // Selector for what would be two or three byte opcode types. - Bitfield<4, 0> m; - EndBitUnion(Vex2Of3) - - BitUnion8(Vex3Of3) - // Bit from the REX prefix. - Bitfield<7> w; - // Inverted extra register index. - Bitfield<6, 3> v; - // Vector length specifier. - Bitfield<2> l; - // Implied 66, F2, or F3 opcode prefix. - Bitfield<1, 0> p; - EndBitUnion(Vex3Of3) - - BitUnion8(Vex2Of2) - // Inverted bit from the REX prefix. - Bitfield<7> r; - // Inverted extra register index. - Bitfield<6, 3> v; - // Vector length specifier - Bitfield<2> l; - // Implied 66, F2, or F3 opcode prefix. - Bitfield<1, 0> p; - EndBitUnion(Vex2Of2) - - BitUnion8(VexInfo) - // Extra register index. - Bitfield<6, 3> v; - // Vector length specifier. - Bitfield<2> l; - // Whether the VEX prefix was used. - Bitfield<0> present; - EndBitUnion(VexInfo) - - enum OpcodeType { - BadOpcode, - OneByteOpcode, - TwoByteOpcode, - ThreeByte0F38Opcode, - ThreeByte0F3AOpcode, - }; +//This really determines how many bytes are passed to the decoder. +typedef uint64_t MachInst; + +enum Prefixes { + NoOverride, + ESOverride, + CSOverride, + SSOverride, + DSOverride, + FSOverride, + GSOverride, + RexPrefix, + OperandSizeOverride, + AddressSizeOverride, + Lock, + Rep, + Repne, + Vex2Prefix, + Vex3Prefix, + XopPrefix, +}; + +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. + Bitfield<2,0> seg; +EndBitUnion(LegacyPrefixVector) + +BitUnion8(ModRM) + Bitfield<7,6> mod; + Bitfield<5,3> reg; + Bitfield<2,0> rm; +EndBitUnion(ModRM) + +BitUnion8(Sib) + Bitfield<7,6> scale; + Bitfield<5,3> index; + Bitfield<2,0> base; +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; + Bitfield<0> b; +EndBitUnion(Rex) + +BitUnion8(Vex2Of3) + // Inverted bits from the REX prefix. + Bitfield<7> r; + Bitfield<6> x; + Bitfield<5> b; + // Selector for what would be two or three byte opcode types. + Bitfield<4, 0> m; +EndBitUnion(Vex2Of3) + +BitUnion8(Vex3Of3) + // Bit from the REX prefix. + Bitfield<7> w; + // Inverted extra register index. + Bitfield<6, 3> v; + // Vector length specifier. + Bitfield<2> l; + // Implied 66, F2, or F3 opcode prefix. + Bitfield<1, 0> p; +EndBitUnion(Vex3Of3) + +BitUnion8(Vex2Of2) + // Inverted bit from the REX prefix. + Bitfield<7> r; + // Inverted extra register index. + Bitfield<6, 3> v; + // Vector length specifier + Bitfield<2> l; + // Implied 66, F2, or F3 opcode prefix. + Bitfield<1, 0> p; +EndBitUnion(Vex2Of2) + +BitUnion8(VexInfo) + // Extra register index. + Bitfield<6, 3> v; + // Vector length specifier. + Bitfield<2> l; + // Whether the VEX prefix was used. + Bitfield<0> present; +EndBitUnion(VexInfo) + +enum OpcodeType { + BadOpcode, + 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!"; + } +} - static inline const char * - opcodeTypeToStr(OpcodeType type) +BitUnion8(Opcode) + Bitfield<7,3> top5; + 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 used by the x86 decoder. +struct ExtMachInst +{ + void reset() { memset(static_cast(this), 0, sizeof(*this)); } + + //Prefixes + LegacyPrefixVector legacy; + Rex rex; + VexInfo vex; + + //This holds all of the bytes of the opcode + struct { - 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!"; - } + OpcodeType type; + //The main opcode byte. The highest addressed byte in the opcode. + Opcode op; + } opcode; + //Modifier bytes + ModRM modRM; + 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 & +operator << (std::ostream &os, const ExtMachInst &emi) +{ + ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t" + "vex/xop = %#x,\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, + (uint8_t)emi.vex, + opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op, + (uint8_t)emi.modRM, (uint8_t)emi.sib, + emi.immediate, emi.displacement, emi.dispSize); + return os; +} + +inline static bool +operator == (const ExtMachInst &emi1, const ExtMachInst &emi2) +{ + if (emi1.legacy != emi2.legacy) + return false; + if (emi1.rex != emi2.rex) + return false; + if (emi1.vex != emi2.vex) + return false; + if (emi1.opcode.type != emi2.opcode.type) + return false; + if (emi1.opcode.op != emi2.opcode.op) + 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; +} + +class PCState : public GenericISA::UPCState +{ + protected: + typedef GenericISA::UPCState Base; + + uint8_t _size; + + public: + void + set(Addr val) + { + Base::set(val); + _size = 0; } - BitUnion8(Opcode) - Bitfield<7,3> top5; - Bitfield<2,0> bottom3; - EndBitUnion(Opcode) + PCState() {} + PCState(Addr val) { set(val); } - BitUnion8(OperatingMode) - Bitfield<3> mode; - Bitfield<2,0> submode; - EndBitUnion(OperatingMode) + void + setNPC(Addr val) + { + Base::setNPC(val); + _size = 0; + } - enum X86Mode { - LongMode, - LegacyMode - }; + uint8_t size() const { return _size; } + void size(uint8_t newSize) { _size = newSize; } - enum X86SubMode { - SixtyFourBitMode, - CompatabilityMode, - ProtectedMode, - Virtual8086Mode, - RealMode - }; + bool + branching() const + { + return (this->npc() != this->pc() + size()) || + (this->nupc() != this->upc() + 1); + } - //The intermediate structure used by the x86 decoder. - struct ExtMachInst + void + advance() { - void reset() { - memset(static_cast(this), 0, sizeof(*this)); - } - - //Prefixes - LegacyPrefixVector legacy; - Rex rex; - VexInfo vex; - - //This holds all of the bytes of the opcode - struct - { - OpcodeType type; - //The main opcode byte. The highest addressed byte in the opcode. - Opcode op; - } opcode; - //Modifier bytes - ModRM modRM; - 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; - }; + Base::advance(); + _size = 0; + } - inline static std::ostream & - operator << (std::ostream & os, const ExtMachInst & emi) + void + uEnd() { - ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t" - "vex/xop = %#x,\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, - (uint8_t)emi.vex, - opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op, - (uint8_t)emi.modRM, (uint8_t)emi.sib, - emi.immediate, emi.displacement, emi.dispSize); - return os; + Base::uEnd(); + _size = 0; } - inline static bool - operator == (const ExtMachInst &emi1, const ExtMachInst &emi2) + void + serialize(CheckpointOut &cp) const { - if (emi1.legacy != emi2.legacy) - return false; - if (emi1.rex != emi2.rex) - return false; - if (emi1.vex != emi2.vex) - return false; - if (emi1.opcode.type != emi2.opcode.type) - return false; - if (emi1.opcode.op != emi2.opcode.op) - 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; + Base::serialize(cp); + SERIALIZE_SCALAR(_size); } - class PCState : public GenericISA::UPCState + void + unserialize(CheckpointIn &cp) { - protected: - typedef GenericISA::UPCState Base; - - uint8_t _size; - - public: - void - set(Addr val) - { - Base::set(val); - _size = 0; - } - - PCState() {} - PCState(Addr val) { set(val); } - - void - setNPC(Addr val) - { - Base::setNPC(val); - _size = 0; - } - - uint8_t size() const { return _size; } - void size(uint8_t newSize) { _size = newSize; } - - bool - branching() const - { - return (this->npc() != this->pc() + size()) || - (this->nupc() != this->upc() + 1); - } - - void - advance() - { - Base::advance(); - _size = 0; - } - - void - uEnd() - { - Base::uEnd(); - _size = 0; - } - - void - serialize(CheckpointOut &cp) const - { - Base::serialize(cp); - SERIALIZE_SCALAR(_size); - } - - void - unserialize(CheckpointIn &cp) - { - Base::unserialize(cp); - UNSERIALIZE_SCALAR(_size); - } - }; + Base::unserialize(cp); + UNSERIALIZE_SCALAR(_size); + } +}; } -namespace std { - template<> - struct hash { - size_t operator()(const X86ISA::ExtMachInst &emi) const { - return (((uint64_t)emi.legacy << 48) | - ((uint64_t)emi.rex << 40) | - ((uint64_t)emi.vex << 32) | - ((uint64_t)emi.modRM << 24) | - ((uint64_t)emi.sib << 16) | - ((uint64_t)emi.opcode.type << 8) | - ((uint64_t)emi.opcode.op)) ^ - emi.immediate ^ emi.displacement ^ - emi.mode ^ - emi.opSize ^ emi.addrSize ^ - emi.stackSize ^ emi.dispSize; - }; +namespace std +{ + +template<> +struct hash +{ + size_t + operator()(const X86ISA::ExtMachInst &emi) const + { + return (((uint64_t)emi.legacy << 48) | + ((uint64_t)emi.rex << 40) | + ((uint64_t)emi.vex << 32) | + ((uint64_t)emi.modRM << 24) | + ((uint64_t)emi.sib << 16) | + ((uint64_t)emi.opcode.type << 8) | + ((uint64_t)emi.opcode.op)) ^ + emi.immediate ^ emi.displacement ^ + emi.mode ^ + emi.opSize ^ emi.addrSize ^ + emi.stackSize ^ emi.dispSize; }; +}; + } // These two functions allow ExtMachInst to be used with SERIALIZE_SCALAR // and UNSERIALIZE_SCALAR. template <> -void -paramOut(CheckpointOut &cp, const std::string &name, - const X86ISA::ExtMachInst &machInst); +void paramOut(CheckpointOut &cp, const std::string &name, + const X86ISA::ExtMachInst &machInst); template <> -void -paramIn(CheckpointIn &cp, const std::string &name, +void paramIn(CheckpointIn &cp, const std::string &name, X86ISA::ExtMachInst &machInst); #endif // __ARCH_X86_TYPES_HH__ -- 2.30.2