diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2012-05-26 13:44:46 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2012-05-26 13:44:46 -0700 |
commit | 0cba96ba6a5d7a4dab2a63b14149c49dfbfbb3bc (patch) | |
tree | 1e4e1372b76ed021060d560c2ee1a474f4b22ef0 /src/arch/arm/decoder.hh | |
parent | eae1e97fb002b44a9d8c46df2da1ddc1d0156ce4 (diff) | |
download | gem5-0cba96ba6a5d7a4dab2a63b14149c49dfbfbb3bc.tar.xz |
CPU: Merge the predecoder and decoder.
These classes are always used together, and merging them will give the ISAs
more flexibility in how they cache things and manage the process.
--HG--
rename : src/arch/x86/predecoder_tables.cc => src/arch/x86/decoder_tables.cc
Diffstat (limited to 'src/arch/arm/decoder.hh')
-rw-r--r-- | src/arch/arm/decoder.hh | 103 |
1 files changed, 101 insertions, 2 deletions
diff --git a/src/arch/arm/decoder.hh b/src/arch/arm/decoder.hh index a91d70f48..dd51fd082 100644 --- a/src/arch/arm/decoder.hh +++ b/src/arch/arm/decoder.hh @@ -31,9 +31,14 @@ #ifndef __ARCH_ARM_DECODER_HH__ #define __ARCH_ARM_DECODER_HH__ -#include "arch/types.hh" +#include <cassert> + +#include "arch/arm/miscregs.hh" +#include "arch/arm/types.hh" +#include "base/types.hh" #include "cpu/decode_cache.hh" -#include "cpu/static_inst_fwd.hh" + +class ThreadContext; namespace ArmISA { @@ -41,6 +46,81 @@ namespace ArmISA class Decoder { protected: + ThreadContext * tc; + //The extended machine instruction being generated + ExtMachInst emi; + MachInst data; + bool bigThumb; + bool instDone; + bool outOfBytes; + int offset; + bool foundIt; + ITSTATE itBits; + + public: + void reset() + { + bigThumb = false; + offset = 0; + emi = 0; + instDone = false; + outOfBytes = true; + foundIt = false; + } + + Decoder(ThreadContext * _tc) : tc(_tc), data(0) + { + reset(); + } + + ThreadContext * getTC() + { + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void process(); + + //Use this to give data to the decoder. This should be used + //when there is control flow. + void moreBytes(const PCState &pc, Addr fetchPC, MachInst inst); + + //Use this to give data to the decoder. This should be used + //when instructions are executed in order. + void moreBytes(MachInst machInst) + { + moreBytes(0, 0, machInst); + } + + inline void consumeBytes(int numBytes) + { + offset += numBytes; + assert(offset <= sizeof(MachInst)); + if (offset == sizeof(MachInst)) + outOfBytes = true; + } + + bool needMoreBytes() const + { + return outOfBytes; + } + + bool instReady() const + { + return instDone; + } + + int getInstSize() const + { + return (!emi.thumb || emi.bigThumb) ? 4 : 2; + } + + protected: /// A cache of decoded instruction objects. static DecodeCache defaultCache; @@ -55,6 +135,25 @@ class Decoder { return defaultCache.decode(this, mach_inst, addr); } + + StaticInstPtr + decode(ArmISA::PCState &nextPC) + { + if (!instDone) + return NULL; + + assert(instDone); + ExtMachInst thisEmi = emi; + nextPC.npc(nextPC.pc() + getInstSize()); + if (foundIt) + nextPC.nextItstate(itBits); + thisEmi.itstate = nextPC.itstate(); + nextPC.size(getInstSize()); + emi = 0; + instDone = false; + foundIt = false; + return decode(thisEmi, nextPC.instAddr()); + } }; } // namespace ArmISA |