gem5  v22.1.0.0
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 
53 namespace gem5
54 {
55 
56 // The guaranteed interface.
57 class PCStateBase : public Serializable
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 &
72  as()
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
140  unserialize(CheckpointIn &cp) override
141  {
144  }
145 };
146 
147 static inline std::ostream &
148 operator<<(std::ostream & os, const PCStateBase &pc)
149 {
150  pc.output(os);
151  return os;
152 }
153 
154 static inline bool
156 {
157  return a.equals(b);
158 }
159 
160 static inline bool
162 {
163  return !a.equals(b);
164 }
165 
166 namespace
167 {
168 
169 inline void
170 set(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 
190 inline void
191 set(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 
199 inline void
200 set(PCStateBase *&dest, const std::unique_ptr<PCStateBase> &src)
201 {
202  const PCStateBase *src_ptr = src.get();
203  set(dest, src_ptr);
204 }
205 
206 inline void
207 set(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 
217 inline void
218 set(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 
229 inline void
230 set(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 
238 inline void
239 set(PCStateBase &dest, const PCStateBase &src)
240 {
241  dest.update(src);
242 }
243 
244 } // anonymous namespace
245 
246 namespace GenericISA
247 {
248 
250 {
251  protected:
252  Addr _npc = 0;
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
321  unserialize(CheckpointIn &cp) override
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.
337 template <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 
349  PCStateBase *
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.
384 template <int InstWidth>
385 class UPCState : public SimplePCState<InstWidth>
386 {
387  protected:
389 
390  public:
391  void
392  output(std::ostream &os) const override
393  {
394  Base::output(os);
395  ccprintf(os, ".(%d=>%d)", this->upc(), this->nupc());
396  }
397 
398  PCStateBase *
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;
414  UPCState() {}
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.
443 template <int InstWidth>
444 class 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 
458  PCStateBase *
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  {}
485  DelaySlotPCState &operator=(const DelaySlotPCState &other) = default;
487  explicit DelaySlotPCState(Addr val) { set(val); }
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
521  unserialize(CheckpointIn &cp) override
522  {
523  Base::unserialize(cp);
525  }
526 };
527 
528 // A PC with a delay slot and a microcode PC.
529 template <int InstWidth>
530 class DelaySlotUPCState : public DelaySlotPCState<InstWidth>
531 {
532  protected:
534 
535  public:
536  void
537  output(std::ostream &os) const override
538  {
539  Base::output(os);
540  ccprintf(os, ".(%d=>%d)", this->upc(), this->nupc());
541  }
542 
543  PCStateBase *
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) {}
560  explicit DelaySlotUPCState(Addr val) { set(val); }
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(const DelaySlotPCState &other)
Definition: pcstate.hh:482
DelaySlotPCState & operator=(const DelaySlotPCState &other)=default
void output(std::ostream &os) const override
Definition: pcstate.hh:453
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pcstate.hh:514
PCStateBase * clone() const override
Definition: pcstate.hh:459
bool equals(const PCStateBase &other) const override
Definition: pcstate.hh:507
SimplePCState< InstWidth > Base
Definition: pcstate.hh:447
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
PCStateBase * clone() const override
Definition: pcstate.hh:544
bool branching() const override
Definition: pcstate.hh:563
DelaySlotUPCState(const DelaySlotUPCState &other)
Definition: pcstate.hh:557
PCStateWithNext & operator=(const PCStateWithNext &other)=default
void output(std::ostream &os) const override
Definition: pcstate.hh:290
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pcstate.hh:321
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
PCStateBase * clone() const override
Definition: pcstate.hh:350
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
void set(Addr val)
Definition: pcstate.hh:405
UPCState & operator=(const UPCState &other)=default
PCStateBase * clone() const override
Definition: pcstate.hh:399
void output(std::ostream &os) const override
Definition: pcstate.hh:392
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
virtual bool branching() const =0
MicroPC microPC() const
Returns the current micropc.
Definition: pcstate.hh:118
PCStateBase & operator=(const PCStateBase &other)=default
virtual void advance()=0
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
Target & as()
Definition: pcstate.hh:72
void update(const PCStateBase *ptr)
Definition: pcstate.hh:91
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 * clone() const =0
const Target & as() const
Definition: pcstate.hh:79
MicroPC _upc
Definition: pcstate.hh:61
virtual ~PCStateBase()=default
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
Definition: misc_types.hh:520
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 8 > a
Definition: misc_types.hh:66
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
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 Wed Dec 21 2022 10:22:26 for gem5 by doxygen 1.9.1