2 * Copyright (c) 2014-2017 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::CCReg CCReg;
64 using VecRegContainer = TheISA::VecRegContainer;
65 using VecElem = TheISA::VecElem;
71 // This is the offset from the current pc that fetch should be performed
73 // This flag says to stay at the current pc. This is useful for
74 // instructions which go beyond MachInst boundaries.
78 TheISA::PCState predPC;
80 /** PER-THREAD STATS */
82 // Number of simulated instructions
84 Stats::Scalar numInsts;
88 // Number of integer alu accesses
89 Stats::Scalar numIntAluAccesses;
91 // Number of float alu accesses
92 Stats::Scalar numFpAluAccesses;
94 // Number of vector alu accesses
95 Stats::Scalar numVecAluAccesses;
97 // Number of function calls/returns
98 Stats::Scalar numCallsReturns;
100 // Conditional control instructions;
101 Stats::Scalar numCondCtrlInsts;
103 // Number of int instructions
104 Stats::Scalar numIntInsts;
106 // Number of float instructions
107 Stats::Scalar numFpInsts;
109 // Number of vector instructions
110 Stats::Scalar numVecInsts;
112 // Number of integer register file accesses
113 Stats::Scalar numIntRegReads;
114 Stats::Scalar numIntRegWrites;
116 // Number of float register file accesses
117 Stats::Scalar numFpRegReads;
118 Stats::Scalar numFpRegWrites;
120 // Number of vector register file accesses
121 mutable Stats::Scalar numVecRegReads;
122 Stats::Scalar numVecRegWrites;
124 // Number of predicate register file accesses
125 mutable Stats::Scalar numVecPredRegReads;
126 Stats::Scalar numVecPredRegWrites;
128 // Number of condition code register file accesses
129 Stats::Scalar numCCRegReads;
130 Stats::Scalar numCCRegWrites;
132 // Number of simulated memory references
133 Stats::Scalar numMemRefs;
134 Stats::Scalar numLoadInsts;
135 Stats::Scalar numStoreInsts;
137 // Number of idle cycles
138 Stats::Formula numIdleCycles;
140 // Number of busy cycles
141 Stats::Formula numBusyCycles;
143 // Number of simulated loads
146 // Number of idle cycles
147 Stats::Average notIdleFraction;
148 Stats::Formula idleFraction;
150 // Number of cycles stalled for I-cache responses
151 Stats::Scalar icacheStallCycles;
152 Counter lastIcacheStall;
154 // Number of cycles stalled for D-cache responses
155 Stats::Scalar dcacheStallCycles;
156 Counter lastDcacheStall;
159 /// Total number of branches fetched
160 Stats::Scalar numBranches;
161 /// Number of branches predicted as taken
162 Stats::Scalar numPredictedBranches;
163 /// Number of misprediced branches
164 Stats::Scalar numBranchMispred;
167 // Instruction mix histogram by OpClass
168 Stats::Vector statExecutedInstType;
172 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
173 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
174 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
177 /** Reads an integer register. */
179 readIntRegOperand(const StaticInst *si, int idx) override
182 const RegId& reg = si->srcRegIdx(idx);
183 assert(reg.isIntReg());
184 return thread->readIntReg(reg.index());
187 /** Sets an integer register to a value. */
189 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
192 const RegId& reg = si->destRegIdx(idx);
193 assert(reg.isIntReg());
194 thread->setIntReg(reg.index(), val);
197 /** Reads a floating point register in its binary format, instead
200 readFloatRegOperandBits(const StaticInst *si, int idx) override
203 const RegId& reg = si->srcRegIdx(idx);
204 assert(reg.isFloatReg());
205 return thread->readFloatReg(reg.index());
208 /** Sets the bits of a floating point register of single width
209 * to a binary value. */
211 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
214 const RegId& reg = si->destRegIdx(idx);
215 assert(reg.isFloatReg());
216 thread->setFloatReg(reg.index(), val);
219 /** Reads a vector register. */
220 const VecRegContainer &
221 readVecRegOperand(const StaticInst *si, int idx) const override
224 const RegId& reg = si->srcRegIdx(idx);
225 assert(reg.isVecReg());
226 return thread->readVecReg(reg);
229 /** Reads a vector register for modification. */
231 getWritableVecRegOperand(const StaticInst *si, int idx) override
234 const RegId& reg = si->destRegIdx(idx);
235 assert(reg.isVecReg());
236 return thread->getWritableVecReg(reg);
239 /** Sets a vector register to a value. */
241 setVecRegOperand(const StaticInst *si, int idx,
242 const VecRegContainer& val) override
245 const RegId& reg = si->destRegIdx(idx);
246 assert(reg.isVecReg());
247 thread->setVecReg(reg, val);
250 /** Vector Register Lane Interfaces. */
252 /** Reads source vector lane. */
253 template <typename VecElem>
254 VecLaneT<VecElem, true>
255 readVecLaneOperand(const StaticInst *si, int idx) const
258 const RegId& reg = si->srcRegIdx(idx);
259 assert(reg.isVecReg());
260 return thread->readVecLane<VecElem>(reg);
262 /** Reads source vector 8bit operand. */
263 virtual ConstVecLane8
264 readVec8BitLaneOperand(const StaticInst *si, int idx) const
266 { return readVecLaneOperand<uint8_t>(si, idx); }
268 /** Reads source vector 16bit operand. */
269 virtual ConstVecLane16
270 readVec16BitLaneOperand(const StaticInst *si, int idx) const
272 { return readVecLaneOperand<uint16_t>(si, idx); }
274 /** Reads source vector 32bit operand. */
275 virtual ConstVecLane32
276 readVec32BitLaneOperand(const StaticInst *si, int idx) const
278 { return readVecLaneOperand<uint32_t>(si, idx); }
280 /** Reads source vector 64bit operand. */
281 virtual ConstVecLane64
282 readVec64BitLaneOperand(const StaticInst *si, int idx) const
284 { return readVecLaneOperand<uint64_t>(si, idx); }
286 /** Write a lane of the destination vector operand. */
287 template <typename LD>
289 setVecLaneOperandT(const StaticInst *si, int idx,
293 const RegId& reg = si->destRegIdx(idx);
294 assert(reg.isVecReg());
295 return thread->setVecLane(reg, val);
297 /** Write a lane of the destination vector operand. */
299 setVecLaneOperand(const StaticInst *si, int idx,
300 const LaneData<LaneSize::Byte>& val) override
301 { return setVecLaneOperandT(si, idx, val); }
302 /** Write a lane of the destination vector operand. */
304 setVecLaneOperand(const StaticInst *si, int idx,
305 const LaneData<LaneSize::TwoByte>& val) override
306 { return setVecLaneOperandT(si, idx, val); }
307 /** Write a lane of the destination vector operand. */
309 setVecLaneOperand(const StaticInst *si, int idx,
310 const LaneData<LaneSize::FourByte>& val) override
311 { return setVecLaneOperandT(si, idx, val); }
312 /** Write a lane of the destination vector operand. */
314 setVecLaneOperand(const StaticInst *si, int idx,
315 const LaneData<LaneSize::EightByte>& val) override
316 { return setVecLaneOperandT(si, idx, val); }
319 /** Reads an element of a vector register. */
321 readVecElemOperand(const StaticInst *si, int idx) const override
324 const RegId& reg = si->srcRegIdx(idx);
325 assert(reg.isVecElem());
326 return thread->readVecElem(reg);
329 /** Sets an element of a vector register to a value. */
331 setVecElemOperand(const StaticInst *si, int idx,
332 const VecElem val) override
335 const RegId& reg = si->destRegIdx(idx);
336 assert(reg.isVecElem());
337 thread->setVecElem(reg, val);
340 const VecPredRegContainer&
341 readVecPredRegOperand(const StaticInst *si, int idx) const override
343 numVecPredRegReads++;
344 const RegId& reg = si->srcRegIdx(idx);
345 assert(reg.isVecPredReg());
346 return thread->readVecPredReg(reg);
350 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
352 numVecPredRegWrites++;
353 const RegId& reg = si->destRegIdx(idx);
354 assert(reg.isVecPredReg());
355 return thread->getWritableVecPredReg(reg);
359 setVecPredRegOperand(const StaticInst *si, int idx,
360 const VecPredRegContainer& val) override
362 numVecPredRegWrites++;
363 const RegId& reg = si->destRegIdx(idx);
364 assert(reg.isVecPredReg());
365 thread->setVecPredReg(reg, val);
369 readCCRegOperand(const StaticInst *si, int idx) override
372 const RegId& reg = si->srcRegIdx(idx);
373 assert(reg.isCCReg());
374 return thread->readCCReg(reg.index());
378 setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
381 const RegId& reg = si->destRegIdx(idx);
382 assert(reg.isCCReg());
383 thread->setCCReg(reg.index(), val);
387 readMiscRegOperand(const StaticInst *si, int idx) override
390 const RegId& reg = si->srcRegIdx(idx);
391 assert(reg.isMiscReg());
392 return thread->readMiscReg(reg.index());
396 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
399 const RegId& reg = si->destRegIdx(idx);
400 assert(reg.isMiscReg());
401 thread->setMiscReg(reg.index(), val);
405 * Reads a miscellaneous register, handling any architectural
406 * side effects due to reading that register.
409 readMiscReg(int misc_reg) override
412 return thread->readMiscReg(misc_reg);
416 * Sets a miscellaneous register, handling any architectural
417 * side effects due to writing that register.
420 setMiscReg(int misc_reg, RegVal val) override
423 thread->setMiscReg(misc_reg, val);
427 pcState() const override
429 return thread->pcState();
433 pcState(const PCState &val) override
435 thread->pcState(val);
440 readMem(Addr addr, uint8_t *data, unsigned int size,
441 Request::Flags flags) override
443 return cpu->readMem(addr, data, size, flags);
447 initiateMemRead(Addr addr, unsigned int size,
448 Request::Flags flags) override
450 return cpu->initiateMemRead(addr, size, flags);
454 writeMem(uint8_t *data, unsigned int size, Addr addr,
455 Request::Flags flags, uint64_t *res) override
457 return cpu->writeMem(data, size, addr, flags, res);
461 * Sets the number of consecutive store conditional failures.
464 setStCondFailures(unsigned int sc_failures) override
466 thread->setStCondFailures(sc_failures);
470 * Returns the number of consecutive store conditional failures.
473 readStCondFailures() const override
475 return thread->readStCondFailures();
479 * Executes a syscall specified by the callnum.
482 syscall(int64_t callnum, Fault *fault) override
485 panic("Syscall emulation isn't available in FS mode.");
487 thread->syscall(callnum, fault);
490 /** Returns a pointer to the ThreadContext. */
491 ThreadContext *tcBase() override { return thread->getTC(); }
494 * Somewhat Alpha-specific function that handles returning from an
495 * error or interrupt.
497 Fault hwrei() override { return thread->hwrei(); }
500 * Check for special simulator handling of specific PAL calls. If
501 * return value is false, actual PAL call will be suppressed.
504 simPalCheck(int palFunc) override
506 return thread->simPalCheck(palFunc);
510 readPredicate() const override
512 return thread->readPredicate();
516 setPredicate(bool val) override
518 thread->setPredicate(val);
520 if (cpu->traceData) {
521 cpu->traceData->setPredicate(val);
526 * Invalidate a page in the DTLB <i>and</i> ITLB.
529 demapPage(Addr vaddr, uint64_t asn) override
531 thread->demapPage(vaddr, asn);
535 armMonitor(Addr address) override
537 cpu->armMonitor(thread->threadId(), address);
541 mwait(PacketPtr pkt) override
543 return cpu->mwait(thread->threadId(), pkt);
547 mwaitAtomic(ThreadContext *tc) override
549 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
553 getAddrMonitor() override
555 return cpu->getCpuAddrMonitor(thread->threadId());
558 #if THE_ISA == MIPS_ISA
560 readRegOtherThread(const RegId& reg, ThreadID tid=InvalidThreadID)
563 panic("Simple CPU models do not support multithreaded "
568 setRegOtherThread(const RegId& reg, RegVal val,
569 ThreadID tid=InvalidThreadID) override
571 panic("Simple CPU models do not support multithreaded "
578 #endif // __CPU_EXEC_CONTEXT_HH__