misc: BaseCPU using ArchMMU instead of ArchDTB/ArchITB
[gem5.git] / src / cpu / simple / exec_context.hh
1 /*
2 * Copyright (c) 2014-2018, 2020 ARM Limited
3 * All rights reserved
4 *
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.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
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.
27 *
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.
39 */
40
41 #ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
42 #define __CPU_SIMPLE_EXEC_CONTEXT_HH__
43
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"
54
55 class BaseSimpleCPU;
56
57 class SimpleExecContext : public ExecContext {
58 protected:
59 using VecRegContainer = TheISA::VecRegContainer;
60 using VecElem = TheISA::VecElem;
61
62 public:
63 BaseSimpleCPU *cpu;
64 SimpleThread* thread;
65
66 // This is the offset from the current pc that fetch should be performed
67 Addr fetchOffset;
68 // This flag says to stay at the current pc. This is useful for
69 // instructions which go beyond MachInst boundaries.
70 bool stayAtPC;
71
72 // Branch prediction
73 TheISA::PCState predPC;
74
75 /** PER-THREAD STATS */
76
77 // Number of simulated instructions
78 Counter numInst;
79 Stats::Scalar numInsts;
80 Counter numOp;
81 Stats::Scalar numOps;
82
83 // Number of integer alu accesses
84 Stats::Scalar numIntAluAccesses;
85
86 // Number of float alu accesses
87 Stats::Scalar numFpAluAccesses;
88
89 // Number of vector alu accesses
90 Stats::Scalar numVecAluAccesses;
91
92 // Number of function calls/returns
93 Stats::Scalar numCallsReturns;
94
95 // Conditional control instructions;
96 Stats::Scalar numCondCtrlInsts;
97
98 // Number of int instructions
99 Stats::Scalar numIntInsts;
100
101 // Number of float instructions
102 Stats::Scalar numFpInsts;
103
104 // Number of vector instructions
105 Stats::Scalar numVecInsts;
106
107 // Number of integer register file accesses
108 Stats::Scalar numIntRegReads;
109 Stats::Scalar numIntRegWrites;
110
111 // Number of float register file accesses
112 Stats::Scalar numFpRegReads;
113 Stats::Scalar numFpRegWrites;
114
115 // Number of vector register file accesses
116 mutable Stats::Scalar numVecRegReads;
117 Stats::Scalar numVecRegWrites;
118
119 // Number of predicate register file accesses
120 mutable Stats::Scalar numVecPredRegReads;
121 Stats::Scalar numVecPredRegWrites;
122
123 // Number of condition code register file accesses
124 Stats::Scalar numCCRegReads;
125 Stats::Scalar numCCRegWrites;
126
127 // Number of simulated memory references
128 Stats::Scalar numMemRefs;
129 Stats::Scalar numLoadInsts;
130 Stats::Scalar numStoreInsts;
131
132 // Number of idle cycles
133 Stats::Formula numIdleCycles;
134
135 // Number of busy cycles
136 Stats::Formula numBusyCycles;
137
138 // Number of simulated loads
139 Counter numLoad;
140
141 // Number of idle cycles
142 Stats::Average notIdleFraction;
143 Stats::Formula idleFraction;
144
145 // Number of cycles stalled for I-cache responses
146 Stats::Scalar icacheStallCycles;
147 Counter lastIcacheStall;
148
149 // Number of cycles stalled for D-cache responses
150 Stats::Scalar dcacheStallCycles;
151 Counter lastDcacheStall;
152
153 /// @{
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;
160 /// @}
161
162 // Instruction mix histogram by OpClass
163 Stats::Vector statExecutedInstType;
164
165 public:
166 /** Constructor */
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)
170 { }
171
172 /** Reads an integer register. */
173 RegVal
174 readIntRegOperand(const StaticInst *si, int idx) override
175 {
176 numIntRegReads++;
177 const RegId& reg = si->srcRegIdx(idx);
178 assert(reg.isIntReg());
179 return thread->readIntReg(reg.index());
180 }
181
182 /** Sets an integer register to a value. */
183 void
184 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
185 {
186 numIntRegWrites++;
187 const RegId& reg = si->destRegIdx(idx);
188 assert(reg.isIntReg());
189 thread->setIntReg(reg.index(), val);
190 }
191
192 /** Reads a floating point register in its binary format, instead
193 * of by value. */
194 RegVal
195 readFloatRegOperandBits(const StaticInst *si, int idx) override
196 {
197 numFpRegReads++;
198 const RegId& reg = si->srcRegIdx(idx);
199 assert(reg.isFloatReg());
200 return thread->readFloatReg(reg.index());
201 }
202
203 /** Sets the bits of a floating point register of single width
204 * to a binary value. */
205 void
206 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
207 {
208 numFpRegWrites++;
209 const RegId& reg = si->destRegIdx(idx);
210 assert(reg.isFloatReg());
211 thread->setFloatReg(reg.index(), val);
212 }
213
214 /** Reads a vector register. */
215 const VecRegContainer &
216 readVecRegOperand(const StaticInst *si, int idx) const override
217 {
218 numVecRegReads++;
219 const RegId& reg = si->srcRegIdx(idx);
220 assert(reg.isVecReg());
221 return thread->readVecReg(reg);
222 }
223
224 /** Reads a vector register for modification. */
225 VecRegContainer &
226 getWritableVecRegOperand(const StaticInst *si, int idx) override
227 {
228 numVecRegWrites++;
229 const RegId& reg = si->destRegIdx(idx);
230 assert(reg.isVecReg());
231 return thread->getWritableVecReg(reg);
232 }
233
234 /** Sets a vector register to a value. */
235 void
236 setVecRegOperand(const StaticInst *si, int idx,
237 const VecRegContainer& val) override
238 {
239 numVecRegWrites++;
240 const RegId& reg = si->destRegIdx(idx);
241 assert(reg.isVecReg());
242 thread->setVecReg(reg, val);
243 }
244
245 /** Vector Register Lane Interfaces. */
246 /** @{ */
247 /** Reads source vector lane. */
248 template <typename VecElem>
249 VecLaneT<VecElem, true>
250 readVecLaneOperand(const StaticInst *si, int idx) const
251 {
252 numVecRegReads++;
253 const RegId& reg = si->srcRegIdx(idx);
254 assert(reg.isVecReg());
255 return thread->readVecLane<VecElem>(reg);
256 }
257 /** Reads source vector 8bit operand. */
258 virtual ConstVecLane8
259 readVec8BitLaneOperand(const StaticInst *si, int idx) const
260 override
261 { return readVecLaneOperand<uint8_t>(si, idx); }
262
263 /** Reads source vector 16bit operand. */
264 virtual ConstVecLane16
265 readVec16BitLaneOperand(const StaticInst *si, int idx) const
266 override
267 { return readVecLaneOperand<uint16_t>(si, idx); }
268
269 /** Reads source vector 32bit operand. */
270 virtual ConstVecLane32
271 readVec32BitLaneOperand(const StaticInst *si, int idx) const
272 override
273 { return readVecLaneOperand<uint32_t>(si, idx); }
274
275 /** Reads source vector 64bit operand. */
276 virtual ConstVecLane64
277 readVec64BitLaneOperand(const StaticInst *si, int idx) const
278 override
279 { return readVecLaneOperand<uint64_t>(si, idx); }
280
281 /** Write a lane of the destination vector operand. */
282 template <typename LD>
283 void
284 setVecLaneOperandT(const StaticInst *si, int idx,
285 const LD& val)
286 {
287 numVecRegWrites++;
288 const RegId& reg = si->destRegIdx(idx);
289 assert(reg.isVecReg());
290 return thread->setVecLane(reg, val);
291 }
292 /** Write a lane of the destination vector operand. */
293 virtual void
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. */
298 virtual void
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. */
303 virtual void
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. */
308 virtual void
309 setVecLaneOperand(const StaticInst *si, int idx,
310 const LaneData<LaneSize::EightByte>& val) override
311 { return setVecLaneOperandT(si, idx, val); }
312 /** @} */
313
314 /** Reads an element of a vector register. */
315 VecElem
316 readVecElemOperand(const StaticInst *si, int idx) const override
317 {
318 numVecRegReads++;
319 const RegId& reg = si->srcRegIdx(idx);
320 assert(reg.isVecElem());
321 return thread->readVecElem(reg);
322 }
323
324 /** Sets an element of a vector register to a value. */
325 void
326 setVecElemOperand(const StaticInst *si, int idx,
327 const VecElem val) override
328 {
329 numVecRegWrites++;
330 const RegId& reg = si->destRegIdx(idx);
331 assert(reg.isVecElem());
332 thread->setVecElem(reg, val);
333 }
334
335 const VecPredRegContainer&
336 readVecPredRegOperand(const StaticInst *si, int idx) const override
337 {
338 numVecPredRegReads++;
339 const RegId& reg = si->srcRegIdx(idx);
340 assert(reg.isVecPredReg());
341 return thread->readVecPredReg(reg);
342 }
343
344 VecPredRegContainer&
345 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
346 {
347 numVecPredRegWrites++;
348 const RegId& reg = si->destRegIdx(idx);
349 assert(reg.isVecPredReg());
350 return thread->getWritableVecPredReg(reg);
351 }
352
353 void
354 setVecPredRegOperand(const StaticInst *si, int idx,
355 const VecPredRegContainer& val) override
356 {
357 numVecPredRegWrites++;
358 const RegId& reg = si->destRegIdx(idx);
359 assert(reg.isVecPredReg());
360 thread->setVecPredReg(reg, val);
361 }
362
363 RegVal
364 readCCRegOperand(const StaticInst *si, int idx) override
365 {
366 numCCRegReads++;
367 const RegId& reg = si->srcRegIdx(idx);
368 assert(reg.isCCReg());
369 return thread->readCCReg(reg.index());
370 }
371
372 void
373 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
374 {
375 numCCRegWrites++;
376 const RegId& reg = si->destRegIdx(idx);
377 assert(reg.isCCReg());
378 thread->setCCReg(reg.index(), val);
379 }
380
381 RegVal
382 readMiscRegOperand(const StaticInst *si, int idx) override
383 {
384 numIntRegReads++;
385 const RegId& reg = si->srcRegIdx(idx);
386 assert(reg.isMiscReg());
387 return thread->readMiscReg(reg.index());
388 }
389
390 void
391 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
392 {
393 numIntRegWrites++;
394 const RegId& reg = si->destRegIdx(idx);
395 assert(reg.isMiscReg());
396 thread->setMiscReg(reg.index(), val);
397 }
398
399 /**
400 * Reads a miscellaneous register, handling any architectural
401 * side effects due to reading that register.
402 */
403 RegVal
404 readMiscReg(int misc_reg) override
405 {
406 numIntRegReads++;
407 return thread->readMiscReg(misc_reg);
408 }
409
410 /**
411 * Sets a miscellaneous register, handling any architectural
412 * side effects due to writing that register.
413 */
414 void
415 setMiscReg(int misc_reg, RegVal val) override
416 {
417 numIntRegWrites++;
418 thread->setMiscReg(misc_reg, val);
419 }
420
421 PCState
422 pcState() const override
423 {
424 return thread->pcState();
425 }
426
427 void
428 pcState(const PCState &val) override
429 {
430 thread->pcState(val);
431 }
432
433 Fault
434 readMem(Addr addr, uint8_t *data, unsigned int size,
435 Request::Flags flags,
436 const std::vector<bool>& byte_enable)
437 override
438 {
439 assert(byte_enable.size() == size);
440 return cpu->readMem(addr, data, size, flags, byte_enable);
441 }
442
443 Fault
444 initiateMemRead(Addr addr, unsigned int size,
445 Request::Flags flags,
446 const std::vector<bool>& byte_enable)
447 override
448 {
449 assert(byte_enable.size() == size);
450 return cpu->initiateMemRead(addr, size, flags, byte_enable);
451 }
452
453 Fault
454 writeMem(uint8_t *data, unsigned int size, Addr addr,
455 Request::Flags flags, uint64_t *res,
456 const std::vector<bool>& byte_enable)
457 override
458 {
459 assert(byte_enable.size() == size);
460 return cpu->writeMem(data, size, addr, flags, res,
461 byte_enable);
462 }
463
464 Fault amoMem(Addr addr, uint8_t *data, unsigned int size,
465 Request::Flags flags, AtomicOpFunctorPtr amo_op) override
466 {
467 return cpu->amoMem(addr, data, size, flags, std::move(amo_op));
468 }
469
470 Fault initiateMemAMO(Addr addr, unsigned int size,
471 Request::Flags flags,
472 AtomicOpFunctorPtr amo_op) override
473 {
474 return cpu->initiateMemAMO(addr, size, flags, std::move(amo_op));
475 }
476
477 Fault initiateHtmCmd(Request::Flags flags) override
478 {
479 return cpu->initiateHtmCmd(flags);
480 }
481
482 /**
483 * Sets the number of consecutive store conditional failures.
484 */
485 void
486 setStCondFailures(unsigned int sc_failures) override
487 {
488 thread->setStCondFailures(sc_failures);
489 }
490
491 /**
492 * Returns the number of consecutive store conditional failures.
493 */
494 unsigned int
495 readStCondFailures() const override
496 {
497 return thread->readStCondFailures();
498 }
499
500 /** Returns a pointer to the ThreadContext. */
501 ThreadContext *tcBase() const override { return thread->getTC(); }
502
503 bool
504 readPredicate() const override
505 {
506 return thread->readPredicate();
507 }
508
509 void
510 setPredicate(bool val) override
511 {
512 thread->setPredicate(val);
513
514 if (cpu->traceData) {
515 cpu->traceData->setPredicate(val);
516 }
517 }
518
519 bool
520 readMemAccPredicate() const override
521 {
522 return thread->readMemAccPredicate();
523 }
524
525 void
526 setMemAccPredicate(bool val) override
527 {
528 thread->setMemAccPredicate(val);
529 }
530
531 uint64_t
532 getHtmTransactionUid() const override
533 {
534 return tcBase()->getHtmCheckpointPtr()->getHtmUid();
535 }
536
537 uint64_t
538 newHtmTransactionUid() const override
539 {
540 return tcBase()->getHtmCheckpointPtr()->newHtmUid();
541 }
542
543 bool
544 inHtmTransactionalState() const override
545 {
546 return (getHtmTransactionalDepth() > 0);
547 }
548
549 uint64_t
550 getHtmTransactionalDepth() const override
551 {
552 assert(thread->htmTransactionStarts >= thread->htmTransactionStops);
553 return (thread->htmTransactionStarts - thread->htmTransactionStops);
554 }
555
556 /**
557 * Invalidate a page in the DTLB <i>and</i> ITLB.
558 */
559 void
560 demapPage(Addr vaddr, uint64_t asn) override
561 {
562 thread->demapPage(vaddr, asn);
563 }
564
565 void
566 armMonitor(Addr address) override
567 {
568 cpu->armMonitor(thread->threadId(), address);
569 }
570
571 bool
572 mwait(PacketPtr pkt) override
573 {
574 return cpu->mwait(thread->threadId(), pkt);
575 }
576
577 void
578 mwaitAtomic(ThreadContext *tc) override
579 {
580 cpu->mwaitAtomic(thread->threadId(), tc, thread->mmu);
581 }
582
583 AddressMonitor *
584 getAddrMonitor() override
585 {
586 return cpu->getCpuAddrMonitor(thread->threadId());
587 }
588 };
589
590 #endif // __CPU_EXEC_CONTEXT_HH__