00001 // Copyright 2007 Sandia Corporation. Under the terms 00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 00003 // Government retains certain rights in this software. 00004 // 00005 // Copyright (c) 2005-2007, Sandia Corporation 00006 // All rights reserved. 00007 // Copyright (c) 2003-2005, University of Notre Dame 00008 // All rights reserved. 00009 // 00010 // This file is part of the SST software package. For license 00011 // information, see the LICENSE file in the top level directory of the 00012 // distribution. 00013 00014 00015 #ifndef INSTRUCTION_H 00016 #define INSTRUCTION_H 00017 00018 #include "global.h" 00019 #include "exceptions.h" 00020 //#include "sst/boost.h" 00021 00022 //:Instruction Types 00023 // 00024 // A JMP is unconditional, a Branch is conditional. 00025 //!SEC:Framework 00026 typedef enum{ NOOP, 00027 QUIT, 00028 UNKNOWN, 00029 TRAP, 00030 ALU, 00031 FP, /* floating point */ 00032 LOAD, 00033 STORE, 00034 JMP, /* unconditional */ 00035 BRANCH, /* conditional */ 00036 VEC, /* vector or VIS */ 00037 BUBBLE, 00038 ISDEAD, 00039 LASTINST /* NOTE: when adding new instructions, be 00040 sure to also add to the array of strings 00041 in tt7.cc in the correct order */ 00042 } instType; 00043 00044 extern const char *instNames[]; 00045 00046 typedef enum {NEW, 00047 FETCHED, 00048 ISSUED, 00049 COMMITTED, 00050 RETIRED, 00051 SQUASHED, 00052 NOT_SUPP} instState; 00053 00054 class processor; 00055 //: Simulated Instruction 00056 // 00057 // A key part of the processor/thread interface. 00058 // 00059 // Instructions are retrieved from threads. They then go through 00060 // several stages of completion (fetch(), issue(), commit()). The 00061 // instruction can be queried for various information, such as its 00062 // state (fetched, issued, etc...), program counter, required 00063 // functional units, memory address accessed, operation type, etc... 00064 // 00065 // For backends which which to model out-of-order execution or branch 00066 // prediction, things are a bit more complex. The back end it required 00067 // to track the program counter. The back end must also detect when it 00068 // has mispredicted, and squash instructions as appropriate. If it 00069 // wishes to model speculative execution, it must supply a speculative 00070 // mode to instructions which are issue()ing or 00071 // commit()ing. Misspeculation can be detected with the use of the 00072 // NPC() function. 00073 // 00074 //!SEC:Framework 00075 class instruction 00076 { 00077 public: 00078 virtual ~instruction() {;} 00079 //: Fetch Instruction 00080 // 00081 // This "tells" the instruction that it needs to be fetched from 00082 // memory. It should be the first thing called upon a new 00083 // instruction after that instruction has been received from a 00084 // thread. 00085 // 00086 // After fetch completes, the instruction should be able to give its 00087 // PC (instruction address) so the backend can simulate instruction 00088 // fetch from a cache. 00089 // 00090 // Returns true upon success. 00091 // 00092 //!NOTE: I'm not sure when fetch would need to fail. Possibly in the 00093 //!OOO case? 00094 virtual bool fetch(processor*)=0; 00095 //: Issue Instruction 00096 // 00097 // This tells the instruction that it needs to be "issued", such as 00098 // to a functional unit. It should be called after instruction::fetch(). 00099 // 00100 // after the issue(), the instruction should be able to give its 00101 // opcode type, and what memory address (memEA) it needs to access 00102 // (if it is a memory access). 00103 // 00104 // Returns true upon success. Should never fail in the serial 00105 // in-order case. It may fail in the OOO case if the instruction 00106 // cannot issue because of a data dependance. ex: Cannot compute its 00107 // memEA because a source register has not been filled in. 00108 virtual bool issue(processor*)=0; 00109 //: Commit Instruction 00110 // 00111 // This tells the thread it can complete its computation and commit 00112 // its results to the thread's state. 00113 // 00114 // After an instrucion successfully commits, it can be retired back 00115 // to its issueing thread. 00116 // 00117 // Returns true upon success. It may fail, if it does so, it should 00118 // be able to give the exception which caused its failure. (thru 00119 // instruction::exception()). 00120 virtual bool commit(processor*)=0; 00121 00122 //: return Next PC 00123 // 00124 // returns the program counter which should follow this 00125 // instruction. Available after commit. Useful to detect 00126 // mispredicted instructions. 00127 virtual simRegister NPC() const =0; 00128 //: return TargetPC 00129 virtual simRegister TPC() const =0; 00130 //: Issue, possibly speculatively 00131 // 00132 // For the out-of-order case, backends can fetch "incorrect" 00133 // instructions. The backend must detect when this has occured and 00134 // supply the correct speculation mode to the instruction. 00135 virtual bool issue(processor *p, const bool)=0; 00136 // Commit, possibly speculatively 00137 // 00138 // For the out-of-order case, backends can fetch "incorrect" 00139 // instructions. The backend must detect when this has occured and 00140 // supply the correct speculation mode to the instruction. 00141 virtual bool commit(processor *p, const bool)=0; 00142 //: Functional unit requirements 00143 // 00144 // return the type of functional unit required for this 00145 // instruction. Follows simpleScalar FU designations. 00146 virtual int fu() const =0; 00147 //: Specific Operation 00148 // 00149 // follows simpleScalar semantics for more detailed opcode flags 00150 virtual int specificOp() const =0; 00151 //: Output dependancies 00152 // 00153 // returns a -1 terminated list of output dependancies. The 00154 // dependancies are register numbers, starting at 1. First integer 00155 // registers, then FP registers, then any special registers as 00156 // required. 00157 virtual const int* outDeps() const =0; 00158 //: Input dependancies 00159 // 00160 // returns a -1 terminated list of input register dependancies. The 00161 // dependancies are register numbers, starting at 1. First integer 00162 // registers, then FP registers, then any special registers as 00163 // required. 00164 virtual const int* inDeps() const =0; 00165 //: Is this a function return 00166 // 00167 // is this instruction returning from an function call. Used for 00168 // branch predictors. 00169 virtual bool isReturn() const =0; 00170 00171 //: Instruction state 00172 virtual instState state() const =0; 00173 //: Accessor for opcode type 00174 virtual instType op() const =0; 00175 //: Accessor for program counter (instruction address) 00176 virtual simAddress PC() const =0; 00177 //: Accessor for effective address 00178 // For a load or store 00179 virtual simAddress memEA() const =0; 00180 //: Offset for memory instructions 00181 virtual int memOffset(bool &valid) const {valid=0; return -1;} 00182 //: Accessor for execption type 00183 // of an instruction which failed to commit. 00184 virtual exceptType exception() const =0; 00185 00186 virtual simPID pid() const =0; 00187 //: Accessor for target destination 00188 // 00189 // If a thread issues an instruction directing it to move (migrate) 00190 // to another LWP location, it should give the MOVE_TO_EXCEPTION and 00191 // then set the location it wishes to move 00192 // to. instruction::exception() accesses that target address. 00193 virtual simAddress moveToTarget() const =0; 00194 //: Accessor for FEB address 00195 // 00196 // If an instruction cannot complete a load or store instruction due 00197 // to Full/Empty Bit complications, it should raise the 00198 // FEB_EXCEPTION and instruction::febTarget() should return the 00199 // address of the data item it was attempting to access. 00200 virtual simAddress febTarget() const =0; 00201 }; 00202 00203 #endif