Deleted Added
sdiff udiff text old ( 13693:85fa3a41014b ) new ( 13865:cca49fc49c57 )
full compact
1/*
2 * Copyright (c) 2011-2012, 2016-2018 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2001-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Steve Reinhardt
42 * Nathan Binkert
43 */
44
45#ifndef __CPU_SIMPLE_THREAD_HH__
46#define __CPU_SIMPLE_THREAD_HH__
47
48#include "arch/decoder.hh"
49#include "arch/generic/tlb.hh"
50#include "arch/isa.hh"
51#include "arch/isa_traits.hh"
52#include "arch/registers.hh"
53#include "arch/types.hh"
54#include "base/types.hh"
55#include "config/the_isa.hh"
56#include "cpu/thread_context.hh"
57#include "cpu/thread_state.hh"
58#include "debug/CCRegs.hh"
59#include "debug/FloatRegs.hh"
60#include "debug/IntRegs.hh"
61#include "debug/VecPredRegs.hh"
62#include "debug/VecRegs.hh"
63#include "mem/page_table.hh"
64#include "mem/request.hh"
65#include "sim/byteswap.hh"
66#include "sim/eventq.hh"
67#include "sim/process.hh"
68#include "sim/serialize.hh"
69#include "sim/system.hh"
70
71class BaseCPU;
72class CheckerCPU;
73
74class FunctionProfile;
75class ProfileNode;
76
77namespace TheISA {
78 namespace Kernel {
79 class Statistics;
80 }
81}
82
83/**
84 * The SimpleThread object provides a combination of the ThreadState
85 * object and the ThreadContext interface. It implements the
86 * ThreadContext interface so that a ProxyThreadContext class can be
87 * made using SimpleThread as the template parameter (see
88 * thread_context.hh). It adds to the ThreadState object by adding all
89 * the objects needed for simple functional execution, including a
90 * simple architectural register file, and pointers to the ITB and DTB
91 * in full system mode. For CPU models that do not need more advanced
92 * ways to hold state (i.e. a separate physical register file, or
93 * separate fetch and commit PC's), this SimpleThread class provides
94 * all the necessary state for full architecture-level functional
95 * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for
96 * examples.
97 */
98
99class SimpleThread : public ThreadState
100{
101 protected:
102 typedef TheISA::MachInst MachInst;
103 using VecRegContainer = TheISA::VecRegContainer;
104 using VecElem = TheISA::VecElem;
105 using VecPredRegContainer = TheISA::VecPredRegContainer;
106 public:
107 typedef ThreadContext::Status Status;
108
109 protected:
110 RegVal floatRegs[TheISA::NumFloatRegs];
111 RegVal intRegs[TheISA::NumIntRegs];
112 VecRegContainer vecRegs[TheISA::NumVecRegs];
113 VecPredRegContainer vecPredRegs[TheISA::NumVecPredRegs];
114#ifdef ISA_HAS_CC_REGS
115 RegVal ccRegs[TheISA::NumCCRegs];
116#endif
117 TheISA::ISA *const isa; // one "instance" of the current ISA.
118
119 TheISA::PCState _pcState;
120
121 /** Did this instruction execute or is it predicated false */
122 bool predicate;
123
124 public:
125 std::string name() const
126 {
127 return csprintf("%s.[tid:%i]", baseCpu->name(), tc->threadId());
128 }
129
130 ProxyThreadContext<SimpleThread> *tc;
131
132 System *system;
133
134 BaseTLB *itb;
135 BaseTLB *dtb;
136
137 TheISA::Decoder decoder;
138
139 // constructor: initialize SimpleThread from given process structure
140 // FS
141 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
142 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
143 bool use_kernel_stats = true);
144 // SE
145 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
146 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
147 TheISA::ISA *_isa);
148
149 virtual ~SimpleThread();
150
151 virtual void takeOverFrom(ThreadContext *oldContext);
152
153 void regStats(const std::string &name);
154
155 void copyState(ThreadContext *oldContext);
156
157 void serialize(CheckpointOut &cp) const override;
158 void unserialize(CheckpointIn &cp) override;
159 void startup();
160
161 /***************************************************************
162 * SimpleThread functions to provide CPU with access to various
163 * state.
164 **************************************************************/
165
166 /** Returns the pointer to this SimpleThread's ThreadContext. Used
167 * when a ThreadContext must be passed to objects outside of the
168 * CPU.
169 */
170 ThreadContext *getTC() { return tc; }
171
172 void demapPage(Addr vaddr, uint64_t asn)
173 {
174 itb->demapPage(vaddr, asn);
175 dtb->demapPage(vaddr, asn);
176 }
177
178 void demapInstPage(Addr vaddr, uint64_t asn)
179 {
180 itb->demapPage(vaddr, asn);
181 }
182
183 void demapDataPage(Addr vaddr, uint64_t asn)
184 {
185 dtb->demapPage(vaddr, asn);
186 }
187
188 void dumpFuncProfile();
189
190 Fault hwrei();
191
192 bool simPalCheck(int palFunc);
193
194 /*******************************************
195 * ThreadContext interface functions.
196 ******************************************/
197
198 BaseCPU *getCpuPtr() { return baseCpu; }
199
200 BaseTLB *getITBPtr() { return itb; }
201
202 BaseTLB *getDTBPtr() { return dtb; }
203
204 CheckerCPU *getCheckerCpuPtr() { return NULL; }
205
206 TheISA::ISA *getIsaPtr() { return isa; }
207
208 TheISA::Decoder *getDecoderPtr() { return &decoder; }
209
210 System *getSystemPtr() { return system; }
211
212 Status status() const { return _status; }
213
214 void setStatus(Status newStatus) { _status = newStatus; }
215
216 /// Set the status to Active.
217 void activate();
218
219 /// Set the status to Suspended.
220 void suspend();
221
222 /// Set the status to Halted.
223 void halt();
224
225 void copyArchRegs(ThreadContext *tc);
226
227 void clearArchRegs()
228 {
229 _pcState = 0;
230 memset(intRegs, 0, sizeof(intRegs));
231 memset(floatRegs, 0, sizeof(floatRegs));
232 for (int i = 0; i < TheISA::NumVecRegs; i++) {
233 vecRegs[i].zero();
234 }
235 for (int i = 0; i < TheISA::NumVecPredRegs; i++) {
236 vecPredRegs[i].reset();
237 }
238#ifdef ISA_HAS_CC_REGS
239 memset(ccRegs, 0, sizeof(ccRegs));
240#endif
241 isa->clear();
242 }
243
244 //
245 // New accessors for new decoder.
246 //
247 RegVal
248 readIntReg(int reg_idx)
249 {
250 int flatIndex = isa->flattenIntIndex(reg_idx);
251 assert(flatIndex < TheISA::NumIntRegs);
252 uint64_t regVal(readIntRegFlat(flatIndex));
253 DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
254 reg_idx, flatIndex, regVal);
255 return regVal;
256 }
257
258 RegVal
259 readFloatReg(int reg_idx)
260 {
261 int flatIndex = isa->flattenFloatIndex(reg_idx);
262 assert(flatIndex < TheISA::NumFloatRegs);
263 RegVal regVal(readFloatRegFlat(flatIndex));
264 DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
265 reg_idx, flatIndex, regVal);
266 return regVal;
267 }
268
269 const VecRegContainer&
270 readVecReg(const RegId& reg) const
271 {
272 int flatIndex = isa->flattenVecIndex(reg.index());
273 assert(flatIndex < TheISA::NumVecRegs);
274 const VecRegContainer& regVal = readVecRegFlat(flatIndex);
275 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
276 reg.index(), flatIndex, regVal.print());
277 return regVal;
278 }
279
280 VecRegContainer&
281 getWritableVecReg(const RegId& reg)
282 {
283 int flatIndex = isa->flattenVecIndex(reg.index());
284 assert(flatIndex < TheISA::NumVecRegs);
285 VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
286 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
287 reg.index(), flatIndex, regVal.print());
288 return regVal;
289 }
290
291 /** Vector Register Lane Interfaces. */
292 /** @{ */
293 /** Reads source vector <T> operand. */
294 template <typename T>
295 VecLaneT<T, true>
296 readVecLane(const RegId& reg) const
297 {
298 int flatIndex = isa->flattenVecIndex(reg.index());
299 assert(flatIndex < TheISA::NumVecRegs);
300 auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
301 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
302 reg.index(), flatIndex, reg.elemIndex(), regVal);
303 return regVal;
304 }
305
306 /** Reads source vector 8bit operand. */
307 virtual ConstVecLane8
308 readVec8BitLaneReg(const RegId& reg) const
309 { return readVecLane<uint8_t>(reg); }
310
311 /** Reads source vector 16bit operand. */
312 virtual ConstVecLane16
313 readVec16BitLaneReg(const RegId& reg) const
314 { return readVecLane<uint16_t>(reg); }
315
316 /** Reads source vector 32bit operand. */
317 virtual ConstVecLane32
318 readVec32BitLaneReg(const RegId& reg) const
319 { return readVecLane<uint32_t>(reg); }
320
321 /** Reads source vector 64bit operand. */
322 virtual ConstVecLane64
323 readVec64BitLaneReg(const RegId& reg) const
324 { return readVecLane<uint64_t>(reg); }
325
326 /** Write a lane of the destination vector register. */
327 template <typename LD>
328 void setVecLaneT(const RegId& reg, const LD& val)
329 {
330 int flatIndex = isa->flattenVecIndex(reg.index());
331 assert(flatIndex < TheISA::NumVecRegs);
332 setVecLaneFlat(flatIndex, reg.elemIndex(), val);
333 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
334 reg.index(), flatIndex, reg.elemIndex(), val);
335 }
336 virtual void setVecLane(const RegId& reg,
337 const LaneData<LaneSize::Byte>& val)
338 { return setVecLaneT(reg, val); }
339 virtual void setVecLane(const RegId& reg,
340 const LaneData<LaneSize::TwoByte>& val)
341 { return setVecLaneT(reg, val); }
342 virtual void setVecLane(const RegId& reg,
343 const LaneData<LaneSize::FourByte>& val)
344 { return setVecLaneT(reg, val); }
345 virtual void setVecLane(const RegId& reg,
346 const LaneData<LaneSize::EightByte>& val)
347 { return setVecLaneT(reg, val); }
348 /** @} */
349
350 const VecElem& readVecElem(const RegId& reg) const
351 {
352 int flatIndex = isa->flattenVecElemIndex(reg.index());
353 assert(flatIndex < TheISA::NumVecRegs);
354 const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
355 DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
356 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
357 return regVal;
358 }
359
360 const VecPredRegContainer&
361 readVecPredReg(const RegId& reg) const
362 {
363 int flatIndex = isa->flattenVecPredIndex(reg.index());
364 assert(flatIndex < TheISA::NumVecPredRegs);
365 const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
366 DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
367 reg.index(), flatIndex, regVal.print());
368 return regVal;
369 }
370
371 VecPredRegContainer&
372 getWritableVecPredReg(const RegId& reg)
373 {
374 int flatIndex = isa->flattenVecPredIndex(reg.index());
375 assert(flatIndex < TheISA::NumVecPredRegs);
376 VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
377 DPRINTF(VecPredRegs,
378 "Reading predicate reg %d (%d) as %s for modify.\n",
379 reg.index(), flatIndex, regVal.print());
380 return regVal;
381 }
382
383 RegVal
384 readCCReg(int reg_idx)
385 {
386#ifdef ISA_HAS_CC_REGS
387 int flatIndex = isa->flattenCCIndex(reg_idx);
388 assert(0 <= flatIndex);
389 assert(flatIndex < TheISA::NumCCRegs);
390 uint64_t regVal(readCCRegFlat(flatIndex));
391 DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
392 reg_idx, flatIndex, regVal);
393 return regVal;
394#else
395 panic("Tried to read a CC register.");
396 return 0;
397#endif
398 }
399
400 void
401 setIntReg(int reg_idx, RegVal val)
402 {
403 int flatIndex = isa->flattenIntIndex(reg_idx);
404 assert(flatIndex < TheISA::NumIntRegs);
405 DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
406 reg_idx, flatIndex, val);
407 setIntRegFlat(flatIndex, val);
408 }
409
410 void
411 setFloatReg(int reg_idx, RegVal val)
412 {
413 int flatIndex = isa->flattenFloatIndex(reg_idx);
414 assert(flatIndex < TheISA::NumFloatRegs);
415 // XXX: Fix array out of bounds compiler error for gem5.fast
416 // when checkercpu enabled
417 if (flatIndex < TheISA::NumFloatRegs)
418 setFloatRegFlat(flatIndex, val);
419 DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
420 reg_idx, flatIndex, val);
421 }
422
423 void
424 setVecReg(const RegId& reg, const VecRegContainer& val)
425 {
426 int flatIndex = isa->flattenVecIndex(reg.index());
427 assert(flatIndex < TheISA::NumVecRegs);
428 setVecRegFlat(flatIndex, val);
429 DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
430 reg.index(), flatIndex, val.print());
431 }
432
433 void
434 setVecElem(const RegId& reg, const VecElem& val)
435 {
436 int flatIndex = isa->flattenVecElemIndex(reg.index());
437 assert(flatIndex < TheISA::NumVecRegs);
438 setVecElemFlat(flatIndex, reg.elemIndex(), val);
439 DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
440 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
441 }
442
443 void
444 setVecPredReg(const RegId& reg, const VecPredRegContainer& val)
445 {
446 int flatIndex = isa->flattenVecPredIndex(reg.index());
447 assert(flatIndex < TheISA::NumVecPredRegs);
448 setVecPredRegFlat(flatIndex, val);
449 DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
450 reg.index(), flatIndex, val.print());
451 }
452
453 void
454 setCCReg(int reg_idx, RegVal val)
455 {
456#ifdef ISA_HAS_CC_REGS
457 int flatIndex = isa->flattenCCIndex(reg_idx);
458 assert(flatIndex < TheISA::NumCCRegs);
459 DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
460 reg_idx, flatIndex, val);
461 setCCRegFlat(flatIndex, val);
462#else
463 panic("Tried to set a CC register.");
464#endif
465 }
466
467 TheISA::PCState
468 pcState()
469 {
470 return _pcState;
471 }
472
473 void
474 pcState(const TheISA::PCState &val)
475 {
476 _pcState = val;
477 }
478
479 void
480 pcStateNoRecord(const TheISA::PCState &val)
481 {
482 _pcState = val;
483 }
484
485 Addr
486 instAddr()
487 {
488 return _pcState.instAddr();
489 }
490
491 Addr
492 nextInstAddr()
493 {
494 return _pcState.nextInstAddr();
495 }
496
497 void
498 setNPC(Addr val)
499 {
500 _pcState.setNPC(val);
501 }
502
503 MicroPC
504 microPC()
505 {
506 return _pcState.microPC();
507 }
508
509 bool readPredicate()
510 {
511 return predicate;
512 }
513
514 void setPredicate(bool val)
515 {
516 predicate = val;
517 }
518
519 RegVal
520 readMiscRegNoEffect(int misc_reg, ThreadID tid=0) const
521 {
522 return isa->readMiscRegNoEffect(misc_reg);
523 }
524
525 RegVal
526 readMiscReg(int misc_reg, ThreadID tid=0)
527 {
528 return isa->readMiscReg(misc_reg, tc);
529 }
530
531 void
532 setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid = 0)
533 {
534 return isa->setMiscRegNoEffect(misc_reg, val);
535 }
536
537 void
538 setMiscReg(int misc_reg, RegVal val, ThreadID tid = 0)
539 {
540 return isa->setMiscReg(misc_reg, val, tc);
541 }
542
543 RegId
544 flattenRegId(const RegId& regId) const
545 {
546 return isa->flattenRegId(regId);
547 }
548
549 unsigned readStCondFailures() { return storeCondFailures; }
550
551 void setStCondFailures(unsigned sc_failures)
552 { storeCondFailures = sc_failures; }
553
554 void
555 syscall(int64_t callnum, Fault *fault)
556 {
557 process->syscall(callnum, tc, fault);
558 }
559
560 RegVal readIntRegFlat(int idx) { return intRegs[idx]; }
561 void setIntRegFlat(int idx, RegVal val) { intRegs[idx] = val; }
562
563 RegVal readFloatRegFlat(int idx) { return floatRegs[idx]; }
564 void setFloatRegFlat(int idx, RegVal val) { floatRegs[idx] = val; }
565
566 const VecRegContainer &
567 readVecRegFlat(const RegIndex& reg) const
568 {
569 return vecRegs[reg];
570 }
571
572 VecRegContainer &
573 getWritableVecRegFlat(const RegIndex& reg)
574 {
575 return vecRegs[reg];
576 }
577
578 void
579 setVecRegFlat(const RegIndex& reg, const VecRegContainer& val)
580 {
581 vecRegs[reg] = val;
582 }
583
584 template <typename T>
585 VecLaneT<T, true>
586 readVecLaneFlat(const RegIndex& reg, int lId) const
587 {
588 return vecRegs[reg].laneView<T>(lId);
589 }
590
591 template <typename LD>
592 void
593 setVecLaneFlat(const RegIndex& reg, int lId, const LD& val)
594 {
595 vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
596 }
597
598 const VecElem &
599 readVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex) const
600 {
601 return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
602 }
603
604 void
605 setVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex,
606 const VecElem val)
607 {
608 vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
609 }
610
611 const VecPredRegContainer& readVecPredRegFlat(const RegIndex& reg) const
612 {
613 return vecPredRegs[reg];
614 }
615
616 VecPredRegContainer& getWritableVecPredRegFlat(const RegIndex& reg)
617 {
618 return vecPredRegs[reg];
619 }
620
621 void setVecPredRegFlat(const RegIndex& reg, const VecPredRegContainer& val)
622 {
623 vecPredRegs[reg] = val;
624 }
625
626#ifdef ISA_HAS_CC_REGS
627 RegVal readCCRegFlat(int idx) { return ccRegs[idx]; }
628 void setCCRegFlat(int idx, RegVal val) { ccRegs[idx] = val; }
629#else
630 RegVal readCCRegFlat(int idx)
631 { panic("readCCRegFlat w/no CC regs!\n"); }
632
633 void setCCRegFlat(int idx, RegVal val)
634 { panic("setCCRegFlat w/no CC regs!\n"); }
635#endif
636};
637
638
639#endif // __CPU_CPU_EXEC_CONTEXT_HH__