diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2013-01-04 19:00:44 -0600 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2013-01-04 19:00:44 -0600 |
commit | d1965af22045d2a62b1cd1bc473b836413d79b46 (patch) | |
tree | 3b5a67ba03489fc8789923b724bc04f04070bea3 /src/arch/x86/decoder.hh | |
parent | 63b10907ef822aa6873d7f4f4d1ee849a188b2c4 (diff) | |
download | gem5-d1965af22045d2a62b1cd1bc473b836413d79b46.tar.xz |
X86: Move address based decode caching in front of the predecoder.
The predecoder in x86 does a lot of work, most of which can be skipped if the
decoder cache is put in front of it.
Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'src/arch/x86/decoder.hh')
-rw-r--r-- | src/arch/x86/decoder.hh | 137 |
1 files changed, 106 insertions, 31 deletions
diff --git a/src/arch/x86/decoder.hh b/src/arch/x86/decoder.hh index 24194d839..796f9eef9 100644 --- a/src/arch/x86/decoder.hh +++ b/src/arch/x86/decoder.hh @@ -32,6 +32,7 @@ #define __ARCH_X86_DECODER_HH__ #include <cassert> +#include <vector> #include "arch/x86/regs/misc.hh" #include "arch/x86/types.hh" @@ -58,9 +59,24 @@ class Decoder static const uint8_t SizeTypeToSize[3][10]; protected: + struct InstBytes + { + StaticInstPtr si; + std::vector<MachInst> chunks; + std::vector<MachInst> masks; + int lastOffset; + + InstBytes() : lastOffset(0) + {} + }; + + static InstBytes dummy; + ThreadContext * tc; //The bytes to be predecoded MachInst fetchChunk; + InstBytes *instBytes; + int chunkIdx; //The pc of the start of fetchChunk Addr basePC; //The pc the current instruction started at @@ -69,9 +85,16 @@ class Decoder int offset; //The extended machine instruction being generated ExtMachInst emi; - HandyM5Reg m5Reg; - - inline uint8_t getNextByte() + //Predecoding state + X86Mode mode; + X86SubMode submode; + uint8_t altOp; + uint8_t defOp; + uint8_t altAddr; + uint8_t defAddr; + uint8_t stack; + + uint8_t getNextByte() { return ((uint8_t *)&fetchChunk)[offset]; } @@ -99,23 +122,34 @@ class Decoder consumeBytes(toGet); } - inline void consumeByte() + void updateOffsetState() { - offset++; assert(offset <= sizeof(MachInst)); - if(offset == sizeof(MachInst)) - outOfBytes = true; + if (offset == sizeof(MachInst)) { + DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n", + chunkIdx, instBytes->chunks.size()); + chunkIdx++; + if (chunkIdx == instBytes->chunks.size()) { + outOfBytes = true; + } else { + offset = 0; + fetchChunk = instBytes->chunks[chunkIdx]; + basePC += sizeof(MachInst); + } + } } - inline void consumeBytes(int numBytes) + void consumeByte() { - offset += numBytes; - assert(offset <= sizeof(MachInst)); - if(offset == sizeof(MachInst)) - outOfBytes = true; + offset++; + updateOffsetState(); } - void doReset(); + void consumeBytes(int numBytes) + { + offset += numBytes; + updateOffsetState(); + } //State machine state protected: @@ -133,6 +167,7 @@ class Decoder enum State { ResetState, + FromCacheState, PrefixState, OpcodeState, ModRMState, @@ -146,6 +181,8 @@ class Decoder State state; //Functions to handle each of the states + State doResetState(); + State doFromCacheState(); State doPrefixState(uint8_t); State doOpcodeState(uint8_t); State doModRMState(uint8_t); @@ -153,6 +190,20 @@ class Decoder State doDisplacementState(); State doImmediateState(); + protected: + /// Caching for decoded instruction objects. + + typedef MiscReg CacheKey; + + typedef DecodeCache::AddrMap<Decoder::InstBytes> DecodePages; + DecodePages *decodePages; + typedef m5::hash_map<CacheKey, DecodePages *> AddrCacheMap; + AddrCacheMap addrCacheMap; + + DecodeCache::InstMap *instMap; + typedef m5::hash_map<CacheKey, DecodeCache::InstMap *> InstCacheMap; + static InstCacheMap instCacheMap; + public: Decoder(ThreadContext * _tc) : tc(_tc), basePC(0), origPC(0), offset(0), @@ -160,9 +211,47 @@ class Decoder state(ResetState) { memset(&emi, 0, sizeof(emi)); - emi.mode.mode = LongMode; - emi.mode.submode = SixtyFourBitMode; - m5Reg = 0; + mode = LongMode; + submode = SixtyFourBitMode; + emi.mode.mode = mode; + emi.mode.submode = submode; + altOp = 0; + defOp = 0; + altAddr = 0; + defAddr = 0; + stack = 0; + instBytes = &dummy; + decodePages = NULL; + instMap = NULL; + } + + void setM5Reg(HandyM5Reg m5Reg) + { + mode = (X86Mode)(uint64_t)m5Reg.mode; + submode = (X86SubMode)(uint64_t)m5Reg.submode; + emi.mode.mode = mode; + emi.mode.submode = submode; + altOp = m5Reg.altOp; + defOp = m5Reg.defOp; + altAddr = m5Reg.altAddr; + defAddr = m5Reg.defAddr; + stack = m5Reg.stack; + + AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg); + if (amIter != addrCacheMap.end()) { + decodePages = amIter->second; + } else { + decodePages = new DecodePages; + addrCacheMap[m5Reg] = decodePages; + } + + InstCacheMap::iterator imIter = instCacheMap.find(m5Reg); + if (imIter != instCacheMap.end()) { + instMap = imIter->second; + } else { + instMap = new DecodeCache::InstMap; + instCacheMap[m5Reg] = instMap; + } } void reset() @@ -218,11 +307,6 @@ class Decoder } } - protected: - /// Caching for decoded instruction objects. - static DecodeCache::InstMap instMap; - static DecodeCache::AddrMap<StaticInstPtr> decodePages; - public: StaticInstPtr decodeInst(ExtMachInst mach_inst); @@ -230,16 +314,7 @@ class Decoder /// @param mach_inst The binary instruction to decode. /// @retval A pointer to the corresponding StaticInst object. StaticInstPtr decode(ExtMachInst mach_inst, Addr addr); - - StaticInstPtr - decode(X86ISA::PCState &nextPC) - { - if (!instDone) - return NULL; - instDone = false; - updateNPC(nextPC); - return decode(emi, origPC); - } + StaticInstPtr decode(X86ISA::PCState &nextPC); }; } // namespace X86ISA |