changeset 5fae03bd840a in /z/repo/gem5 details: http://repo.gem5.org/gem5?cmd=changeset;node=5fae03bd840a description: arm: Clean up and document decoder API
This changeset adds more documentation to the ArmISA::Decoder class and restructures it slightly to make API groups more obvious. diffstat: src/arch/arm/decoder.cc | 52 +++++++++++- src/arch/arm/decoder.hh | 197 +++++++++++++++++++++++++++-------------------- 2 files changed, 162 insertions(+), 87 deletions(-) diffs (truncated from 302 to 300 lines): diff -r ae5582819481 -r 5fae03bd840a src/arch/arm/decoder.cc --- a/src/arch/arm/decoder.cc Tue Dec 23 09:31:17 2014 -0500 +++ b/src/arch/arm/decoder.cc Tue Dec 23 09:31:17 2014 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013 ARM Limited + * Copyright (c) 2012-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -51,6 +51,23 @@ GenericISA::BasicDecodeCache Decoder::defaultCache; +Decoder::Decoder() + : data(0), fpscrLen(0), fpscrStride(0) +{ + reset(); +} + +void +Decoder::reset() +{ + bigThumb = false; + offset = 0; + emi = 0; + instDone = false; + outOfBytes = true; + foundIt = false; +} + void Decoder::process() { @@ -118,8 +135,15 @@ } } -//Use this to give data to the decoder. This should be used -//when there is control flow. +void +Decoder::consumeBytes(int numBytes) +{ + offset += numBytes; + assert(offset <= sizeof(MachInst)); + if (offset == sizeof(MachInst)) + outOfBytes = true; +} + void Decoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst) { @@ -134,4 +158,26 @@ process(); } +StaticInstPtr +Decoder::decode(ArmISA::PCState &pc) +{ + if (!instDone) + return NULL; + + const int inst_size((!emi.thumb || emi.bigThumb) ? 4 : 2); + ExtMachInst this_emi(emi); + + pc.npc(pc.pc() + inst_size); + if (foundIt) + pc.nextItstate(itBits); + this_emi.itstate = pc.itstate(); + pc.size(inst_size); + + emi = 0; + instDone = false; + foundIt = false; + + return decode(this_emi, pc.instAddr()); } + +} diff -r ae5582819481 -r 5fae03bd840a src/arch/arm/decoder.hh --- a/src/arch/arm/decoder.hh Tue Dec 23 09:31:17 2014 -0500 +++ b/src/arch/arm/decoder.hh Tue Dec 23 09:31:17 2014 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 ARM Limited + * Copyright (c) 2013-2014 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -70,100 +70,129 @@ int fpscrLen; int fpscrStride; - public: - void reset() + /// A cache of decoded instruction objects. + static GenericISA::BasicDecodeCache defaultCache; + + /** + * Pre-decode an instruction from the current state of the + * decoder. + */ + void process(); + + /** + * Consume bytes by moving the offset into the data word and + * sanity check the results. + */ + void consumeBytes(int numBytes); + + public: // Decoder API + Decoder(); + + /** Reset the decoders internal state. */ + void reset(); + + /** + * Can the decoder accept more data? + * + * A CPU model uses this method to determine if the decoder can + * accept more data. Note that an instruction can be ready (see + * instReady() even if this method returns true. + */ + bool needMoreBytes() const { return outOfBytes; } + + /** + * Is an instruction ready to be decoded? + * + * CPU models call this method to determine if decode() will + * return a new instruction on the next call. It typically only + * returns false if the decoder hasn't received enough data to + * decode a full instruction. + */ + bool instReady() const { return instDone; } + + /** + * Feed data to the decoder. + * + * A CPU model uses this interface to load instruction data into + * the decoder. Once enough data has been loaded (check with + * instReady()), a decoded instruction can be retrieved using + * decode(ArmISA::PCState). + * + * This method is intended to support both fixed-length and + * variable-length instructions. Instruction data is fetch in + * MachInst blocks (which correspond to the size of a typical + * insturction). The method might need to be called multiple times + * if the instruction spans multiple blocks, in that case + * needMoreBytes() will return true and instReady() will return + * false. + * + * The fetchPC parameter is used to indicate where in memory the + * instruction was fetched from. This is should be the same + * address as the pc. If fetching multiple blocks, it indicates + * where subsequent blocks are fetched from (pc + n * + * sizeof(MachInst)). + * + * @param pc Instruction pointer that we are decoding. + * @param fetchPC The address this chunk was fetched from. + * @param inst Raw instruction data. + */ + void moreBytes(const PCState &pc, Addr fetchPC, MachInst inst); + + /** + * Decode an instruction or fetch it from the code cache. + * + * This method decodes the currently pending pre-decoded + * instruction. Data must be fed to the decoder using moreBytes() + * until instReady() is true before calling this method. + * + * @param pc Instruction pointer that we are decoding. + * @return A pointer to a static instruction or NULL if the + * decoder isn't ready (see instReady()). + */ + StaticInstPtr decode(ArmISA::PCState &pc); + + /** + * Decode a pre-decoded machine instruction. + * + * @warn This method takes a pre-decoded instruction as its + * argument. It should typically not be called directly. + * + * @param mach_inst A pre-decoded instruction + * @retval A pointer to the corresponding StaticInst object. + */ + StaticInstPtr decode(ExtMachInst mach_inst, Addr addr) { - bigThumb = false; - offset = 0; - emi = 0; - instDone = false; - outOfBytes = true; - foundIt = false; + return defaultCache.decode(this, mach_inst, addr); } - Decoder() : data(0), fpscrLen(0), fpscrStride(0) - { - reset(); - } + /** + * Decode a machine instruction without calling the cache. + * + * @note The implementation of this method is generated by the ISA + * parser script. + * + * @warn This method takes a pre-decoded instruction as its + * argument. It should typically not be called directly. + * + * @param mach_inst The binary instruction to decode. + * @retval A pointer to the corresponding StaticInst object. + */ + StaticInstPtr decodeInst(ExtMachInst mach_inst); - void process(); + /** + * Take over the state from an old decoder when switching CPUs. + * + * @param old Decoder used in old CPU + */ + void takeOverFrom(Decoder *old) {} - //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; - } - + public: // ARM-specific decoder state manipulation void setContext(FPSCR fpscr) { fpscrLen = fpscr.len; fpscrStride = fpscr.stride; } - - void takeOverFrom(Decoder *old) {} - - protected: - /// A cache of decoded instruction objects. - static GenericISA::BasicDecodeCache defaultCache; - - public: - StaticInstPtr decodeInst(ExtMachInst mach_inst); - - /// Decode a machine instruction. - /// @param mach_inst The binary instruction to decode. - /// @retval A pointer to the corresponding StaticInst object. - StaticInstPtr - decode(ExtMachInst mach_inst, Addr addr) - { - 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()); - } }; _______________________________________________ gem5-dev mailing list gem5-dev@gem5.org http://m5sim.org/mailman/listinfo/gem5-dev