2 * Copyright (c) 2001-2004 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef __BASE_DYN_INST_HH__
30 #define __BASE_DYN_INST_HH__
35 #include "base/fast_alloc.hh"
36 #include "base/trace.hh"
38 #include "cpu/static_inst.hh"
39 #include "cpu/beta_cpu/comm.hh"
40 #include "cpu/full_cpu/bpred_update.hh"
41 #include "mem/functional_mem/main_memory.hh"
42 #include "cpu/full_cpu/spec_memory.hh"
43 #include "cpu/inst_seq.hh"
44 #include "cpu/full_cpu/op_class.hh"
45 #include "cpu/full_cpu/spec_state.hh"
49 * Defines a dynamic instruction context.
61 class BaseDynInst : public FastAlloc
64 // Typedef for the CPU.
65 typedef typename Impl::FullCPU FullCPU;
67 //Typedef to get the ISA.
68 typedef typename Impl::ISA ISA;
70 /// Binary machine instruction type.
71 typedef typename ISA::MachInst MachInst;
72 /// Memory address type.
73 typedef typename ISA::Addr Addr;
74 /// Logical register index type.
75 typedef typename ISA::RegIndex RegIndex;
76 /// Integer register index type.
77 typedef typename ISA::IntReg IntReg;
80 MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs
81 MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs
84 StaticInstPtr<ISA> staticInst;
86 ////////////////////////////////////////////
88 // INSTRUCTION EXECUTION
90 ////////////////////////////////////////////
91 Trace::InstRecord *traceData;
93 // void setCPSeq(InstSeqNum seq);
96 Fault read(Addr addr, T &data, unsigned flags);
99 Fault write(T data, Addr addr, unsigned flags,
103 IntReg *getIntegerRegs(void);
104 FunctionalMemory *getMemory(void);
106 void prefetch(Addr addr, unsigned flags);
107 void writeHint(Addr addr, int size, unsigned flags);
108 Fault copySrcTranslate(Addr src);
109 Fault copy(Addr dest);
112 /** Is this instruction valid. */
115 /** The sequence number of the instruction. */
118 /** How many source registers are ready. */
121 /** Can this instruction issue. */
124 /** Has this instruction issued. */
127 /** Has this instruction executed (or made it through execute) yet. */
130 /** Can this instruction commit. */
133 /** Is this instruction squashed. */
136 /** Is this instruction squashed in the instruction queue. */
139 /** Is this a recover instruction. */
142 /** Is this a thread blocking instruction. */
143 bool blockingInst; /* this inst has called thread_block() */
145 /** Is this a thread syncrhonization instruction. */
148 /** If the BTB missed. */
151 /** The thread this instruction is from. */
154 /** If instruction is speculative. */
157 /** data address space ID, for loads & stores. */
160 /** Pointer to the FullCPU object. */
163 /** Pointer to the exec context. Will not exist in the final version. */
166 /** The kind of fault this instruction has generated. */
169 /** The effective virtual address (lds & stores only). */
172 /** The effective physical address. */
175 /** Effective virtual address for a copy source. */
178 /** Effective physical address for a copy source. */
179 Addr copySrcPhysEffAddr;
181 /** The memory request flags (from translation). */
182 unsigned memReqFlags;
184 /** The size of the data to be stored. */
187 /** The data to be stored. */
190 /** Result of this instruction, if an integer. */
193 /** Result of this instruction, if a float. */
196 /** Result of this instruction, if a double. */
199 /** PC of this instruction. */
202 /** Next non-speculative PC. It is not filled in at fetch, but rather
203 * once the target of the branch is truly known (either decode or
208 /** Predicted next PC. */
211 /** Count of total number of dynamic instructions. */
212 static int instcount;
214 /** Did this instruction do a spec write? */
218 /** Physical register index of the destination registers of this
221 PhysRegIndex _destRegIdx[MaxInstDestRegs];
223 /** Physical register index of the source registers of this
226 PhysRegIndex _srcRegIdx[MaxInstSrcRegs];
228 /** Whether or not the source register is ready. */
229 bool _readySrcRegIdx[MaxInstSrcRegs];
231 /** Physical register index of the previous producers of the
232 * architected destinations.
234 PhysRegIndex _prevDestRegIdx[MaxInstDestRegs];
237 /** BaseDynInst constructor given a binary instruction. */
238 BaseDynInst(MachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
241 /** BaseDynInst constructor given a static inst pointer. */
242 BaseDynInst(StaticInstPtr<ISA> &_staticInst);
244 /** BaseDynInst destructor. */
249 mem_access(MemCmd cmd, // Read or Write access cmd
250 Addr addr, // virtual address of access
251 void *p, // input/output buffer
252 int nbytes); // access size
256 trace_mem(Fault fault, // last fault
257 MemCmd cmd, // last command
258 Addr addr, // virtual address of access
259 void *p, // memory accessed
260 int nbytes); // access size
262 /** Dumps out contents of this BaseDynInst. */
265 /** Dumps out contents of this BaseDynInst into given string. */
266 void dump(std::string &outstring);
268 /** Returns the fault type. */
269 Fault getFault() { return fault; }
271 /** Checks whether or not this instruction has had its branch target
272 * calculated yet. For now it is not utilized and is hacked to be
275 bool doneTargCalc() { return false; }
277 /** Returns the calculated target of the branch. */
278 Addr readCalcTarg() { return nextPC; }
280 Addr readNextPC() { return nextPC; }
282 /** Set the predicted target of this current instruction. */
283 void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; }
285 /** Returns the predicted target of the branch. */
286 Addr readPredTarg() { return predPC; }
288 /** Returns whether the instruction was predicted taken or not. */
290 // DPRINTF(FullCPU, "PC: %08p\n", PC);
291 // DPRINTF(FullCPU, "predPC: %08p\n", predPC);
293 return( predPC != (PC + sizeof(MachInst) ) );
296 /** Returns whether the instruction mispredicted. */
297 bool mispredicted() { return (predPC != nextPC); }
300 // Instruction types. Forward checks to StaticInst object.
302 bool isNop() const { return staticInst->isNop(); }
303 bool isMemRef() const { return staticInst->isMemRef(); }
304 bool isLoad() const { return staticInst->isLoad(); }
305 bool isStore() const { return staticInst->isStore(); }
306 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
307 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
308 bool isCopy() const { return staticInst->isCopy(); }
309 bool isInteger() const { return staticInst->isInteger(); }
310 bool isFloating() const { return staticInst->isFloating(); }
311 bool isControl() const { return staticInst->isControl(); }
312 bool isCall() const { return staticInst->isCall(); }
313 bool isReturn() const { return staticInst->isReturn(); }
314 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); }
315 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
316 bool isCondCtrl() const { return staticInst->isCondCtrl(); }
317 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); }
318 bool isThreadSync() const { return staticInst->isThreadSync(); }
319 bool isSerializing() const { return staticInst->isSerializing(); }
320 bool isMemBarrier() const { return staticInst->isMemBarrier(); }
321 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
322 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
324 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
325 int8_t numDestRegs() const { return staticInst->numDestRegs(); }
327 // the following are used to track physical register usage
328 // for machines with separate int & FP reg files
329 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); }
330 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
332 /** Returns the logical register index of the i'th destination register. */
333 RegIndex destRegIdx(int i) const
335 return staticInst->destRegIdx(i);
338 /** Returns the logical register index of the i'th source register. */
339 RegIndex srcRegIdx(int i) const
341 return staticInst->srcRegIdx(i);
344 /** Returns the physical register index of the i'th destination
347 PhysRegIndex renamedDestRegIdx(int idx) const
349 return _destRegIdx[idx];
352 /** Returns the physical register index of the i'th source register. */
353 PhysRegIndex renamedSrcRegIdx(int idx) const
355 return _srcRegIdx[idx];
358 bool isReadySrcRegIdx(int idx) const
360 return _readySrcRegIdx[idx];
363 /** Returns the physical register index of the previous physical register
364 * that remapped to the same logical register index.
366 PhysRegIndex prevDestRegIdx(int idx) const
368 return _prevDestRegIdx[idx];
371 /** Renames a destination register to a physical register. Also records
372 * the previous physical register that the logical register mapped to.
374 void renameDestReg(int idx,
375 PhysRegIndex renamed_dest,
376 PhysRegIndex previous_rename)
378 _destRegIdx[idx] = renamed_dest;
379 _prevDestRegIdx[idx] = previous_rename;
382 /** Renames a source logical register to the physical register which
383 * has/will produce that logical register's result.
384 * @todo: add in whether or not the source register is ready.
386 void renameSrcReg(int idx, PhysRegIndex renamed_src)
388 _srcRegIdx[idx] = renamed_src;
392 /** Records that one of the source registers is ready. */
393 void markSrcRegReady()
396 if(readyRegs == numSrcRegs()) {
401 void markSrcRegReady(RegIndex src_idx)
405 _readySrcRegIdx[src_idx] = 1;
407 if(readyRegs == numSrcRegs()) {
412 /** Sets this instruction as ready to issue. */
413 void setCanIssue() { canIssue = true; }
415 /** Returns whether or not this instruction is ready to issue. */
416 bool readyToIssue() const { return canIssue; }
418 /** Sets this instruction as issued from the IQ. */
419 void setIssued() { issued = true; }
421 /** Returns whether or not this instruction has issued. */
422 bool isIssued() { return issued; }
424 /** Sets this instruction as executed. */
425 void setExecuted() { executed = true; }
427 /** Returns whether or not this instruction has executed. */
428 bool isExecuted() { return executed; }
430 /** Sets this instruction as ready to commit. */
431 void setCanCommit() { canCommit = true; }
433 /** Returns whether or not this instruction is ready to commit. */
434 bool readyToCommit() const { return canCommit; }
436 /** Sets this instruction as squashed. */
437 void setSquashed() { squashed = true; }
439 /** Returns whether or not this instruction is squashed. */
440 bool isSquashed() const { return squashed; }
442 /** Sets this instruction as squashed in the IQ. */
443 void setSquashedInIQ() { squashedInIQ = true; }
445 /** Returns whether or not this instruction is squashed in the IQ. */
446 bool isSquashedInIQ() { return squashedInIQ; }
448 /** Returns the opclass of this instruction. */
449 OpClass opClass() const { return staticInst->opClass(); }
451 /** Returns whether or not the BTB missed. */
452 bool btbMiss() const { return btbMissed; }
454 /** Returns the branch target address. */
455 Addr branchTarget() const { return staticInst->branchTarget(PC); }
457 // The register accessor methods provide the index of the
458 // instruction's operand (e.g., 0 or 1), not the architectural
459 // register index, to simplify the implementation of register
460 // renaming. We find the architectural register index by indexing
461 // into the instruction's own operand index table. Note that a
462 // raw pointer to the StaticInst is provided instead of a
463 // ref-counted StaticInstPtr to redice overhead. This is fine as
464 // long as these methods don't copy the pointer into any long-term
465 // storage (which is pretty hard to imagine they would have reason
468 uint64_t readIntReg(StaticInst<ISA> *si, int idx)
470 return cpu->readIntReg(_srcRegIdx[idx]);
473 float readFloatRegSingle(StaticInst<ISA> *si, int idx)
475 return cpu->readFloatRegSingle(_srcRegIdx[idx]);
478 double readFloatRegDouble(StaticInst<ISA> *si, int idx)
480 return cpu->readFloatRegDouble(_srcRegIdx[idx]);
483 uint64_t readFloatRegInt(StaticInst<ISA> *si, int idx)
485 return cpu->readFloatRegInt(_srcRegIdx[idx]);
487 /** @todo: Make results into arrays so they can handle multiple dest
490 void setIntReg(StaticInst<ISA> *si, int idx, uint64_t val)
492 cpu->setIntReg(_destRegIdx[idx], val);
496 void setFloatRegSingle(StaticInst<ISA> *si, int idx, float val)
498 cpu->setFloatRegSingle(_destRegIdx[idx], val);
502 void setFloatRegDouble(StaticInst<ISA> *si, int idx, double val)
504 cpu->setFloatRegDouble(_destRegIdx[idx], val);
508 void setFloatRegInt(StaticInst<ISA> *si, int idx, uint64_t val)
510 cpu->setFloatRegInt(_destRegIdx[idx], val);
514 /** Read the PC of this instruction. */
515 Addr readPC() { return PC; }
517 /** Set the next PC of this instruction (its actual target). */
518 void setNextPC(uint64_t val) { nextPC = val; }
520 // bool misspeculating() { return cpu->misspeculating(); }
521 ExecContext *xcBase() { return xc; }
527 BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
529 MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags);
532 fault = cpu->translateDataReadReq(req);
534 // Record key MemReq parameters so we can generate another one
535 // just like it for the timing access without calling translate()
536 // again (which might mess up the TLB).
537 effAddr = req->vaddr;
538 physEffAddr = req->paddr;
539 memReqFlags = req->flags;
543 * Replace the disjoint functional memory with a unified one and remove
547 req->paddr = req->vaddr;
550 if (fault == No_Fault) {
551 fault = cpu->read(req, data);
554 // Return a fixed value to keep simulation deterministic even
555 // along misspeculated paths.
560 traceData->setAddr(addr);
561 traceData->setData(data);
570 BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
573 traceData->setAddr(addr);
574 traceData->setData(data);
577 storeSize = sizeof(T);
582 MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags);
586 fault = cpu->translateDataWriteReq(req);
588 // Record key MemReq parameters so we can generate another one
589 // just like it for the timing access without calling translate()
590 // again (which might mess up the TLB).
591 effAddr = req->vaddr;
592 physEffAddr = req->paddr;
593 memReqFlags = req->flags;
597 * Replace the disjoint functional memory with a unified one and remove
601 req->paddr = req->vaddr;
604 if (fault == No_Fault) {
605 fault = cpu->write(req, data);
609 // always return some result to keep misspeculated paths
610 // (which will ignore faults) deterministic
611 *res = (fault == No_Fault) ? req->result : 0;
617 #endif // __DYN_INST_HH__