00001 00002 #ifndef REORDERBUFFER_H 00003 #define REORDERBUFFER_H 00004 00005 #include <OpteronDefs.h> 00006 00007 class Token; 00008 00009 /// @brief Simulated instruction re-order buffer 00010 /// 00011 /// This class is responsible for retiring instructions in order 00012 /// and for canceling all outstanding instructions in case of a 00013 /// branch mispredict. It was expected to be a singleton class, but 00014 /// we are currently instantiating a second object which acts as 00015 /// a "fake" retirement buffer for fake LEA instructions that are 00016 /// created for FP instructions that have a memop on them. This way 00017 /// the fake LEAs are not counted, but are retired and cleaned up 00018 /// properly (ooh, except for mispredicted branches! -- does it matter?) 00019 /// 00020 class ReorderBuffer 00021 { 00022 public: 00023 ReorderBuffer(unsigned int numSlots, unsigned int numRetireablePerCycle, 00024 bool fake=false); 00025 ~ReorderBuffer(); 00026 bool dispatch(Token *token, CycleCount atCycle); 00027 bool isFull(); 00028 void incFullStall() {fullStalls++;} 00029 int updateStatus(CycleCount currentCycle); // returns 1 if canceled insns 00030 InstructionCount retiredCount() {return totalRetired;} 00031 private: 00032 Token **tokenBuffer; ///< circular queue of Token pointers of size numSlots 00033 unsigned int numSlots; ///< number of instructions the buffer can hold 00034 unsigned int numTokens; ///< number of instructions currently in buffer 00035 unsigned int numPerCycle; ///< number of instructions accepted and retired per cycle 00036 unsigned int availSlot; ///< index of next available slot (if not full); 00037 unsigned int retireSlot; ///< index of next retireable token 00038 unsigned long long totalRetired; ///< statistic: total retired instructions 00039 unsigned long long totalAnulled; ///< statistic: total canceled instructions 00040 unsigned long long fullStalls; ///< statistic: total stalls due to full buffer 00041 bool fake; 00042 }; 00043 00044 #endif