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) 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
45#include "base/bitunion.hh"
46#include "base/types.hh"
47#include "debug/Decoder.hh"
48
49namespace gem5
50{
51
52namespace ArmISA
53{
54
55BitUnion8(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;
67EndBitUnion(ITSTATE)
68
69class PCState : public GenericISA::UPCState<4>
70{
71 protected:
72
73 typedef GenericISA::UPCState<4> Base;
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:210
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
#define BitUnion8(name)
Definition bitunion.hh:497
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:213
#define EndBitUnion(name)
This closes off the class and union started by the above macro.
Definition bitunion.hh:428
uint8_t flags
Definition helpers.cc:66
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 4 > s
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
Bitfield< 34 > aarch64
Definition types.hh:81
Bitfield< 12, 11 > set
Bitfield< 4 > pc
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 Mon Jul 10 2023 14:24:27 for gem5 by doxygen 1.9.7