2 * Copyright (c) 2014-2018, 2020 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.
41 #ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
42 #define __CPU_SIMPLE_EXEC_CONTEXT_HH__
44 #include "arch/registers.hh"
45 #include "base/types.hh"
46 #include "config/the_isa.hh"
47 #include "cpu/base.hh"
48 #include "cpu/exec_context.hh"
49 #include "cpu/reg_class.hh"
50 #include "cpu/simple/base.hh"
51 #include "cpu/static_inst_fwd.hh"
52 #include "cpu/translation.hh"
53 #include "mem/request.hh"
57 class SimpleExecContext : public ExecContext {
59 using VecRegContainer = TheISA::VecRegContainer;
60 using VecElem = TheISA::VecElem;
66 // This is the offset from the current pc that fetch should be performed
68 // This flag says to stay at the current pc. This is useful for
69 // instructions which go beyond MachInst boundaries.
73 TheISA::PCState predPC;
75 /** PER-THREAD STATS */
77 // Number of simulated instructions
79 Stats::Scalar numInsts;
83 // Number of integer alu accesses
84 Stats::Scalar numIntAluAccesses;
86 // Number of float alu accesses
87 Stats::Scalar numFpAluAccesses;
89 // Number of vector alu accesses
90 Stats::Scalar numVecAluAccesses;
92 // Number of function calls/returns
93 Stats::Scalar numCallsReturns;
95 // Conditional control instructions;
96 Stats::Scalar numCondCtrlInsts;
98 // Number of int instructions
99 Stats::Scalar numIntInsts;
101 // Number of float instructions
102 Stats::Scalar numFpInsts;
104 // Number of vector instructions
105 Stats::Scalar numVecInsts;
107 // Number of integer register file accesses
108 Stats::Scalar numIntRegReads;
109 Stats::Scalar numIntRegWrites;
111 // Number of float register file accesses
112 Stats::Scalar numFpRegReads;
113 Stats::Scalar numFpRegWrites;
115 // Number of vector register file accesses
116 mutable Stats::Scalar numVecRegReads;
117 Stats::Scalar numVecRegWrites;
119 // Number of predicate register file accesses
120 mutable Stats::Scalar numVecPredRegReads;
121 Stats::Scalar numVecPredRegWrites;
123 // Number of condition code register file accesses
124 Stats::Scalar numCCRegReads;
125 Stats::Scalar numCCRegWrites;
127 // Number of simulated memory references
128 Stats::Scalar numMemRefs;
129 Stats::Scalar numLoadInsts;
130 Stats::Scalar numStoreInsts;
132 // Number of idle cycles
133 Stats::Formula numIdleCycles;
135 // Number of busy cycles
136 Stats::Formula numBusyCycles;
138 // Number of simulated loads
141 // Number of idle cycles
142 Stats::Average notIdleFraction;
143 Stats::Formula idleFraction;
145 // Number of cycles stalled for I-cache responses
146 Stats::Scalar icacheStallCycles;
147 Counter lastIcacheStall;
149 // Number of cycles stalled for D-cache responses
150 Stats::Scalar dcacheStallCycles;
151 Counter lastDcacheStall;
154 /// Total number of branches fetched
155 Stats::Scalar numBranches;
156 /// Number of branches predicted as taken
157 Stats::Scalar numPredictedBranches;
158 /// Number of misprediced branches
159 Stats::Scalar numBranchMispred;
162 // Instruction mix histogram by OpClass
163 Stats::Vector statExecutedInstType;
167 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
168 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
169 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
172 /** Reads an integer register. */
174 readIntRegOperand(const StaticInst *si, int idx) override
177 const RegId& reg = si->srcRegIdx(idx);
178 assert(reg.isIntReg());
179 return thread->readIntReg(reg.index());
182 /** Sets an integer register to a value. */
184 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
187 const RegId& reg = si->destRegIdx(idx);
188 assert(reg.isIntReg());
189 thread->setIntReg(reg.index(), val);
192 /** Reads a floating point register in its binary format, instead
195 readFloatRegOperandBits(const StaticInst *si, int idx) override
198 const RegId& reg = si->srcRegIdx(idx);
199 assert(reg.isFloatReg());
200 return thread->readFloatReg(reg.index());
203 /** Sets the bits of a floating point register of single width
204 * to a binary value. */
206 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
209 const RegId& reg = si->destRegIdx(idx);
210 assert(reg.isFloatReg());
211 thread->setFloatReg(reg.index(), val);
214 /** Reads a vector register. */
215 const VecRegContainer &
216 readVecRegOperand(const StaticInst *si, int idx) const override
219 const RegId& reg = si->srcRegIdx(idx);
220 assert(reg.isVecReg());
221 return thread->readVecReg(reg);
224 /** Reads a vector register for modification. */
226 getWritableVecRegOperand(const StaticInst *si, int idx) override
229 const RegId& reg = si->destRegIdx(idx);
230 assert(reg.isVecReg());
231 return thread->getWritableVecReg(reg);
234 /** Sets a vector register to a value. */
236 setVecRegOperand(const StaticInst *si, int idx,
237 const VecRegContainer& val) override
240 const RegId& reg = si->destRegIdx(idx);
241 assert(reg.isVecReg());
242 thread->setVecReg(reg, val);
245 /** Vector Register Lane Interfaces. */
247 /** Reads source vector lane. */
248 template <typename VecElem>
249 VecLaneT<VecElem, true>
250 readVecLaneOperand(const StaticInst *si, int idx) const
253 const RegId& reg = si->srcRegIdx(idx);
254 assert(reg.isVecReg());
255 return thread->readVecLane<VecElem>(reg);
257 /** Reads source vector 8bit operand. */
258 virtual ConstVecLane8
259 readVec8BitLaneOperand(const StaticInst *si, int idx) const
261 { return readVecLaneOperand<uint8_t>(si, idx); }
263 /** Reads source vector 16bit operand. */
264 virtual ConstVecLane16
265 readVec16BitLaneOperand(const StaticInst *si, int idx) const
267 { return readVecLaneOperand<uint16_t>(si, idx); }
269 /** Reads source vector 32bit operand. */
270 virtual ConstVecLane32
271 readVec32BitLaneOperand(const StaticInst *si, int idx) const
273 { return readVecLaneOperand<uint32_t>(si, idx); }
275 /** Reads source vector 64bit operand. */
276 virtual ConstVecLane64
277 readVec64BitLaneOperand(const StaticInst *si, int idx) const
279 { return readVecLaneOperand<uint64_t>(si, idx); }
281 /** Write a lane of the destination vector operand. */
282 template <typename LD>
284 setVecLaneOperandT(const StaticInst *si, int idx,
288 const RegId& reg = si->destRegIdx(idx);
289 assert(reg.isVecReg());
290 return thread->setVecLane(reg, val);
292 /** Write a lane of the destination vector operand. */
294 setVecLaneOperand(const StaticInst *si, int idx,
295 const LaneData<LaneSize::Byte>& val) override
296 { return setVecLaneOperandT(si, idx, val); }
297 /** Write a lane of the destination vector operand. */
299 setVecLaneOperand(const StaticInst *si, int idx,
300 const LaneData<LaneSize::TwoByte>& 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::FourByte>& 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::EightByte>& val) override
311 { return setVecLaneOperandT(si, idx, val); }
314 /** Reads an element of a vector register. */
316 readVecElemOperand(const StaticInst *si, int idx) const override
319 const RegId& reg = si->srcRegIdx(idx);
320 assert(reg.isVecElem());
321 return thread->readVecElem(reg);
324 /** Sets an element of a vector register to a value. */
326 setVecElemOperand(const StaticInst *si, int idx,
327 const VecElem val) override
330 const RegId& reg = si->destRegIdx(idx);
331 assert(reg.isVecElem());
332 thread->setVecElem(reg, val);
335 const VecPredRegContainer&
336 readVecPredRegOperand(const StaticInst *si, int idx) const override
338 numVecPredRegReads++;
339 const RegId& reg = si->srcRegIdx(idx);
340 assert(reg.isVecPredReg());
341 return thread->readVecPredReg(reg);
345 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
347 numVecPredRegWrites++;
348 const RegId& reg = si->destRegIdx(idx);
349 assert(reg.isVecPredReg());
350 return thread->getWritableVecPredReg(reg);
354 setVecPredRegOperand(const StaticInst *si, int idx,
355 const VecPredRegContainer& val) override
357 numVecPredRegWrites++;
358 const RegId& reg = si->destRegIdx(idx);
359 assert(reg.isVecPredReg());
360 thread->setVecPredReg(reg, val);
364 readCCRegOperand(const StaticInst *si, int idx) override
367 const RegId& reg = si->srcRegIdx(idx);
368 assert(reg.isCCReg());
369 return thread->readCCReg(reg.index());
373 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
376 const RegId& reg = si->destRegIdx(idx);
377 assert(reg.isCCReg());
378 thread->setCCReg(reg.index(), val);
382 readMiscRegOperand(const StaticInst *si, int idx) override
385 const RegId& reg = si->srcRegIdx(idx);
386 assert(reg.isMiscReg());
387 return thread->readMiscReg(reg.index());
391 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
394 const RegId& reg = si->destRegIdx(idx);
395 assert(reg.isMiscReg());
396 thread->setMiscReg(reg.index(), val);
400 * Reads a miscellaneous register, handling any architectural
401 * side effects due to reading that register.
404 readMiscReg(int misc_reg) override
407 return thread->readMiscReg(misc_reg);
411 * Sets a miscellaneous register, handling any architectural
412 * side effects due to writing that register.
415 setMiscReg(int misc_reg, RegVal val) override
418 thread->setMiscReg(misc_reg, val);
422 pcState() const override
424 return thread->pcState();
428 pcState(const PCState &val) override
430 thread->pcState(val);
434 readMem(Addr addr, uint8_t *data, unsigned int size,
435 Request::Flags flags,
436 const std::vector<bool>& byte_enable)
439 assert(byte_enable.size() == size);
440 return cpu->readMem(addr, data, size, flags, byte_enable);
444 initiateMemRead(Addr addr, unsigned int size,
445 Request::Flags flags,
446 const std::vector<bool>& byte_enable)
449 assert(byte_enable.size() == size);
450 return cpu->initiateMemRead(addr, size, flags, byte_enable);
454 writeMem(uint8_t *data, unsigned int size, Addr addr,
455 Request::Flags flags, uint64_t *res,
456 const std::vector<bool>& byte_enable)
459 assert(byte_enable.size() == size);
460 return cpu->writeMem(data, size, addr, flags, res,
464 Fault amoMem(Addr addr, uint8_t *data, unsigned int size,
465 Request::Flags flags, AtomicOpFunctorPtr amo_op) override
467 return cpu->amoMem(addr, data, size, flags, std::move(amo_op));
470 Fault initiateMemAMO(Addr addr, unsigned int size,
471 Request::Flags flags,
472 AtomicOpFunctorPtr amo_op) override
474 return cpu->initiateMemAMO(addr, size, flags, std::move(amo_op));
477 Fault initiateHtmCmd(Request::Flags flags) override
479 return cpu->initiateHtmCmd(flags);
483 * Sets the number of consecutive store conditional failures.
486 setStCondFailures(unsigned int sc_failures) override
488 thread->setStCondFailures(sc_failures);
492 * Returns the number of consecutive store conditional failures.
495 readStCondFailures() const override
497 return thread->readStCondFailures();
500 /** Returns a pointer to the ThreadContext. */
501 ThreadContext *tcBase() const override { return thread->getTC(); }
504 readPredicate() const override
506 return thread->readPredicate();
510 setPredicate(bool val) override
512 thread->setPredicate(val);
514 if (cpu->traceData) {
515 cpu->traceData->setPredicate(val);
520 readMemAccPredicate() const override
522 return thread->readMemAccPredicate();
526 setMemAccPredicate(bool val) override
528 thread->setMemAccPredicate(val);
532 getHtmTransactionUid() const override
534 return tcBase()->getHtmCheckpointPtr()->getHtmUid();
538 newHtmTransactionUid() const override
540 return tcBase()->getHtmCheckpointPtr()->newHtmUid();
544 inHtmTransactionalState() const override
546 return (getHtmTransactionalDepth() > 0);
550 getHtmTransactionalDepth() const override
552 assert(thread->htmTransactionStarts >= thread->htmTransactionStops);
553 return (thread->htmTransactionStarts - thread->htmTransactionStops);
557 * Invalidate a page in the DTLB <i>and</i> ITLB.
560 demapPage(Addr vaddr, uint64_t asn) override
562 thread->demapPage(vaddr, asn);
566 armMonitor(Addr address) override
568 cpu->armMonitor(thread->threadId(), address);
572 mwait(PacketPtr pkt) override
574 return cpu->mwait(thread->threadId(), pkt);
578 mwaitAtomic(ThreadContext *tc) override
580 cpu->mwaitAtomic(thread->threadId(), tc, thread->mmu);
584 getAddrMonitor() override
586 return cpu->getCpuAddrMonitor(thread->threadId());
590 #endif // __CPU_EXEC_CONTEXT_HH__