gem5  v22.1.0.0
pcstate.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2013, 2017-2018 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) 2007-2008 The Florida State University
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_ARM_PCSTATE_HH__
42 #define __ARCH_ARM_PCSTATE_HH__
43 
44 #include "arch/generic/pcstate.hh"
45 #include "base/bitunion.hh"
46 #include "base/types.hh"
47 #include "debug/Decoder.hh"
48 
49 namespace gem5
50 {
51 
52 namespace ArmISA
53 {
54 
55 BitUnion8(ITSTATE)
56  /* Note that the split (cond, mask) below is not as in ARM ARM.
57  * But it is more convenient for simulation. The condition
58  * is always the concatenation of the top 3 bits and the next bit,
59  * which applies when one of the bottom 4 bits is set.
60  * Refer to predecoder.cc for the use case.
61  */
62  Bitfield<7, 4> cond;
63  Bitfield<3, 0> mask;
64  // Bitfields for moving to/from CPSR
65  Bitfield<7, 2> top6;
66  Bitfield<1, 0> bottom2;
67 EndBitUnion(ITSTATE)
68 
69 class PCState : public GenericISA::UPCState<4>
70 {
71  protected:
72 
74 
75  enum FlagBits
76  {
77  ThumbBit = (1 << 0),
78  JazelleBit = (1 << 1),
79  AArch64Bit = (1 << 2)
80  };
81 
82  uint8_t flags = 0;
83  uint8_t nextFlags = 0;
84  uint8_t _itstate = 0;
85  uint8_t _nextItstate = 0;
86  uint8_t _size = 0;
87  bool _illegalExec = false;
88 
89  // Software Step flags
90  bool _debugStep = false;
91  bool _stepped = false;
92 
93  public:
94  void
95  set(Addr val)
96  {
97  Base::set(val);
98  npc(val + (thumb() ? 2 : 4));
99  }
100 
101  PCState(const PCState &other) : Base(other),
102  flags(other.flags), nextFlags(other.nextFlags),
103  _itstate(other._itstate), _nextItstate(other._nextItstate),
104  _size(other._size), _illegalExec(other._illegalExec),
105  _debugStep(other._debugStep), _stepped(other._stepped)
106  {}
107  PCState &operator=(const PCState &other) = default;
108 
109  PCState() {}
110  explicit PCState(Addr val) { set(val); }
111 
112  PCStateBase *clone() const override { return new PCState(*this); }
113 
114  void
115  update(const PCStateBase &other) override
116  {
117  Base::update(other);
118  auto &pcstate = other.as<PCState>();
119  flags = pcstate.flags;
120  nextFlags = pcstate.nextFlags;
121  _itstate = pcstate._itstate;
122  _nextItstate = pcstate._nextItstate;
123  _size = pcstate._size;
124  _illegalExec = pcstate._illegalExec;
125  _debugStep = pcstate._debugStep;
126  _stepped = pcstate._stepped;
127  }
128 
129  bool
130  illegalExec() const
131  {
132  return _illegalExec;
133  }
134 
135  void
136  illegalExec(bool val)
137  {
138  _illegalExec = val;
139  }
140 
141  bool
142  debugStep() const
143  {
144  return _debugStep;
145  }
146 
147  void
148  debugStep(bool val)
149  {
150  _debugStep = val;
151  }
152 
153  bool
154  stepped() const
155  {
156  return _stepped;
157  }
158 
159  void
160  stepped(bool val)
161  {
162  _stepped = val;
163  }
164 
165  bool
166  thumb() const
167  {
168  return flags & ThumbBit;
169  }
170 
171  void
172  thumb(bool val)
173  {
174  if (val)
175  flags |= ThumbBit;
176  else
177  flags &= ~ThumbBit;
178  }
179 
180  bool
181  nextThumb() const
182  {
183  return nextFlags & ThumbBit;
184  }
185 
186  void
187  nextThumb(bool val)
188  {
189  if (val)
190  nextFlags |= ThumbBit;
191  else
192  nextFlags &= ~ThumbBit;
193  }
194 
195  void size(uint8_t s) { _size = s; }
196  uint8_t size() const { return _size; }
197 
198  bool
199  branching() const override
200  {
201  return ((this->pc() + this->size()) != this->npc());
202  }
203 
204 
205  bool
206  jazelle() const
207  {
208  return flags & JazelleBit;
209  }
210 
211  void
212  jazelle(bool val)
213  {
214  if (val)
215  flags |= JazelleBit;
216  else
217  flags &= ~JazelleBit;
218  }
219 
220  bool
221  nextJazelle() const
222  {
223  return nextFlags & JazelleBit;
224  }
225 
226  void
227  nextJazelle(bool val)
228  {
229  if (val)
230  nextFlags |= JazelleBit;
231  else
232  nextFlags &= ~JazelleBit;
233  }
234 
235  bool
236  aarch64() const
237  {
238  return flags & AArch64Bit;
239  }
240 
241  void
242  aarch64(bool val)
243  {
244  if (val)
245  flags |= AArch64Bit;
246  else
247  flags &= ~AArch64Bit;
248  }
249 
250  bool
251  nextAArch64() const
252  {
253  return nextFlags & AArch64Bit;
254  }
255 
256  void
257  nextAArch64(bool val)
258  {
259  if (val)
260  nextFlags |= AArch64Bit;
261  else
262  nextFlags &= ~AArch64Bit;
263  }
264 
265 
266  uint8_t
267  itstate() const
268  {
269  return _itstate;
270  }
271 
272  void
273  itstate(uint8_t value)
274  {
275  _itstate = value;
276  }
277 
278  uint8_t
279  nextItstate() const
280  {
281  return _nextItstate;
282  }
283 
284  void
285  nextItstate(uint8_t value)
286  {
287  _nextItstate = value;
288  }
289 
290  void
291  advance() override
292  {
293  Base::advance();
294  flags = nextFlags;
295  npc(pc() + (thumb() ? 2 : 4));
296 
297  if (_nextItstate) {
298  _itstate = _nextItstate;
299  _nextItstate = 0;
300  } else if (_itstate) {
301  ITSTATE it = _itstate;
302  uint8_t cond_mask = it.mask;
303  uint8_t thumb_cond = it.cond;
304  DPRINTF(Decoder, "Advancing ITSTATE from %#x,%#x.\n",
305  thumb_cond, cond_mask);
306  cond_mask <<= 1;
307  uint8_t new_bit = bits(cond_mask, 4);
308  cond_mask &= mask(4);
309  if (cond_mask == 0)
310  thumb_cond = 0;
311  else
312  replaceBits(thumb_cond, 0, new_bit);
313  DPRINTF(Decoder, "Advancing ITSTATE to %#x,%#x.\n",
314  thumb_cond, cond_mask);
315  it.mask = cond_mask;
316  it.cond = thumb_cond;
317  _itstate = it;
318  }
319  }
320 
321  void
322  uEnd()
323  {
324  advance();
325  upc(0);
326  nupc(1);
327  }
328 
329  Addr
330  instPC() const
331  {
332  return pc() + (thumb() ? 4 : 8);
333  }
334 
335  void
336  instNPC(Addr val)
337  {
338  // @todo: review this when AArch32/64 interprocessing is
339  // supported
340  if (aarch64())
341  npc(val); // AArch64 doesn't force PC alignment, a PC
342  // Alignment Fault can be raised instead
343  else
344  npc(val &~ mask(nextThumb() ? 1 : 2));
345  }
346 
347  Addr
348  instNPC() const
349  {
350  return npc();
351  }
352 
353  // Perform an interworking branch.
354  void
355  instIWNPC(Addr val)
356  {
357  bool thumbEE = (thumb() && jazelle());
358 
359  Addr newPC = val;
360  if (thumbEE) {
361  if (bits(newPC, 0)) {
362  newPC = newPC & ~mask(1);
363  } // else we have a bad interworking address; do not call
364  // panic() since the instruction could be executed
365  // speculatively
366  } else {
367  if (bits(newPC, 0)) {
368  nextThumb(true);
369  newPC = newPC & ~mask(1);
370  } else if (!bits(newPC, 1)) {
371  nextThumb(false);
372  } else {
373  // This state is UNPREDICTABLE in the ARM architecture
374  // The easy thing to do is just mask off the bit and
375  // stay in the current mode, so we'll do that.
376  newPC &= ~mask(2);
377  }
378  }
379  npc(newPC);
380  }
381 
382  // Perform an interworking branch in ARM mode, a regular branch
383  // otherwise.
384  void
385  instAIWNPC(Addr val)
386  {
387  if (!thumb() && !jazelle())
388  instIWNPC(val);
389  else
390  instNPC(val);
391  }
392 
393  bool
394  equals(const PCStateBase &other) const override
395  {
396  auto &opc = other.as<PCState>();
397  return Base::equals(other) &&
398  flags == opc.flags && nextFlags == opc.nextFlags &&
399  _itstate == opc._itstate &&
400  _nextItstate == opc._nextItstate &&
401  _illegalExec == opc._illegalExec &&
402  _debugStep == opc._debugStep &&
403  _stepped == opc._stepped;
404  }
405 
406  void
407  serialize(CheckpointOut &cp) const override
408  {
409  Base::serialize(cp);
411  SERIALIZE_SCALAR(_size);
412  SERIALIZE_SCALAR(nextFlags);
413  SERIALIZE_SCALAR(_itstate);
414  SERIALIZE_SCALAR(_nextItstate);
415  SERIALIZE_SCALAR(_illegalExec);
416  SERIALIZE_SCALAR(_debugStep);
417  SERIALIZE_SCALAR(_stepped);
418  }
419 
420  void
421  unserialize(CheckpointIn &cp) override
422  {
423  Base::unserialize(cp);
425  UNSERIALIZE_SCALAR(_size);
426  UNSERIALIZE_SCALAR(nextFlags);
427  UNSERIALIZE_SCALAR(_itstate);
428  UNSERIALIZE_SCALAR(_nextItstate);
429  UNSERIALIZE_SCALAR(_illegalExec);
430  UNSERIALIZE_SCALAR(_debugStep);
431  UNSERIALIZE_SCALAR(_stepped);
432  }
433 };
434 
435 } // namespace ArmISA
436 } // namespace gem5
437 
438 #endif
#define DPRINTF(x,...)
Definition: trace.hh:186
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Target & as()
Definition: pcstate.hh:72
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
constexpr void replaceBits(T &val, unsigned first, unsigned last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:197
uint8_t flags
Definition: helpers.cc:66
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
Bitfield< 4 > s
Definition: misc_types.hh:568
Bitfield< 7, 2 > top6
Definition: pcstate.hh:65
Bitfield< 60 > debugStep
Definition: types.hh:63
Bitfield< 36 > thumb
Definition: types.hh:79
Bitfield< 1, 0 > bottom2
Definition: pcstate.hh:66
Bitfield< 55, 48 > itstate
Definition: types.hh:70
EndBitUnion(PackedIntReg) namespace int_reg
Definition: int.hh:65
Bitfield< 34 > aarch64
Definition: types.hh:81
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
BitUnion8(ITSTATE) Bitfield< 7
Bitfield< 4 > pc
GenericISA::DelaySlotUPCState< 4 > PCState
Definition: pcstate.hh:40
Bitfield< 63 > val
Definition: misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
#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