gem5 v23.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pcstate.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 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) 2010 Gabe Black
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 __ARCH_GENERIC_TYPES_HH__
42#define __ARCH_GENERIC_TYPES_HH__
43
44#include <iostream>
45#include <memory>
46#include <type_traits>
47
48#include "base/compiler.hh"
49#include "base/trace.hh"
50#include "base/types.hh"
51#include "sim/serialize.hh"
52
53namespace gem5
54{
55
56// The guaranteed interface.
58{
59 protected:
60 Addr _pc = 0;
62
63 PCStateBase(const PCStateBase &other) : _pc(other._pc), _upc(other._upc) {}
64 PCStateBase &operator=(const PCStateBase &other) = default;
66
67 public:
68 virtual ~PCStateBase() = default;
69
70 template<class Target>
71 Target &
73 {
74 return static_cast<Target &>(*this);
75 }
76
77 template<class Target>
78 const Target &
79 as() const
80 {
81 return static_cast<const Target &>(*this);
82 }
83
84 virtual PCStateBase *clone() const = 0;
85 virtual void
86 update(const PCStateBase &other)
87 {
88 _pc = other._pc;
89 _upc = other._upc;
90 }
91 void update(const PCStateBase *ptr) { update(*ptr); }
92
93 virtual void output(std::ostream &os) const = 0;
94
95 virtual bool
96 equals(const PCStateBase &other) const
97 {
98 return _pc == other._pc && _upc == other._upc;
99 }
100
106 Addr
107 instAddr() const
108 {
109 return _pc;
110 }
111
117 MicroPC
118 microPC() const
119 {
120 return _upc;
121 }
122
123 virtual void
125 {
126 _upc = 0;
127 }
128
129 virtual void advance() = 0;
130 virtual bool branching() const = 0;
131
132 void
133 serialize(CheckpointOut &cp) const override
134 {
137 }
138
139 void
141 {
144 }
145};
146
147static inline std::ostream &
148operator<<(std::ostream & os, const PCStateBase &pc)
149{
150 pc.output(os);
151 return os;
152}
153
154static inline bool
156{
157 return a.equals(b);
158}
159
160static inline bool
162{
163 return !a.equals(b);
164}
165
166namespace
167{
168
169inline void
170set(PCStateBase *&dest, const PCStateBase *src)
171{
172 if (GEM5_LIKELY(dest)) {
173 if (GEM5_LIKELY(src)) {
174 // Both src and dest already have storage, so just copy contents.
175 dest->update(src);
176 } else {
177 // src is empty, so clear out dest.
178 dest = nullptr;
179 }
180 } else {
181 if (GEM5_LIKELY(src)) {
182 // dest doesn't have storage, so create some as a copy of src.
183 dest = src->clone();
184 } else {
185 // dest is already nullptr, so nothing to do.
186 }
187 }
188}
189
190inline void
191set(std::unique_ptr<PCStateBase> &dest, const PCStateBase *src)
192{
193 PCStateBase *dest_ptr = dest.get();
194 set(dest_ptr, src);
195 if (dest.get() != dest_ptr)
196 dest.reset(dest_ptr);
197}
198
199inline void
200set(PCStateBase *&dest, const std::unique_ptr<PCStateBase> &src)
201{
202 const PCStateBase *src_ptr = src.get();
203 set(dest, src_ptr);
204}
205
206inline void
207set(std::unique_ptr<PCStateBase> &dest,
208 const std::unique_ptr<PCStateBase> &src)
209{
210 PCStateBase *dest_ptr = dest.get();
211 const PCStateBase *src_ptr = src.get();
212 set(dest_ptr, src_ptr);
213 if (dest.get() != dest_ptr)
214 dest.reset(dest_ptr);
215}
216
217inline void
218set(PCStateBase *&dest, const PCStateBase &src)
219{
220 if (GEM5_LIKELY(dest)) {
221 // Update dest with the contents of src.
222 dest->update(src);
223 } else {
224 // Clone src over to dest.
225 dest = src.clone();
226 }
227}
228
229inline void
230set(std::unique_ptr<PCStateBase> &dest, const PCStateBase &src)
231{
232 PCStateBase *dest_ptr = dest.get();
233 set(dest_ptr, src);
234 if (dest.get() != dest_ptr)
235 dest.reset(dest_ptr);
236}
237
238inline void
239set(PCStateBase &dest, const PCStateBase &src)
240{
241 dest.update(src);
242}
243
244} // anonymous namespace
245
246namespace GenericISA
247{
248
250{
251 protected:
253
255
257 _npc(other._npc), _nupc(other._nupc)
258 {}
259 PCStateWithNext &operator=(const PCStateWithNext &other) = default;
261
262 public:
263 Addr pc() const { return _pc; }
264 void pc(Addr val) { _pc = val; }
265
266 Addr npc() const { return _npc; }
267 void npc(Addr val) { _npc = val; }
268
269 MicroPC upc() const { return _upc; }
270 void upc(MicroPC val) { _upc = val; }
271
272 MicroPC nupc() const { return _nupc; }
273 void nupc(MicroPC val) { _nupc = val; }
274
275 // Reset the macroop's upc without advancing the regular pc.
276 void
277 uReset() override
278 {
280 _nupc = 1;
281 }
282
283 void
285 {
286 npc(val);
287 }
288
289 void
290 output(std::ostream &os) const override
291 {
292 ccprintf(os, "(%#x=>%#x)", this->pc(), this->npc());
293 }
294
295 void
296 update(const PCStateBase &other) override
297 {
298 PCStateBase::update(other);
299 auto &pcstate = other.as<PCStateWithNext>();
300 _npc = pcstate._npc;
301 _nupc = pcstate._nupc;
302 }
303
304 bool
305 equals(const PCStateBase &other) const override
306 {
307 auto &ps = other.as<PCStateWithNext>();
308 return PCStateBase::equals(other) &&
309 _npc == ps._npc && _nupc == ps._nupc;
310 }
311
312 void
313 serialize(CheckpointOut &cp) const override
314 {
318 }
319
320 void
322 {
326 }
327};
328
329
330/*
331 * Different flavors of PC state. Only ISA specific code should rely on
332 * any particular type of PC state being available. All other code should
333 * use the interface above.
334 */
335
336// The most basic type of PC.
337template <int InstWidth>
339{
340 protected:
342
343 public:
344 SimplePCState(const SimplePCState &other) : Base(other) {}
345 SimplePCState &operator=(const SimplePCState &other) = default;
347 explicit SimplePCState(Addr val) { set(val); }
348
350 clone() const override
351 {
352 return new SimplePCState<InstWidth>(*this);
353 }
354
361 void
363 {
364 this->pc(val);
365 this->npc(val + InstWidth);
366 };
367
368 bool
369 branching() const override
370 {
371 return this->npc() != this->pc() + InstWidth;
372 }
373
374 // Advance the PC.
375 void
376 advance() override
377 {
378 this->_pc = this->_npc;
379 this->_npc += InstWidth;
380 }
381};
382
383// A PC and microcode PC.
384template <int InstWidth>
385class UPCState : public SimplePCState<InstWidth>
386{
387 protected:
389
390 public:
391 void
392 output(std::ostream &os) const override
393 {
395 ccprintf(os, ".(%d=>%d)", this->upc(), this->nupc());
396 }
397
399 clone() const override
400 {
401 return new UPCState<InstWidth>(*this);
402 }
403
404 void
406 {
407 Base::set(val);
408 this->upc(0);
409 this->nupc(1);
410 }
411
412 UPCState(const UPCState &other) : Base(other) {}
413 UPCState &operator=(const UPCState &other) = default;
415 explicit UPCState(Addr val) { set(val); }
416
417 bool
418 branching() const override
419 {
420 return this->npc() != this->pc() + InstWidth ||
421 this->nupc() != this->upc() + 1;
422 }
423
424 // Advance the upc within the instruction.
425 void
427 {
428 this->upc(this->nupc());
429 this->nupc(this->nupc() + 1);
430 }
431
432 // End the macroop by resetting the upc and advancing the regular pc.
433 void
435 {
436 this->advance();
437 this->upc(0);
438 this->nupc(1);
439 }
440};
441
442// A PC with a delay slot.
443template <int InstWidth>
444class DelaySlotPCState : public SimplePCState<InstWidth>
445{
446 protected:
448
450
451 public:
452 void
453 output(std::ostream &os) const override
454 {
455 ccprintf(os, "(%#x=>%#x=>%#x)", this->pc(), this->npc(), nnpc());
456 }
457
459 clone() const override
460 {
461 return new DelaySlotPCState<InstWidth>(*this);
462 }
463
464 void
465 update(const PCStateBase &other) override
466 {
467 Base::update(other);
468 auto &pcstate = other.as<DelaySlotPCState<InstWidth>>();
469 _nnpc = pcstate._nnpc;
470 }
471
472 Addr nnpc() const { return _nnpc; }
473 void nnpc(Addr val) { _nnpc = val; }
474
475 void
477 {
478 Base::set(val);
479 nnpc(val + 2 * InstWidth);
480 }
481
483 Base(other), _nnpc(other._nnpc)
484 {}
488
489 bool
490 branching() const override
491 {
492 return !(this->nnpc() == this->npc() + InstWidth &&
493 (this->npc() == this->pc() + InstWidth ||
494 this->npc() == this->pc() + 2 * InstWidth));
495 }
496
497 // Advance the PC.
498 void
499 advance() override
500 {
501 this->_pc = this->_npc;
502 this->_npc = this->_nnpc;
503 this->_nnpc += InstWidth;
504 }
505
506 bool
507 equals(const PCStateBase &other) const override
508 {
509 auto &ps = other.as<DelaySlotPCState<InstWidth>>();
510 return Base::equals(other) && ps._nnpc == this->_nnpc;
511 }
512
513 void
514 serialize(CheckpointOut &cp) const override
515 {
516 Base::serialize(cp);
518 }
519
520 void
522 {
525 }
526};
527
528// A PC with a delay slot and a microcode PC.
529template <int InstWidth>
530class DelaySlotUPCState : public DelaySlotPCState<InstWidth>
531{
532 protected:
534
535 public:
536 void
537 output(std::ostream &os) const override
538 {
540 ccprintf(os, ".(%d=>%d)", this->upc(), this->nupc());
541 }
542
544 clone() const override
545 {
546 return new DelaySlotUPCState<InstWidth>(*this);
547 }
548
549 void
551 {
552 Base::set(val);
553 this->upc(0);
554 this->nupc(1);
555 }
556
557 DelaySlotUPCState(const DelaySlotUPCState &other) : Base(other) {}
561
562 bool
563 branching() const override
564 {
565 return Base::branching() || this->nupc() != this->upc() + 1;
566 }
567
568 // Advance the upc within the instruction.
569 void
571 {
572 this->_upc = this->_nupc;
573 this->_nupc++;
574 }
575
576 // End the macroop by resetting the upc and advancing the regular pc.
577 void
579 {
580 this->advance();
581 this->_upc = 0;
582 this->_nupc = 1;
583 }
584};
585
586}
587
588} // namespace gem5
589
590#endif
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
bool branching() const override
Definition pcstate.hh:490
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pcstate.hh:521
DelaySlotPCState & operator=(const DelaySlotPCState &other)=default
DelaySlotPCState(const DelaySlotPCState &other)
Definition pcstate.hh:482
void output(std::ostream &os) const override
Definition pcstate.hh:453
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pcstate.hh:514
bool equals(const PCStateBase &other) const override
Definition pcstate.hh:507
SimplePCState< InstWidth > Base
Definition pcstate.hh:447
PCStateBase * clone() const override
Definition pcstate.hh:459
void update(const PCStateBase &other) override
Definition pcstate.hh:465
DelaySlotUPCState & operator=(const DelaySlotUPCState &other)=default
void output(std::ostream &os) const override
Definition pcstate.hh:537
DelaySlotPCState< InstWidth > Base
Definition pcstate.hh:533
bool branching() const override
Definition pcstate.hh:563
PCStateBase * clone() const override
Definition pcstate.hh:544
DelaySlotUPCState(const DelaySlotUPCState &other)
Definition pcstate.hh:557
void output(std::ostream &os) const override
Definition pcstate.hh:290
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pcstate.hh:321
PCStateWithNext & operator=(const PCStateWithNext &other)=default
bool equals(const PCStateBase &other) const override
Definition pcstate.hh:305
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pcstate.hh:313
PCStateWithNext(const PCStateWithNext &other)
Definition pcstate.hh:256
void update(const PCStateBase &other) override
Definition pcstate.hh:296
bool branching() const override
Definition pcstate.hh:369
SimplePCState & operator=(const SimplePCState &other)=default
SimplePCState(const SimplePCState &other)
Definition pcstate.hh:344
void set(Addr val)
Force this PC to reflect a particular value, resetting all its other fields around it.
Definition pcstate.hh:362
PCStateBase * clone() const override
Definition pcstate.hh:350
UPCState & operator=(const UPCState &other)=default
void output(std::ostream &os) const override
Definition pcstate.hh:392
PCStateBase * clone() const override
Definition pcstate.hh:399
SimplePCState< InstWidth > Base
Definition pcstate.hh:388
UPCState(const UPCState &other)
Definition pcstate.hh:412
bool branching() const override
Definition pcstate.hh:418
virtual bool equals(const PCStateBase &other) const
Definition pcstate.hh:96
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pcstate.hh:140
Target & as()
Definition pcstate.hh:72
virtual bool branching() const =0
MicroPC microPC() const
Returns the current micropc.
Definition pcstate.hh:118
virtual void advance()=0
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:107
void update(const PCStateBase *ptr)
Definition pcstate.hh:91
PCStateBase & operator=(const PCStateBase &other)=default
const Target & as() const
Definition pcstate.hh:79
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pcstate.hh:133
virtual void output(std::ostream &os) const =0
virtual void update(const PCStateBase &other)
Definition pcstate.hh:86
virtual ~PCStateBase()=default
virtual PCStateBase * clone() const =0
virtual void uReset()
Definition pcstate.hh:124
PCStateBase(const PCStateBase &other)
Definition pcstate.hh:63
Basic support for object serialization.
Definition serialize.hh:170
Bitfield< 18, 16 > ps
Bitfield< 7 > b
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 12, 11 > set
Bitfield< 4 > pc
Bitfield< 17 > os
Definition misc.hh:810
Bitfield< 63 > val
Definition misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static bool operator==(const PCStateBase &a, const PCStateBase &b)
Definition pcstate.hh:155
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
std::ostream & operator<<(std::ostream &os, const ArmSemihosting::InPlaceArg &ipa)
static bool operator!=(const PCStateBase &a, const PCStateBase &b)
Definition pcstate.hh:161
uint16_t MicroPC
Definition types.hh:149
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568

Generated on Mon Jul 10 2023 14:24:27 for gem5 by doxygen 1.9.7