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