2 * Copyright (c) 2014-2016 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 #ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
46 #define __CPU_SIMPLE_EXEC_CONTEXT_HH__
48 #include "arch/registers.hh"
49 #include "base/types.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/base.hh"
52 #include "cpu/exec_context.hh"
53 #include "cpu/reg_class.hh"
54 #include "cpu/simple/base.hh"
55 #include "cpu/static_inst_fwd.hh"
56 #include "cpu/translation.hh"
57 #include "mem/request.hh"
61 class SimpleExecContext : public ExecContext {
63 typedef TheISA::MiscReg MiscReg;
64 typedef TheISA::FloatReg FloatReg;
65 typedef TheISA::FloatRegBits FloatRegBits;
66 typedef TheISA::CCReg CCReg;
67 using VecRegContainer = TheISA::VecRegContainer;
68 using VecElem = TheISA::VecElem;
74 // This is the offset from the current pc that fetch should be performed
76 // This flag says to stay at the current pc. This is useful for
77 // instructions which go beyond MachInst boundaries.
81 TheISA::PCState predPC;
83 /** PER-THREAD STATS */
85 // Number of simulated instructions
87 Stats::Scalar numInsts;
91 // Number of integer alu accesses
92 Stats::Scalar numIntAluAccesses;
94 // Number of float alu accesses
95 Stats::Scalar numFpAluAccesses;
97 // Number of vector alu accesses
98 Stats::Scalar numVecAluAccesses;
100 // Number of function calls/returns
101 Stats::Scalar numCallsReturns;
103 // Conditional control instructions;
104 Stats::Scalar numCondCtrlInsts;
106 // Number of int instructions
107 Stats::Scalar numIntInsts;
109 // Number of float instructions
110 Stats::Scalar numFpInsts;
112 // Number of vector instructions
113 Stats::Scalar numVecInsts;
115 // Number of integer register file accesses
116 Stats::Scalar numIntRegReads;
117 Stats::Scalar numIntRegWrites;
119 // Number of float register file accesses
120 Stats::Scalar numFpRegReads;
121 Stats::Scalar numFpRegWrites;
123 // Number of vector register file accesses
124 mutable Stats::Scalar numVecRegReads;
125 Stats::Scalar numVecRegWrites;
127 // Number of condition code register file accesses
128 Stats::Scalar numCCRegReads;
129 Stats::Scalar numCCRegWrites;
131 // Number of simulated memory references
132 Stats::Scalar numMemRefs;
133 Stats::Scalar numLoadInsts;
134 Stats::Scalar numStoreInsts;
136 // Number of idle cycles
137 Stats::Formula numIdleCycles;
139 // Number of busy cycles
140 Stats::Formula numBusyCycles;
142 // Number of simulated loads
145 // Number of idle cycles
146 Stats::Average notIdleFraction;
147 Stats::Formula idleFraction;
149 // Number of cycles stalled for I-cache responses
150 Stats::Scalar icacheStallCycles;
151 Counter lastIcacheStall;
153 // Number of cycles stalled for D-cache responses
154 Stats::Scalar dcacheStallCycles;
155 Counter lastDcacheStall;
158 /// Total number of branches fetched
159 Stats::Scalar numBranches;
160 /// Number of branches predicted as taken
161 Stats::Scalar numPredictedBranches;
162 /// Number of misprediced branches
163 Stats::Scalar numBranchMispred;
166 // Instruction mix histogram by OpClass
167 Stats::Vector statExecutedInstType;
171 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
172 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
173 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
176 /** Reads an integer register. */
177 IntReg readIntRegOperand(const StaticInst *si, int idx) override
180 const RegId& reg = si->srcRegIdx(idx);
181 assert(reg.isIntReg());
182 return thread->readIntReg(reg.index());
185 /** Sets an integer register to a value. */
186 void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
189 const RegId& reg = si->destRegIdx(idx);
190 assert(reg.isIntReg());
191 thread->setIntReg(reg.index(), val);
194 /** Reads a floating point register of single register width. */
195 FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
198 const RegId& reg = si->srcRegIdx(idx);
199 assert(reg.isFloatReg());
200 return thread->readFloatReg(reg.index());
203 /** Reads a floating point register in its binary format, instead
205 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
208 const RegId& reg = si->srcRegIdx(idx);
209 assert(reg.isFloatReg());
210 return thread->readFloatRegBits(reg.index());
213 /** Sets a floating point register of single width to a value. */
214 void setFloatRegOperand(const StaticInst *si, int idx,
215 FloatReg val) override
218 const RegId& reg = si->destRegIdx(idx);
219 assert(reg.isFloatReg());
220 thread->setFloatReg(reg.index(), val);
223 /** Sets the bits of a floating point register of single width
224 * to a binary value. */
225 void setFloatRegOperandBits(const StaticInst *si, int idx,
226 FloatRegBits val) override
229 const RegId& reg = si->destRegIdx(idx);
230 assert(reg.isFloatReg());
231 thread->setFloatRegBits(reg.index(), val);
234 /** Reads a vector register. */
235 const VecRegContainer&
236 readVecRegOperand(const StaticInst *si, int idx) const override
239 const RegId& reg = si->srcRegIdx(idx);
240 assert(reg.isVecReg());
241 return thread->readVecReg(reg);
244 /** Reads a vector register for modification. */
246 getWritableVecRegOperand(const StaticInst *si, int idx) override
249 const RegId& reg = si->destRegIdx(idx);
250 assert(reg.isVecReg());
251 return thread->getWritableVecReg(reg);
254 /** Sets a vector register to a value. */
255 void setVecRegOperand(const StaticInst *si, int idx,
256 const VecRegContainer& val) override
259 const RegId& reg = si->destRegIdx(idx);
260 assert(reg.isVecReg());
261 thread->setVecReg(reg, val);
264 /** Vector Register Lane Interfaces. */
266 /** Reads source vector lane. */
267 template <typename VecElem>
268 VecLaneT<VecElem, true>
269 readVecLaneOperand(const StaticInst *si, int idx) const
272 const RegId& reg = si->srcRegIdx(idx);
273 assert(reg.isVecReg());
274 return thread->readVecLane<VecElem>(reg);
276 /** Reads source vector 8bit operand. */
277 virtual ConstVecLane8
278 readVec8BitLaneOperand(const StaticInst *si, int idx) const
280 { return readVecLaneOperand<uint8_t>(si, idx); }
282 /** Reads source vector 16bit operand. */
283 virtual ConstVecLane16
284 readVec16BitLaneOperand(const StaticInst *si, int idx) const
286 { return readVecLaneOperand<uint16_t>(si, idx); }
288 /** Reads source vector 32bit operand. */
289 virtual ConstVecLane32
290 readVec32BitLaneOperand(const StaticInst *si, int idx) const
292 { return readVecLaneOperand<uint32_t>(si, idx); }
294 /** Reads source vector 64bit operand. */
295 virtual ConstVecLane64
296 readVec64BitLaneOperand(const StaticInst *si, int idx) const
298 { return readVecLaneOperand<uint64_t>(si, idx); }
300 /** Write a lane of the destination vector operand. */
301 template <typename LD>
303 setVecLaneOperandT(const StaticInst *si, int idx,
307 const RegId& reg = si->destRegIdx(idx);
308 assert(reg.isVecReg());
309 return thread->setVecLane(reg, val);
311 /** Write a lane of the destination vector operand. */
313 setVecLaneOperand(const StaticInst *si, int idx,
314 const LaneData<LaneSize::Byte>& val) override
315 { return setVecLaneOperandT(si, idx, val); }
316 /** Write a lane of the destination vector operand. */
318 setVecLaneOperand(const StaticInst *si, int idx,
319 const LaneData<LaneSize::TwoByte>& val) override
320 { return setVecLaneOperandT(si, idx, val); }
321 /** Write a lane of the destination vector operand. */
323 setVecLaneOperand(const StaticInst *si, int idx,
324 const LaneData<LaneSize::FourByte>& val) override
325 { return setVecLaneOperandT(si, idx, val); }
326 /** Write a lane of the destination vector operand. */
328 setVecLaneOperand(const StaticInst *si, int idx,
329 const LaneData<LaneSize::EightByte>& val) override
330 { return setVecLaneOperandT(si, idx, val); }
333 /** Reads an element of a vector register. */
334 VecElem readVecElemOperand(const StaticInst *si, int idx) const override
337 const RegId& reg = si->destRegIdx(idx);
338 assert(reg.isVecElem());
339 return thread->readVecElem(reg);
342 /** Sets an element of a vector register to a value. */
343 void setVecElemOperand(const StaticInst *si, int idx,
344 const VecElem val) override
347 const RegId& reg = si->destRegIdx(idx);
348 assert(reg.isVecElem());
349 thread->setVecElem(reg, val);
352 CCReg readCCRegOperand(const StaticInst *si, int idx) override
355 const RegId& reg = si->srcRegIdx(idx);
356 assert(reg.isCCReg());
357 return thread->readCCReg(reg.index());
360 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
363 const RegId& reg = si->destRegIdx(idx);
364 assert(reg.isCCReg());
365 thread->setCCReg(reg.index(), val);
368 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
371 const RegId& reg = si->srcRegIdx(idx);
372 assert(reg.isMiscReg());
373 return thread->readMiscReg(reg.index());
376 void setMiscRegOperand(const StaticInst *si, int idx,
377 const MiscReg &val) override
380 const RegId& reg = si->destRegIdx(idx);
381 assert(reg.isMiscReg());
382 thread->setMiscReg(reg.index(), val);
386 * Reads a miscellaneous register, handling any architectural
387 * side effects due to reading that register.
389 MiscReg readMiscReg(int misc_reg) override
392 return thread->readMiscReg(misc_reg);
396 * Sets a miscellaneous register, handling any architectural
397 * side effects due to writing that register.
399 void setMiscReg(int misc_reg, const MiscReg &val) override
402 thread->setMiscReg(misc_reg, val);
405 PCState pcState() const override
407 return thread->pcState();
410 void pcState(const PCState &val) override
412 thread->pcState(val);
417 * Record the effective address of the instruction.
419 * @note Only valid for memory ops.
421 void setEA(Addr EA) override
422 { panic("BaseSimpleCPU::setEA() not implemented\n"); }
425 * Get the effective address of the instruction.
427 * @note Only valid for memory ops.
429 Addr getEA() const override
430 { panic("BaseSimpleCPU::getEA() not implemented\n"); }
432 Fault readMem(Addr addr, uint8_t *data, unsigned int size,
433 Request::Flags flags) override
435 return cpu->readMem(addr, data, size, flags);
438 Fault initiateMemRead(Addr addr, unsigned int size,
439 Request::Flags flags) override
441 return cpu->initiateMemRead(addr, size, flags);
444 Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
445 Request::Flags flags, uint64_t *res) override
447 return cpu->writeMem(data, size, addr, flags, res);
451 * Sets the number of consecutive store conditional failures.
453 void setStCondFailures(unsigned int sc_failures) override
455 thread->setStCondFailures(sc_failures);
459 * Returns the number of consecutive store conditional failures.
461 unsigned int readStCondFailures() const override
463 return thread->readStCondFailures();
467 * Executes a syscall specified by the callnum.
469 void syscall(int64_t callnum, Fault *fault) override
472 panic("Syscall emulation isn't available in FS mode.");
474 thread->syscall(callnum, fault);
477 /** Returns a pointer to the ThreadContext. */
478 ThreadContext *tcBase() override
480 return thread->getTC();
484 * Somewhat Alpha-specific function that handles returning from an
485 * error or interrupt.
487 Fault hwrei() override
489 return thread->hwrei();
493 * Check for special simulator handling of specific PAL calls. If
494 * return value is false, actual PAL call will be suppressed.
496 bool simPalCheck(int palFunc) override
498 return thread->simPalCheck(palFunc);
501 bool readPredicate() override
503 return thread->readPredicate();
506 void setPredicate(bool val) override
508 thread->setPredicate(val);
510 if (cpu->traceData) {
511 cpu->traceData->setPredicate(val);
516 * Invalidate a page in the DTLB <i>and</i> ITLB.
518 void demapPage(Addr vaddr, uint64_t asn) override
520 thread->demapPage(vaddr, asn);
523 void armMonitor(Addr address) override
525 cpu->armMonitor(thread->threadId(), address);
528 bool mwait(PacketPtr pkt) override
530 return cpu->mwait(thread->threadId(), pkt);
533 void mwaitAtomic(ThreadContext *tc) override
535 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
538 AddressMonitor *getAddrMonitor() override
540 return cpu->getCpuAddrMonitor(thread->threadId());
543 #if THE_ISA == MIPS_ISA
544 MiscReg readRegOtherThread(const RegId& reg,
545 ThreadID tid = InvalidThreadID)
548 panic("Simple CPU models do not support multithreaded "
552 void setRegOtherThread(const RegId& reg, MiscReg val,
553 ThreadID tid = InvalidThreadID) override
555 panic("Simple CPU models do not support multithreaded "
563 #endif // __CPU_EXEC_CONTEXT_HH__