diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-03-15 19:16:39 +0000 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-03-15 19:16:39 +0000 |
commit | 9ad3f1e479d8c57253cf057c14f5cfb40f141db3 (patch) | |
tree | bd0a19b59324dbebe5f1e74cd144af482cb9d6ad /src/arch/x86/predecoder.hh | |
parent | f4eee4fb81809b8b35393c49390fdcd40ac4f2a1 (diff) | |
download | gem5-9ad3f1e479d8c57253cf057c14f5cfb40f141db3.tar.xz |
Refactor things a little.
--HG--
extra : convert_revision : 8167455ffc05130d4afcc68466879c7c439bee57
Diffstat (limited to 'src/arch/x86/predecoder.hh')
-rw-r--r-- | src/arch/x86/predecoder.hh | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index a1d0905c5..d7734be88 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -59,6 +59,7 @@ #define __ARCH_X86_PREDECODER_HH__ #include "arch/x86/types.hh" +#include "base/bitfield.hh" #include "sim/host.hh" class ThreadContext; @@ -85,6 +86,50 @@ namespace X86ISA //The extended machine instruction being generated ExtMachInst emi; + inline uint8_t getNextByte() + { + return (fetchChunk >> (offset * 8)) & 0xff; + } + + void getImmediate(int &collected, uint64_t ¤t, int size) + { + //Figure out how many bytes we still need to get for the + //immediate. + int toGet = size - collected; + //Figure out how many bytes are left in our "buffer" + int remaining = sizeof(MachInst) - offset; + //Get as much as we need, up to the amount available. + toGet = toGet > remaining ? remaining : toGet; + + //Shift the bytes we want to be all the way to the right + uint64_t partialDisp = fetchChunk >> (offset * 8); + //Mask off what we don't want + partialDisp &= mask(toGet * 8); + //Shift it over to overlay with our displacement. + partialDisp <<= (displacementCollected * 8); + //Put it into our displacement + current |= partialDisp; + //Update how many bytes we've collected. + collected += toGet; + consumeBytes(toGet); + } + + inline void consumeByte() + { + offset++; + assert(offset <= sizeof(MachInst)); + if(offset == sizeof(MachInst)) + outOfBytes = true; + } + + inline void consumeBytes(int numBytes) + { + offset += numBytes; + assert(offset <= sizeof(MachInst)); + if(offset == sizeof(MachInst)) + outOfBytes = true; + } + //State machine state protected: //Whether or not we're out of bytes @@ -98,23 +143,27 @@ namespace X86ISA int immediateSize; int immediateCollected; - //These are local to some of the states. I need to turn the states - //into inline functions to clean things up a bit. - int toGet; - int remaining; - MachInst partialDisp; - enum State { Prefix, Opcode, ModRM, SIB, Displacement, - Immediate + Immediate, + //We should never get to this state. Getting here is an error. + ErrorState }; State state; + //Functions to handle each of the states + State doPrefixState(uint8_t); + State doOpcodeState(uint8_t); + State doModRMState(uint8_t); + State doSIBState(uint8_t); + State doDisplacementState(); + State doImmediateState(); + public: Predecoder(ThreadContext * _tc) : tc(_tc), basePC(0), offset(0), |