summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-03-15 19:16:39 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-03-15 19:16:39 +0000
commit9ad3f1e479d8c57253cf057c14f5cfb40f141db3 (patch)
treebd0a19b59324dbebe5f1e74cd144af482cb9d6ad /src/arch
parentf4eee4fb81809b8b35393c49390fdcd40ac4f2a1 (diff)
downloadgem5-9ad3f1e479d8c57253cf057c14f5cfb40f141db3.tar.xz
Refactor things a little.
--HG-- extra : convert_revision : 8167455ffc05130d4afcc68466879c7c439bee57
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/predecoder.hh63
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 &current, 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),