1 // Copyright 2015, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright notice,
10 // this list of conditions and the following disclaimer in the documentation
11 // and/or other materials provided with the distribution.
12 // * Neither the name of ARM Limited nor the names of its contributors may be
13 // used to endorse or promote products derived from this software without
14 // specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 #ifndef VIXL_AARCH64_SIMULATOR_AARCH64_H_
28 #define VIXL_AARCH64_SIMULATOR_AARCH64_H_
29
30 #include <vector>
31
32 #include "../globals-vixl.h"
33 #include "../utils-vixl.h"
34
35 #include "cpu-features.h"
36 #include "abi-aarch64.h"
37 #include "cpu-features-auditor-aarch64.h"
38 #include "disasm-aarch64.h"
39 #include "instructions-aarch64.h"
40 #include "instrument-aarch64.h"
41 #include "simulator-constants-aarch64.h"
42
43 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
44
45 // These are only used for the ABI feature, and depend on checks performed for
46 // it.
47 #ifdef VIXL_HAS_ABI_SUPPORT
48 #include <tuple>
49 #if __cplusplus >= 201402L
50 // Required for `std::index_sequence`
51 #include <utility>
52 #endif
53 #endif
54
55 namespace vixl {
56 namespace aarch64 {
57
58 // Representation of memory, with typed getters and setters for access.
59 class Memory {
60 public:
61 template <typename T>
AddressUntag(T address)62 static T AddressUntag(T address) {
63 // Cast the address using a C-style cast. A reinterpret_cast would be
64 // appropriate, but it can't cast one integral type to another.
65 uint64_t bits = (uint64_t)address;
66 return (T)(bits & ~kAddressTagMask);
67 }
68
69 template <typename T, typename A>
Read(A address)70 static T Read(A address) {
71 T value;
72 address = AddressUntag(address);
73 VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
74 (sizeof(value) == 4) || (sizeof(value) == 8) ||
75 (sizeof(value) == 16));
76 memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
77 return value;
78 }
79
80 template <typename T, typename A>
Write(A address,T value)81 static void Write(A address, T value) {
82 address = AddressUntag(address);
83 VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
84 (sizeof(value) == 4) || (sizeof(value) == 8) ||
85 (sizeof(value) == 16));
86 memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
87 }
88 };
89
90 // Represent a register (r0-r31, v0-v31).
91 template <int kSizeInBytes>
92 class SimRegisterBase {
93 public:
SimRegisterBase()94 SimRegisterBase() : written_since_last_log_(false) {}
95
96 // Write the specified value. The value is zero-extended if necessary.
97 template <typename T>
Write(T new_value)98 void Write(T new_value) {
99 if (sizeof(new_value) < kSizeInBytes) {
100 // All AArch64 registers are zero-extending.
101 memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value));
102 }
103 WriteLane(new_value, 0);
104 NotifyRegisterWrite();
105 }
106 template <typename T>
Set(T new_value)107 VIXL_DEPRECATED("Write", void Set(T new_value)) {
108 Write(new_value);
109 }
110
111 // Insert a typed value into a register, leaving the rest of the register
112 // unchanged. The lane parameter indicates where in the register the value
113 // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
114 // 0 represents the least significant bits.
115 template <typename T>
Insert(int lane,T new_value)116 void Insert(int lane, T new_value) {
117 WriteLane(new_value, lane);
118 NotifyRegisterWrite();
119 }
120
121 // Get the value as the specified type. The value is truncated if necessary.
122 template <typename T>
Get()123 T Get() const {
124 return GetLane<T>(0);
125 }
126
127 // Get the lane value as the specified type. The value is truncated if
128 // necessary.
129 template <typename T>
GetLane(int lane)130 T GetLane(int lane) const {
131 T result;
132 ReadLane(&result, lane);
133 return result;
134 }
135 template <typename T>
136 VIXL_DEPRECATED("GetLane", T Get(int lane) const) {
137 return GetLane(lane);
138 }
139
140 // TODO: Make this return a map of updated bytes, so that we can highlight
141 // updated lanes for load-and-insert. (That never happens for scalar code, but
142 // NEON has some instructions that can update individual lanes.)
WrittenSinceLastLog()143 bool WrittenSinceLastLog() const { return written_since_last_log_; }
144
NotifyRegisterLogged()145 void NotifyRegisterLogged() { written_since_last_log_ = false; }
146
147 protected:
148 uint8_t value_[kSizeInBytes];
149
150 // Helpers to aid with register tracing.
151 bool written_since_last_log_;
152
NotifyRegisterWrite()153 void NotifyRegisterWrite() { written_since_last_log_ = true; }
154
155 private:
156 template <typename T>
ReadLane(T * dst,int lane)157 void ReadLane(T* dst, int lane) const {
158 VIXL_ASSERT(lane >= 0);
159 VIXL_ASSERT((sizeof(*dst) + (lane * sizeof(*dst))) <= kSizeInBytes);
160 memcpy(dst, &value_[lane * sizeof(*dst)], sizeof(*dst));
161 }
162
163 template <typename T>
WriteLane(T src,int lane)164 void WriteLane(T src, int lane) {
165 VIXL_ASSERT(lane >= 0);
166 VIXL_ASSERT((sizeof(src) + (lane * sizeof(src))) <= kSizeInBytes);
167 memcpy(&value_[lane * sizeof(src)], &src, sizeof(src));
168 }
169 };
170 typedef SimRegisterBase<kXRegSizeInBytes> SimRegister; // r0-r31
171 typedef SimRegisterBase<kQRegSizeInBytes> SimVRegister; // v0-v31
172
173 // The default ReadLane and WriteLane methods assume what we are copying is
174 // "trivially copyable" by using memcpy. We have to provide alternative
175 // implementations for SimFloat16 which cannot be copied this way.
176
177 template <>
178 template <>
ReadLane(vixl::internal::SimFloat16 * dst,int lane)179 inline void SimVRegister::ReadLane(vixl::internal::SimFloat16* dst,
180 int lane) const {
181 uint16_t rawbits;
182 ReadLane(&rawbits, lane);
183 *dst = RawbitsToFloat16(rawbits);
184 }
185
186 template <>
187 template <>
WriteLane(vixl::internal::SimFloat16 src,int lane)188 inline void SimVRegister::WriteLane(vixl::internal::SimFloat16 src, int lane) {
189 WriteLane(Float16ToRawbits(src), lane);
190 }
191
192 // Representation of a vector register, with typed getters and setters for lanes
193 // and additional information to represent lane state.
194 class LogicVRegister {
195 public:
LogicVRegister(SimVRegister & other)196 inline LogicVRegister(
197 SimVRegister& other) // NOLINT(runtime/references)(runtime/explicit)
198 : register_(other) {
199 for (size_t i = 0; i < ArrayLength(saturated_); i++) {
200 saturated_[i] = kNotSaturated;
201 }
202 for (size_t i = 0; i < ArrayLength(round_); i++) {
203 round_[i] = 0;
204 }
205 }
206
Int(VectorFormat vform,int index)207 int64_t Int(VectorFormat vform, int index) const {
208 int64_t element;
209 switch (LaneSizeInBitsFromFormat(vform)) {
210 case 8:
211 element = register_.GetLane<int8_t>(index);
212 break;
213 case 16:
214 element = register_.GetLane<int16_t>(index);
215 break;
216 case 32:
217 element = register_.GetLane<int32_t>(index);
218 break;
219 case 64:
220 element = register_.GetLane<int64_t>(index);
221 break;
222 default:
223 VIXL_UNREACHABLE();
224 return 0;
225 }
226 return element;
227 }
228
Uint(VectorFormat vform,int index)229 uint64_t Uint(VectorFormat vform, int index) const {
230 uint64_t element;
231 switch (LaneSizeInBitsFromFormat(vform)) {
232 case 8:
233 element = register_.GetLane<uint8_t>(index);
234 break;
235 case 16:
236 element = register_.GetLane<uint16_t>(index);
237 break;
238 case 32:
239 element = register_.GetLane<uint32_t>(index);
240 break;
241 case 64:
242 element = register_.GetLane<uint64_t>(index);
243 break;
244 default:
245 VIXL_UNREACHABLE();
246 return 0;
247 }
248 return element;
249 }
250
UintLeftJustified(VectorFormat vform,int index)251 uint64_t UintLeftJustified(VectorFormat vform, int index) const {
252 return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
253 }
254
IntLeftJustified(VectorFormat vform,int index)255 int64_t IntLeftJustified(VectorFormat vform, int index) const {
256 uint64_t value = UintLeftJustified(vform, index);
257 int64_t result;
258 memcpy(&result, &value, sizeof(result));
259 return result;
260 }
261
SetInt(VectorFormat vform,int index,int64_t value)262 void SetInt(VectorFormat vform, int index, int64_t value) const {
263 switch (LaneSizeInBitsFromFormat(vform)) {
264 case 8:
265 register_.Insert(index, static_cast<int8_t>(value));
266 break;
267 case 16:
268 register_.Insert(index, static_cast<int16_t>(value));
269 break;
270 case 32:
271 register_.Insert(index, static_cast<int32_t>(value));
272 break;
273 case 64:
274 register_.Insert(index, static_cast<int64_t>(value));
275 break;
276 default:
277 VIXL_UNREACHABLE();
278 return;
279 }
280 }
281
SetIntArray(VectorFormat vform,const int64_t * src)282 void SetIntArray(VectorFormat vform, const int64_t* src) const {
283 ClearForWrite(vform);
284 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
285 SetInt(vform, i, src[i]);
286 }
287 }
288
SetUint(VectorFormat vform,int index,uint64_t value)289 void SetUint(VectorFormat vform, int index, uint64_t value) const {
290 switch (LaneSizeInBitsFromFormat(vform)) {
291 case 8:
292 register_.Insert(index, static_cast<uint8_t>(value));
293 break;
294 case 16:
295 register_.Insert(index, static_cast<uint16_t>(value));
296 break;
297 case 32:
298 register_.Insert(index, static_cast<uint32_t>(value));
299 break;
300 case 64:
301 register_.Insert(index, static_cast<uint64_t>(value));
302 break;
303 default:
304 VIXL_UNREACHABLE();
305 return;
306 }
307 }
308
SetUintArray(VectorFormat vform,const uint64_t * src)309 void SetUintArray(VectorFormat vform, const uint64_t* src) const {
310 ClearForWrite(vform);
311 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
312 SetUint(vform, i, src[i]);
313 }
314 }
315
ReadUintFromMem(VectorFormat vform,int index,uint64_t addr)316 void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const {
317 switch (LaneSizeInBitsFromFormat(vform)) {
318 case 8:
319 register_.Insert(index, Memory::Read<uint8_t>(addr));
320 break;
321 case 16:
322 register_.Insert(index, Memory::Read<uint16_t>(addr));
323 break;
324 case 32:
325 register_.Insert(index, Memory::Read<uint32_t>(addr));
326 break;
327 case 64:
328 register_.Insert(index, Memory::Read<uint64_t>(addr));
329 break;
330 default:
331 VIXL_UNREACHABLE();
332 return;
333 }
334 }
335
WriteUintToMem(VectorFormat vform,int index,uint64_t addr)336 void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const {
337 uint64_t value = Uint(vform, index);
338 switch (LaneSizeInBitsFromFormat(vform)) {
339 case 8:
340 Memory::Write(addr, static_cast<uint8_t>(value));
341 break;
342 case 16:
343 Memory::Write(addr, static_cast<uint16_t>(value));
344 break;
345 case 32:
346 Memory::Write(addr, static_cast<uint32_t>(value));
347 break;
348 case 64:
349 Memory::Write(addr, value);
350 break;
351 }
352 }
353
354 template <typename T>
Float(int index)355 T Float(int index) const {
356 return register_.GetLane<T>(index);
357 }
358
359 template <typename T>
SetFloat(int index,T value)360 void SetFloat(int index, T value) const {
361 register_.Insert(index, value);
362 }
363
364 // When setting a result in a register of size less than Q, the top bits of
365 // the Q register must be cleared.
ClearForWrite(VectorFormat vform)366 void ClearForWrite(VectorFormat vform) const {
367 unsigned size = RegisterSizeInBytesFromFormat(vform);
368 for (unsigned i = size; i < kQRegSizeInBytes; i++) {
369 SetUint(kFormat16B, i, 0);
370 }
371 }
372
373 // Saturation state for each lane of a vector.
374 enum Saturation {
375 kNotSaturated = 0,
376 kSignedSatPositive = 1 << 0,
377 kSignedSatNegative = 1 << 1,
378 kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
379 kSignedSatUndefined = kSignedSatMask,
380 kUnsignedSatPositive = 1 << 2,
381 kUnsignedSatNegative = 1 << 3,
382 kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
383 kUnsignedSatUndefined = kUnsignedSatMask
384 };
385
386 // Getters for saturation state.
GetSignedSaturation(int index)387 Saturation GetSignedSaturation(int index) {
388 return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
389 }
390
GetUnsignedSaturation(int index)391 Saturation GetUnsignedSaturation(int index) {
392 return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
393 }
394
395 // Setters for saturation state.
ClearSat(int index)396 void ClearSat(int index) { saturated_[index] = kNotSaturated; }
397
SetSignedSat(int index,bool positive)398 void SetSignedSat(int index, bool positive) {
399 SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
400 }
401
SetUnsignedSat(int index,bool positive)402 void SetUnsignedSat(int index, bool positive) {
403 SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
404 }
405
SetSatFlag(int index,Saturation sat)406 void SetSatFlag(int index, Saturation sat) {
407 saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
408 VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined);
409 VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined);
410 }
411
412 // Saturate lanes of a vector based on saturation state.
SignedSaturate(VectorFormat vform)413 LogicVRegister& SignedSaturate(VectorFormat vform) {
414 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
415 Saturation sat = GetSignedSaturation(i);
416 if (sat == kSignedSatPositive) {
417 SetInt(vform, i, MaxIntFromFormat(vform));
418 } else if (sat == kSignedSatNegative) {
419 SetInt(vform, i, MinIntFromFormat(vform));
420 }
421 }
422 return *this;
423 }
424
UnsignedSaturate(VectorFormat vform)425 LogicVRegister& UnsignedSaturate(VectorFormat vform) {
426 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
427 Saturation sat = GetUnsignedSaturation(i);
428 if (sat == kUnsignedSatPositive) {
429 SetUint(vform, i, MaxUintFromFormat(vform));
430 } else if (sat == kUnsignedSatNegative) {
431 SetUint(vform, i, 0);
432 }
433 }
434 return *this;
435 }
436
437 // Getter for rounding state.
GetRounding(int index)438 bool GetRounding(int index) { return round_[index]; }
439
440 // Setter for rounding state.
SetRounding(int index,bool round)441 void SetRounding(int index, bool round) { round_[index] = round; }
442
443 // Round lanes of a vector based on rounding state.
Round(VectorFormat vform)444 LogicVRegister& Round(VectorFormat vform) {
445 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
446 SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0));
447 }
448 return *this;
449 }
450
451 // Unsigned halve lanes of a vector, and use the saturation state to set the
452 // top bit.
Uhalve(VectorFormat vform)453 LogicVRegister& Uhalve(VectorFormat vform) {
454 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
455 uint64_t val = Uint(vform, i);
456 SetRounding(i, (val & 1) == 1);
457 val >>= 1;
458 if (GetUnsignedSaturation(i) != kNotSaturated) {
459 // If the operation causes unsigned saturation, the bit shifted into the
460 // most significant bit must be set.
461 val |= (MaxUintFromFormat(vform) >> 1) + 1;
462 }
463 SetInt(vform, i, val);
464 }
465 return *this;
466 }
467
468 // Signed halve lanes of a vector, and use the carry state to set the top bit.
Halve(VectorFormat vform)469 LogicVRegister& Halve(VectorFormat vform) {
470 for (int i = 0; i < LaneCountFromFormat(vform); i++) {
471 int64_t val = Int(vform, i);
472 SetRounding(i, (val & 1) == 1);
473 val >>= 1;
474 if (GetSignedSaturation(i) != kNotSaturated) {
475 // If the operation causes signed saturation, the sign bit must be
476 // inverted.
477 val ^= (MaxUintFromFormat(vform) >> 1) + 1;
478 }
479 SetInt(vform, i, val);
480 }
481 return *this;
482 }
483
484 private:
485 SimVRegister& register_;
486
487 // Allocate one saturation state entry per lane; largest register is type Q,
488 // and lanes can be a minimum of one byte wide.
489 Saturation saturated_[kQRegSizeInBytes];
490
491 // Allocate one rounding state entry per lane.
492 bool round_[kQRegSizeInBytes];
493 };
494
495 // The proper way to initialize a simulated system register (such as NZCV) is as
496 // follows:
497 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
498 class SimSystemRegister {
499 public:
500 // The default constructor represents a register which has no writable bits.
501 // It is not possible to set its value to anything other than 0.
SimSystemRegister()502 SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
503
GetRawValue()504 uint32_t GetRawValue() const { return value_; }
505 VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) {
506 return GetRawValue();
507 }
508
SetRawValue(uint32_t new_value)509 void SetRawValue(uint32_t new_value) {
510 value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
511 }
512
ExtractBits(int msb,int lsb)513 uint32_t ExtractBits(int msb, int lsb) const {
514 return ExtractUnsignedBitfield32(msb, lsb, value_);
515 }
516 VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) {
517 return ExtractBits(msb, lsb);
518 }
519
ExtractSignedBits(int msb,int lsb)520 int32_t ExtractSignedBits(int msb, int lsb) const {
521 return ExtractSignedBitfield32(msb, lsb, value_);
522 }
523 VIXL_DEPRECATED("ExtractSignedBits",
524 int32_t SignedBits(int msb, int lsb) const) {
525 return ExtractSignedBits(msb, lsb);
526 }
527
528 void SetBits(int msb, int lsb, uint32_t bits);
529
530 // Default system register values.
531 static SimSystemRegister DefaultValueFor(SystemRegister id);
532
533 #define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
534 uint32_t Get##Name() const { return this->Func(HighBit, LowBit); } \
535 VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \
536 void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); }
537 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
538 static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
539
SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER,DEFINE_WRITE_IGNORE_MASK)540 SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
541
542 #undef DEFINE_ZERO_BITS
543 #undef DEFINE_GETTER
544
545 protected:
546 // Most system registers only implement a few of the bits in the word. Other
547 // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
548 // describes the bits which are not modifiable.
549 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
550 : value_(value), write_ignore_mask_(write_ignore_mask) {}
551
552 uint32_t value_;
553 uint32_t write_ignore_mask_;
554 };
555
556
557 class SimExclusiveLocalMonitor {
558 public:
SimExclusiveLocalMonitor()559 SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) {
560 Clear();
561 }
562
563 // Clear the exclusive monitor (like clrex).
Clear()564 void Clear() {
565 address_ = 0;
566 size_ = 0;
567 }
568
569 // Clear the exclusive monitor most of the time.
MaybeClear()570 void MaybeClear() {
571 if ((seed_ % kSkipClearProbability) != 0) {
572 Clear();
573 }
574
575 // Advance seed_ using a simple linear congruential generator.
576 seed_ = (seed_ * 48271) % 2147483647;
577 }
578
579 // Mark the address range for exclusive access (like load-exclusive).
MarkExclusive(uint64_t address,size_t size)580 void MarkExclusive(uint64_t address, size_t size) {
581 address_ = address;
582 size_ = size;
583 }
584
585 // Return true if the address range is marked (like store-exclusive).
586 // This helper doesn't implicitly clear the monitor.
IsExclusive(uint64_t address,size_t size)587 bool IsExclusive(uint64_t address, size_t size) {
588 VIXL_ASSERT(size > 0);
589 // Be pedantic: Require both the address and the size to match.
590 return (size == size_) && (address == address_);
591 }
592
593 private:
594 uint64_t address_;
595 size_t size_;
596
597 const int kSkipClearProbability;
598 uint32_t seed_;
599 };
600
601
602 // We can't accurate simulate the global monitor since it depends on external
603 // influences. Instead, this implementation occasionally causes accesses to
604 // fail, according to kPassProbability.
605 class SimExclusiveGlobalMonitor {
606 public:
SimExclusiveGlobalMonitor()607 SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {}
608
IsExclusive(uint64_t address,size_t size)609 bool IsExclusive(uint64_t address, size_t size) {
610 USE(address, size);
611
612 bool pass = (seed_ % kPassProbability) != 0;
613 // Advance seed_ using a simple linear congruential generator.
614 seed_ = (seed_ * 48271) % 2147483647;
615 return pass;
616 }
617
618 private:
619 const int kPassProbability;
620 uint32_t seed_;
621 };
622
623
624 class Simulator : public DecoderVisitor {
625 public:
626 explicit Simulator(Decoder* decoder, FILE* stream = stdout);
627 ~Simulator();
628
629 void ResetState();
630
631 // Run the simulator.
632 virtual void Run();
633 void RunFrom(const Instruction* first);
634
635
636 #if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
637 (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
638 // Templated `RunFrom` version taking care of passing arguments and returning
639 // the result value.
640 // This allows code like:
641 // int32_t res = simulator.RunFrom<int32_t, int32_t>(GenerateCode(),
642 // 0x123);
643 // It requires VIXL's ABI features, and C++11 or greater.
644 // Also, the initialisation of tuples is incorrect in GCC before 4.9.1:
645 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
646 template <typename R, typename... P>
RunFrom(const Instruction * code,P...arguments)647 R RunFrom(const Instruction* code, P... arguments) {
648 return RunFromStructHelper<R, P...>::Wrapper(this, code, arguments...);
649 }
650
651 template <typename R, typename... P>
652 struct RunFromStructHelper {
WrapperRunFromStructHelper653 static R Wrapper(Simulator* simulator,
654 const Instruction* code,
655 P... arguments) {
656 ABI abi;
657 std::tuple<P...> unused_tuple{
658 // TODO: We currently do not support arguments passed on the stack. We
659 // could do so by using `WriteGenericOperand()` here, but may need to
660 // add features to handle situations where the stack is or is not set
661 // up.
662 (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
663 .GetCPURegister(),
664 arguments),
665 arguments)...};
666 simulator->RunFrom(code);
667 return simulator->ReadGenericOperand<R>(abi.GetReturnGenericOperand<R>());
668 }
669 };
670
671 // Partial specialization when the return type is `void`.
672 template <typename... P>
673 struct RunFromStructHelper<void, P...> {
674 static void Wrapper(Simulator* simulator,
675 const Instruction* code,
676 P... arguments) {
677 ABI abi;
678 std::tuple<P...> unused_tuple{
679 // TODO: We currently do not support arguments passed on the stack. We
680 // could do so by using `WriteGenericOperand()` here, but may need to
681 // add features to handle situations where the stack is or is not set
682 // up.
683 (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
684 .GetCPURegister(),
685 arguments),
686 arguments)...};
687 simulator->RunFrom(code);
688 }
689 };
690 #endif
691
692 // Execution ends when the PC hits this address.
693 static const Instruction* kEndOfSimAddress;
694
695 // Simulation helpers.
696 const Instruction* ReadPc() const { return pc_; }
697 VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
698
699 enum BranchLogMode { LogBranches, NoBranchLog };
700
701 void WritePc(const Instruction* new_pc,
702 BranchLogMode log_mode = LogBranches) {
703 if (log_mode == LogBranches) LogTakenBranch(new_pc);
704 pc_ = Memory::AddressUntag(new_pc);
705 pc_modified_ = true;
706 }
707 VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) {
708 return WritePc(new_pc);
709 }
710
711 void IncrementPc() {
712 if (!pc_modified_) {
713 pc_ = pc_->GetNextInstruction();
714 }
715 }
716 VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); }
717
718 void ExecuteInstruction() {
719 // The program counter should always be aligned.
720 VIXL_ASSERT(IsWordAligned(pc_));
721 pc_modified_ = false;
722
723 // decoder_->Decode(...) triggers at least the following visitors:
724 // 1. The CPUFeaturesAuditor (`cpu_features_auditor_`).
725 // 2. The PrintDisassembler (`print_disasm_`), if enabled.
726 // 3. The Simulator (`this`).
727 // User can add additional visitors at any point, but the Simulator requires
728 // that the ordering above is preserved.
729 decoder_->Decode(pc_);
730 IncrementPc();
731 LogAllWrittenRegisters();
732
733 VIXL_CHECK(cpu_features_auditor_.InstructionIsAvailable());
734 }
735
736 // Declare all Visitor functions.
737 #define DECLARE(A) \
738 virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE;
739 VISITOR_LIST_THAT_RETURN(DECLARE)
740 #undef DECLARE
741
742 #define DECLARE(A) \
743 VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr) \
744 VIXL_OVERRIDE;
745 VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
746 #undef DECLARE
747
748
749 // Integer register accessors.
750
751 // Basic accessor: Read the register as the specified type.
752 template <typename T>
753 T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
754 VIXL_ASSERT(
755 code < kNumberOfRegisters ||
756 ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
757 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
758 T result;
759 memset(&result, 0, sizeof(result));
760 return result;
761 }
762 if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
763 code = 31;
764 }
765 return registers_[code].Get<T>();
766 }
767 template <typename T>
768 VIXL_DEPRECATED("ReadRegister",
769 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister)
770 const) {
771 return ReadRegister<T>(code, r31mode);
772 }
773
774 // Common specialized accessors for the ReadRegister() template.
775 int32_t ReadWRegister(unsigned code,
776 Reg31Mode r31mode = Reg31IsZeroRegister) const {
777 return ReadRegister<int32_t>(code, r31mode);
778 }
779 VIXL_DEPRECATED("ReadWRegister",
780 int32_t wreg(unsigned code,
781 Reg31Mode r31mode = Reg31IsZeroRegister) const) {
782 return ReadWRegister(code, r31mode);
783 }
784
785 int64_t ReadXRegister(unsigned code,
786 Reg31Mode r31mode = Reg31IsZeroRegister) const {
787 return ReadRegister<int64_t>(code, r31mode);
788 }
789 VIXL_DEPRECATED("ReadXRegister",
790 int64_t xreg(unsigned code,
791 Reg31Mode r31mode = Reg31IsZeroRegister) const) {
792 return ReadXRegister(code, r31mode);
793 }
794
795 // As above, with parameterized size and return type. The value is
796 // either zero-extended or truncated to fit, as required.
797 template <typename T>
798 T ReadRegister(unsigned size,
799 unsigned code,
800 Reg31Mode r31mode = Reg31IsZeroRegister) const {
801 uint64_t raw;
802 switch (size) {
803 case kWRegSize:
804 raw = ReadRegister<uint32_t>(code, r31mode);
805 break;
806 case kXRegSize:
807 raw = ReadRegister<uint64_t>(code, r31mode);
808 break;
809 default:
810 VIXL_UNREACHABLE();
811 return 0;
812 }
813
814 T result;
815 VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
816 // Copy the result and truncate to fit. This assumes a little-endian host.
817 memcpy(&result, &raw, sizeof(result));
818 return result;
819 }
820 template <typename T>
821 VIXL_DEPRECATED("ReadRegister",
822 T reg(unsigned size,
823 unsigned code,
824 Reg31Mode r31mode = Reg31IsZeroRegister) const) {
825 return ReadRegister<T>(size, code, r31mode);
826 }
827
828 // Use int64_t by default if T is not specified.
829 int64_t ReadRegister(unsigned size,
830 unsigned code,
831 Reg31Mode r31mode = Reg31IsZeroRegister) const {
832 return ReadRegister<int64_t>(size, code, r31mode);
833 }
834 VIXL_DEPRECATED("ReadRegister",
835 int64_t reg(unsigned size,
836 unsigned code,
837 Reg31Mode r31mode = Reg31IsZeroRegister) const) {
838 return ReadRegister(size, code, r31mode);
839 }
840
841 enum RegLogMode { LogRegWrites, NoRegLog };
842
843 // Write 'value' into an integer register. The value is zero-extended. This
844 // behaviour matches AArch64 register writes.
845 template <typename T>
846 void WriteRegister(unsigned code,
847 T value,
848 RegLogMode log_mode = LogRegWrites,
849 Reg31Mode r31mode = Reg31IsZeroRegister) {
850 if (sizeof(T) < kWRegSizeInBytes) {
851 // We use a C-style cast on purpose here.
852 // Since we do not have access to 'constepxr if', the casts in this `if`
853 // must be valid even if we know the code will never be executed, in
854 // particular when `T` is a pointer type.
855 int64_t tmp_64bit = (int64_t)value;
856 int32_t tmp_32bit = static_cast<int32_t>(tmp_64bit);
857 WriteRegister<int32_t>(code, tmp_32bit, log_mode, r31mode);
858 return;
859 }
860
861 VIXL_ASSERT((sizeof(T) == kWRegSizeInBytes) ||
862 (sizeof(T) == kXRegSizeInBytes));
863 VIXL_ASSERT(
864 code < kNumberOfRegisters ||
865 ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
866
867 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
868 return;
869 }
870
871 if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
872 code = 31;
873 }
874
875 registers_[code].Write(value);
876
877 if (log_mode == LogRegWrites) LogRegister(code, r31mode);
878 }
879 template <typename T>
880 VIXL_DEPRECATED("WriteRegister",
881 void set_reg(unsigned code,
882 T value,
883 RegLogMode log_mode = LogRegWrites,
884 Reg31Mode r31mode = Reg31IsZeroRegister)) {
885 WriteRegister<T>(code, value, log_mode, r31mode);
886 }
887
888 // Common specialized accessors for the set_reg() template.
889 void WriteWRegister(unsigned code,
890 int32_t value,
891 RegLogMode log_mode = LogRegWrites,
892 Reg31Mode r31mode = Reg31IsZeroRegister) {
893 WriteRegister(code, value, log_mode, r31mode);
894 }
895 VIXL_DEPRECATED("WriteWRegister",
896 void set_wreg(unsigned code,
897 int32_t value,
898 RegLogMode log_mode = LogRegWrites,
899 Reg31Mode r31mode = Reg31IsZeroRegister)) {
900 WriteWRegister(code, value, log_mode, r31mode);
901 }
902
903 void WriteXRegister(unsigned code,
904 int64_t value,
905 RegLogMode log_mode = LogRegWrites,
906 Reg31Mode r31mode = Reg31IsZeroRegister) {
907 WriteRegister(code, value, log_mode, r31mode);
908 }
909 VIXL_DEPRECATED("WriteXRegister",
910 void set_xreg(unsigned code,
911 int64_t value,
912 RegLogMode log_mode = LogRegWrites,
913 Reg31Mode r31mode = Reg31IsZeroRegister)) {
914 WriteXRegister(code, value, log_mode, r31mode);
915 }
916
917 // As above, with parameterized size and type. The value is either
918 // zero-extended or truncated to fit, as required.
919 template <typename T>
920 void WriteRegister(unsigned size,
921 unsigned code,
922 T value,
923 RegLogMode log_mode = LogRegWrites,
924 Reg31Mode r31mode = Reg31IsZeroRegister) {
925 // Zero-extend the input.
926 uint64_t raw = 0;
927 VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw));
928 memcpy(&raw, &value, sizeof(value));
929
930 // Write (and possibly truncate) the value.
931 switch (size) {
932 case kWRegSize:
933 WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode);
934 break;
935 case kXRegSize:
936 WriteRegister(code, raw, log_mode, r31mode);
937 break;
938 default:
939 VIXL_UNREACHABLE();
940 return;
941 }
942 }
943 template <typename T>
944 VIXL_DEPRECATED("WriteRegister",
945 void set_reg(unsigned size,
946 unsigned code,
947 T value,
948 RegLogMode log_mode = LogRegWrites,
949 Reg31Mode r31mode = Reg31IsZeroRegister)) {
950 WriteRegister(size, code, value, log_mode, r31mode);
951 }
952
953 // Common specialized accessors for the set_reg() template.
954
955 // Commonly-used special cases.
956 template <typename T>
957 void WriteLr(T value) {
958 WriteRegister(kLinkRegCode, value);
959 }
960 template <typename T>
961 VIXL_DEPRECATED("WriteLr", void set_lr(T value)) {
962 WriteLr(value);
963 }
964
965 template <typename T>
966 void WriteSp(T value) {
967 WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer);
968 }
969 template <typename T>
970 VIXL_DEPRECATED("WriteSp", void set_sp(T value)) {
971 WriteSp(value);
972 }
973
974 // Vector register accessors.
975 // These are equivalent to the integer register accessors, but for vector
976 // registers.
977
978 // A structure for representing a 128-bit Q register.
979 struct qreg_t {
980 uint8_t val[kQRegSizeInBytes];
981 };
982
983 // Basic accessor: read the register as the specified type.
984 template <typename T>
985 T ReadVRegister(unsigned code) const {
986 VIXL_STATIC_ASSERT(
987 (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) ||
988 (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) ||
989 (sizeof(T) == kQRegSizeInBytes));
990 VIXL_ASSERT(code < kNumberOfVRegisters);
991
992 return vregisters_[code].Get<T>();
993 }
994 template <typename T>
995 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) {
996 return ReadVRegister<T>(code);
997 }
998
999 // Common specialized accessors for the vreg() template.
1000 int8_t ReadBRegister(unsigned code) const {
1001 return ReadVRegister<int8_t>(code);
1002 }
1003 VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) {
1004 return ReadBRegister(code);
1005 }
1006
1007 vixl::internal::SimFloat16 ReadHRegister(unsigned code) const {
1008 return RawbitsToFloat16(ReadHRegisterBits(code));
1009 }
1010 VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) {
1011 return Float16ToRawbits(ReadHRegister(code));
1012 }
1013
1014 uint16_t ReadHRegisterBits(unsigned code) const {
1015 return ReadVRegister<uint16_t>(code);
1016 }
1017
1018 float ReadSRegister(unsigned code) const {
1019 return ReadVRegister<float>(code);
1020 }
1021 VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) {
1022 return ReadSRegister(code);
1023 }
1024
1025 uint32_t ReadSRegisterBits(unsigned code) const {
1026 return ReadVRegister<uint32_t>(code);
1027 }
1028 VIXL_DEPRECATED("ReadSRegisterBits",
1029 uint32_t sreg_bits(unsigned code) const) {
1030 return ReadSRegisterBits(code);
1031 }
1032
1033 double ReadDRegister(unsigned code) const {
1034 return ReadVRegister<double>(code);
1035 }
1036 VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) {
1037 return ReadDRegister(code);
1038 }
1039
1040 uint64_t ReadDRegisterBits(unsigned code) const {
1041 return ReadVRegister<uint64_t>(code);
1042 }
1043 VIXL_DEPRECATED("ReadDRegisterBits",
1044 uint64_t dreg_bits(unsigned code) const) {
1045 return ReadDRegisterBits(code);
1046 }
1047
1048 qreg_t ReadQRegister(unsigned code) const {
1049 return ReadVRegister<qreg_t>(code);
1050 }
1051 VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) {
1052 return ReadQRegister(code);
1053 }
1054
1055 // As above, with parameterized size and return type. The value is
1056 // either zero-extended or truncated to fit, as required.
1057 template <typename T>
1058 T ReadVRegister(unsigned size, unsigned code) const {
1059 uint64_t raw = 0;
1060 T result;
1061
1062 switch (size) {
1063 case kSRegSize:
1064 raw = ReadVRegister<uint32_t>(code);
1065 break;
1066 case kDRegSize:
1067 raw = ReadVRegister<uint64_t>(code);
1068 break;
1069 default:
1070 VIXL_UNREACHABLE();
1071 break;
1072 }
1073
1074 VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
1075 // Copy the result and truncate to fit. This assumes a little-endian host.
1076 memcpy(&result, &raw, sizeof(result));
1077 return result;
1078 }
1079 template <typename T>
1080 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) {
1081 return ReadVRegister<T>(size, code);
1082 }
1083
1084 SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; }
1085 VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) {
1086 return ReadVRegister(code);
1087 }
1088
1089 // Basic accessor: Write the specified value.
1090 template <typename T>
1091 void WriteVRegister(unsigned code,
1092 T value,
1093 RegLogMode log_mode = LogRegWrites) {
1094 VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) ||
1095 (sizeof(value) == kHRegSizeInBytes) ||
1096 (sizeof(value) == kSRegSizeInBytes) ||
1097 (sizeof(value) == kDRegSizeInBytes) ||
1098 (sizeof(value) == kQRegSizeInBytes));
1099 VIXL_ASSERT(code < kNumberOfVRegisters);
1100 vregisters_[code].Write(value);
1101
1102 if (log_mode == LogRegWrites) {
1103 LogVRegister(code, GetPrintRegisterFormat(value));
1104 }
1105 }
1106 template <typename T>
1107 VIXL_DEPRECATED("WriteVRegister",
1108 void set_vreg(unsigned code,
1109 T value,
1110 RegLogMode log_mode = LogRegWrites)) {
1111 WriteVRegister(code, value, log_mode);
1112 }
1113
1114 // Common specialized accessors for the WriteVRegister() template.
1115 void WriteBRegister(unsigned code,
1116 int8_t value,
1117 RegLogMode log_mode = LogRegWrites) {
1118 WriteVRegister(code, value, log_mode);
1119 }
1120 VIXL_DEPRECATED("WriteBRegister",
1121 void set_breg(unsigned code,
1122 int8_t value,
1123 RegLogMode log_mode = LogRegWrites)) {
1124 return WriteBRegister(code, value, log_mode);
1125 }
1126
1127 void WriteHRegister(unsigned code,
1128 vixl::internal::SimFloat16 value,
1129 RegLogMode log_mode = LogRegWrites) {
1130 WriteVRegister(code, Float16ToRawbits(value), log_mode);
1131 }
1132
1133 void WriteHRegister(unsigned code,
1134 int16_t value,
1135 RegLogMode log_mode = LogRegWrites) {
1136 WriteVRegister(code, value, log_mode);
1137 }
1138 VIXL_DEPRECATED("WriteHRegister",
1139 void set_hreg(unsigned code,
1140 int16_t value,
1141 RegLogMode log_mode = LogRegWrites)) {
1142 return WriteHRegister(code, value, log_mode);
1143 }
1144
1145 void WriteSRegister(unsigned code,
1146 float value,
1147 RegLogMode log_mode = LogRegWrites) {
1148 WriteVRegister(code, value, log_mode);
1149 }
1150 VIXL_DEPRECATED("WriteSRegister",
1151 void set_sreg(unsigned code,
1152 float value,
1153 RegLogMode log_mode = LogRegWrites)) {
1154 WriteSRegister(code, value, log_mode);
1155 }
1156
1157 void WriteSRegisterBits(unsigned code,
1158 uint32_t value,
1159 RegLogMode log_mode = LogRegWrites) {
1160 WriteVRegister(code, value, log_mode);
1161 }
1162 VIXL_DEPRECATED("WriteSRegisterBits",
1163 void set_sreg_bits(unsigned code,
1164 uint32_t value,
1165 RegLogMode log_mode = LogRegWrites)) {
1166 WriteSRegisterBits(code, value, log_mode);
1167 }
1168
1169 void WriteDRegister(unsigned code,
1170 double value,
1171 RegLogMode log_mode = LogRegWrites) {
1172 WriteVRegister(code, value, log_mode);
1173 }
1174 VIXL_DEPRECATED("WriteDRegister",
1175 void set_dreg(unsigned code,
1176 double value,
1177 RegLogMode log_mode = LogRegWrites)) {
1178 WriteDRegister(code, value, log_mode);
1179 }
1180
1181 void WriteDRegisterBits(unsigned code,
1182 uint64_t value,
1183 RegLogMode log_mode = LogRegWrites) {
1184 WriteVRegister(code, value, log_mode);
1185 }
1186 VIXL_DEPRECATED("WriteDRegisterBits",
1187 void set_dreg_bits(unsigned code,
1188 uint64_t value,
1189 RegLogMode log_mode = LogRegWrites)) {
1190 WriteDRegisterBits(code, value, log_mode);
1191 }
1192
1193 void WriteQRegister(unsigned code,
1194 qreg_t value,
1195 RegLogMode log_mode = LogRegWrites) {
1196 WriteVRegister(code, value, log_mode);
1197 }
1198 VIXL_DEPRECATED("WriteQRegister",
1199 void set_qreg(unsigned code,
1200 qreg_t value,
1201 RegLogMode log_mode = LogRegWrites)) {
1202 WriteQRegister(code, value, log_mode);
1203 }
1204
1205 template <typename T>
1206 T ReadRegister(Register reg) const {
1207 return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister);
1208 }
1209
1210 template <typename T>
1211 void WriteRegister(Register reg,
1212 T value,
1213 RegLogMode log_mode = LogRegWrites) {
1214 WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister);
1215 }
1216
1217 template <typename T>
1218 T ReadVRegister(VRegister vreg) const {
1219 return ReadVRegister<T>(vreg.GetCode());
1220 }
1221
1222 template <typename T>
1223 void WriteVRegister(VRegister vreg,
1224 T value,
1225 RegLogMode log_mode = LogRegWrites) {
1226 WriteVRegister<T>(vreg.GetCode(), value, log_mode);
1227 }
1228
1229 template <typename T>
1230 T ReadCPURegister(CPURegister reg) const {
1231 if (reg.IsVRegister()) {
1232 return ReadVRegister<T>(VRegister(reg));
1233 } else {
1234 return ReadRegister<T>(Register(reg));
1235 }
1236 }
1237
1238 template <typename T>
1239 void WriteCPURegister(CPURegister reg,
1240 T value,
1241 RegLogMode log_mode = LogRegWrites) {
1242 if (reg.IsVRegister()) {
1243 WriteVRegister<T>(VRegister(reg), value, log_mode);
1244 } else {
1245 WriteRegister<T>(Register(reg), value, log_mode);
1246 }
1247 }
1248
1249 uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
1250
1251 template <typename T>
1252 T ReadGenericOperand(GenericOperand operand) const {
1253 if (operand.IsCPURegister()) {
1254 return ReadCPURegister<T>(operand.GetCPURegister());
1255 } else {
1256 VIXL_ASSERT(operand.IsMemOperand());
1257 return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
1258 }
1259 }
1260
1261 template <typename T>
1262 void WriteGenericOperand(GenericOperand operand,
1263 T value,
1264 RegLogMode log_mode = LogRegWrites) {
1265 if (operand.IsCPURegister()) {
1266 WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode);
1267 } else {
1268 VIXL_ASSERT(operand.IsMemOperand());
1269 Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value);
1270 }
1271 }
1272
1273 bool ReadN() const { return nzcv_.GetN() != 0; }
1274 VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); }
1275
1276 bool ReadZ() const { return nzcv_.GetZ() != 0; }
1277 VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); }
1278
1279 bool ReadC() const { return nzcv_.GetC() != 0; }
1280 VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); }
1281
1282 bool ReadV() const { return nzcv_.GetV() != 0; }
1283 VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); }
1284
1285 SimSystemRegister& ReadNzcv() { return nzcv_; }
1286 VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); }
1287
1288 // TODO: Find a way to make the fpcr_ members return the proper types, so
1289 // these accessors are not necessary.
1290 FPRounding ReadRMode() const {
1291 return static_cast<FPRounding>(fpcr_.GetRMode());
1292 }
1293 VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); }
1294
1295 UseDefaultNaN ReadDN() const {
1296 return fpcr_.GetDN() != 0 ? kUseDefaultNaN : kIgnoreDefaultNaN;
1297 }
1298
1299 VIXL_DEPRECATED("ReadDN", bool DN()) {
1300 return ReadDN() == kUseDefaultNaN ? true : false;
1301 }
1302
1303 SimSystemRegister& ReadFpcr() { return fpcr_; }
1304 VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); }
1305
1306 // Specify relevant register formats for Print(V)Register and related helpers.
1307 enum PrintRegisterFormat {
1308 // The lane size.
1309 kPrintRegLaneSizeB = 0 << 0,
1310 kPrintRegLaneSizeH = 1 << 0,
1311 kPrintRegLaneSizeS = 2 << 0,
1312 kPrintRegLaneSizeW = kPrintRegLaneSizeS,
1313 kPrintRegLaneSizeD = 3 << 0,
1314 kPrintRegLaneSizeX = kPrintRegLaneSizeD,
1315 kPrintRegLaneSizeQ = 4 << 0,
1316
1317 kPrintRegLaneSizeOffset = 0,
1318 kPrintRegLaneSizeMask = 7 << 0,
1319
1320 // The lane count.
1321 kPrintRegAsScalar = 0,
1322 kPrintRegAsDVector = 1 << 3,
1323 kPrintRegAsQVector = 2 << 3,
1324
1325 kPrintRegAsVectorMask = 3 << 3,
1326
1327 // Indicate floating-point format lanes. (This flag is only supported for
1328 // S-, H-, and D-sized lanes.)
1329 kPrintRegAsFP = 1 << 5,
1330
1331 // Supported combinations.
1332
1333 kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
1334 kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
1335 kPrintHReg = kPrintRegLaneSizeH | kPrintRegAsScalar | kPrintRegAsFP,
1336 kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1337 kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1338
1339 kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
1340 kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
1341 kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
1342 kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
1343 kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
1344 kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
1345 kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
1346 kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
1347 kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
1348 kPrintReg1HFP = kPrintRegLaneSizeH | kPrintRegAsScalar | kPrintRegAsFP,
1349 kPrintReg4HFP = kPrintRegLaneSizeH | kPrintRegAsDVector | kPrintRegAsFP,
1350 kPrintReg8HFP = kPrintRegLaneSizeH | kPrintRegAsQVector | kPrintRegAsFP,
1351 kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1352 kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
1353 kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
1354 kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
1355 kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
1356 kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1357 kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
1358 kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
1359 };
1360
1361 unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
1362 return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
1363 }
1364
1365 unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
1366 return 1 << GetPrintRegLaneSizeInBytesLog2(format);
1367 }
1368
1369 unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
1370 if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2;
1371 if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2;
1372
1373 // Scalar types.
1374 return GetPrintRegLaneSizeInBytesLog2(format);
1375 }
1376
1377 unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
1378 return 1 << GetPrintRegSizeInBytesLog2(format);
1379 }
1380
1381 unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
1382 unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
1383 unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
1384 VIXL_ASSERT(reg_size_log2 >= lane_size_log2);
1385 return 1 << (reg_size_log2 - lane_size_log2);
1386 }
1387
1388 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size,
1389 unsigned lane_size);
1390
1391 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) {
1392 return GetPrintRegisterFormatForSize(size, size);
1393 }
1394
1395 PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) {
1396 switch (size) {
1397 default:
1398 VIXL_UNREACHABLE();
1399 return kPrintDReg;
1400 case kDRegSizeInBytes:
1401 return kPrintDReg;
1402 case kSRegSizeInBytes:
1403 return kPrintSReg;
1404 case kHRegSizeInBytes:
1405 return kPrintHReg;
1406 }
1407 }
1408
1409 PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
1410 if ((GetPrintRegLaneSizeInBytes(format) == kHRegSizeInBytes) ||
1411 (GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) ||
1412 (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) {
1413 return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
1414 }
1415 return format;
1416 }
1417
1418 template <typename T>
1419 PrintRegisterFormat GetPrintRegisterFormat(T value) {
1420 return GetPrintRegisterFormatForSize(sizeof(value));
1421 }
1422
1423 PrintRegisterFormat GetPrintRegisterFormat(double value) {
1424 VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes);
1425 return GetPrintRegisterFormatForSizeFP(sizeof(value));
1426 }
1427
1428 PrintRegisterFormat GetPrintRegisterFormat(float value) {
1429 VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes);
1430 return GetPrintRegisterFormatForSizeFP(sizeof(value));
1431 }
1432
1433 PrintRegisterFormat GetPrintRegisterFormat(Float16 value) {
1434 VIXL_STATIC_ASSERT(sizeof(Float16ToRawbits(value)) == kHRegSizeInBytes);
1435 return GetPrintRegisterFormatForSizeFP(sizeof(Float16ToRawbits(value)));
1436 }
1437
1438 PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
1439 PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
1440
1441 // Print all registers of the specified types.
1442 void PrintRegisters();
1443 void PrintVRegisters();
1444 void PrintSystemRegisters();
1445
1446 // As above, but only print the registers that have been updated.
1447 void PrintWrittenRegisters();
1448 void PrintWrittenVRegisters();
1449
1450 // As above, but respect LOG_REG and LOG_VREG.
1451 void LogWrittenRegisters() {
1452 if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters();
1453 }
1454 void LogWrittenVRegisters() {
1455 if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters();
1456 }
1457 void LogAllWrittenRegisters() {
1458 LogWrittenRegisters();
1459 LogWrittenVRegisters();
1460 }
1461
1462 // Print individual register values (after update).
1463 void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
1464 void PrintVRegister(unsigned code, PrintRegisterFormat format);
1465 void PrintSystemRegister(SystemRegister id);
1466 void PrintTakenBranch(const Instruction* target);
1467
1468 // Like Print* (above), but respect GetTraceParameters().
1469 void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
1470 if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode);
1471 }
1472 void LogVRegister(unsigned code, PrintRegisterFormat format) {
1473 if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format);
1474 }
1475 void LogSystemRegister(SystemRegister id) {
1476 if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id);
1477 }
1478 void LogTakenBranch(const Instruction* target) {
1479 if (GetTraceParameters() & LOG_BRANCH) PrintTakenBranch(target);
1480 }
1481
1482 // Print memory accesses.
1483 void PrintRead(uintptr_t address,
1484 unsigned reg_code,
1485 PrintRegisterFormat format);
1486 void PrintWrite(uintptr_t address,
1487 unsigned reg_code,
1488 PrintRegisterFormat format);
1489 void PrintVRead(uintptr_t address,
1490 unsigned reg_code,
1491 PrintRegisterFormat format,
1492 unsigned lane);
1493 void PrintVWrite(uintptr_t address,
1494 unsigned reg_code,
1495 PrintRegisterFormat format,
1496 unsigned lane);
1497
1498 // Like Print* (above), but respect GetTraceParameters().
1499 void LogRead(uintptr_t address,
1500 unsigned reg_code,
1501 PrintRegisterFormat format) {
1502 if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format);
1503 }
1504 void LogWrite(uintptr_t address,
1505 unsigned reg_code,
1506 PrintRegisterFormat format) {
1507 if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
1508 }
1509 void LogVRead(uintptr_t address,
1510 unsigned reg_code,
1511 PrintRegisterFormat format,
1512 unsigned lane = 0) {
1513 if (GetTraceParameters() & LOG_VREGS) {
1514 PrintVRead(address, reg_code, format, lane);
1515 }
1516 }
1517 void LogVWrite(uintptr_t address,
1518 unsigned reg_code,
1519 PrintRegisterFormat format,
1520 unsigned lane = 0) {
1521 if (GetTraceParameters() & LOG_WRITE) {
1522 PrintVWrite(address, reg_code, format, lane);
1523 }
1524 }
1525
1526 // Helper functions for register tracing.
1527 void PrintRegisterRawHelper(unsigned code,
1528 Reg31Mode r31mode,
1529 int size_in_bytes = kXRegSizeInBytes);
1530 void PrintVRegisterRawHelper(unsigned code,
1531 int bytes = kQRegSizeInBytes,
1532 int lsb = 0);
1533 void PrintVRegisterFPHelper(unsigned code,
1534 unsigned lane_size_in_bytes,
1535 int lane_count = 1,
1536 int rightmost_lane = 0);
1537
1538 VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
1539 void DoTrace(const Instruction* instr);
1540 void DoLog(const Instruction* instr);
1541
1542 static const char* WRegNameForCode(unsigned code,
1543 Reg31Mode mode = Reg31IsZeroRegister);
1544 static const char* XRegNameForCode(unsigned code,
1545 Reg31Mode mode = Reg31IsZeroRegister);
1546 static const char* HRegNameForCode(unsigned code);
1547 static const char* SRegNameForCode(unsigned code);
1548 static const char* DRegNameForCode(unsigned code);
1549 static const char* VRegNameForCode(unsigned code);
1550
1551 bool IsColouredTrace() const { return coloured_trace_; }
1552 VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) {
1553 return IsColouredTrace();
1554 }
1555
1556 void SetColouredTrace(bool value);
1557 VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) {
1558 SetColouredTrace(value);
1559 }
1560
1561 // Values for traces parameters defined in simulator-constants-aarch64.h in
1562 // enum TraceParameters.
1563 int GetTraceParameters() const { return trace_parameters_; }
1564 VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) {
1565 return GetTraceParameters();
1566 }
1567
1568 void SetTraceParameters(int parameters);
1569 VIXL_DEPRECATED("SetTraceParameters",
1570 void set_trace_parameters(int parameters)) {
1571 SetTraceParameters(parameters);
1572 }
1573
1574 void SetInstructionStats(bool value);
1575 VIXL_DEPRECATED("SetInstructionStats",
1576 void set_instruction_stats(bool value)) {
1577 SetInstructionStats(value);
1578 }
1579
1580 // Clear the simulated local monitor to force the next store-exclusive
1581 // instruction to fail.
1582 void ClearLocalMonitor() { local_monitor_.Clear(); }
1583
1584 void SilenceExclusiveAccessWarning() {
1585 print_exclusive_access_warning_ = false;
1586 }
1587
1588 enum PointerType { kDataPointer, kInstructionPointer };
1589
1590 struct PACKey {
1591 uint64_t high;
1592 uint64_t low;
1593 int number;
1594 };
1595
1596 // Current implementation is that all pointers are tagged.
1597 bool HasTBI(uint64_t ptr, PointerType type) {
1598 USE(ptr, type);
1599 return true;
1600 }
1601
1602 // Current implementation uses 48-bit virtual addresses.
1603 int GetBottomPACBit(uint64_t ptr, int ttbr) {
1604 USE(ptr, ttbr);
1605 VIXL_ASSERT((ttbr == 0) || (ttbr == 1));
1606 return 48;
1607 }
1608
1609 // The top PAC bit is 55 for the purposes of relative bit fields with TBI,
1610 // however bit 55 is the TTBR bit regardless of TBI so isn't part of the PAC
1611 // codes in pointers.
1612 int GetTopPACBit(uint64_t ptr, PointerType type) {
1613 return HasTBI(ptr, type) ? 55 : 63;
1614 }
1615
1616 // Armv8.3 Pointer authentication helpers.
1617 uint64_t CalculatePACMask(uint64_t ptr, PointerType type, int ext_bit);
1618 uint64_t ComputePAC(uint64_t data, uint64_t context, PACKey key);
1619 uint64_t AuthPAC(uint64_t ptr,
1620 uint64_t context,
1621 PACKey key,
1622 PointerType type);
1623 uint64_t AddPAC(uint64_t ptr, uint64_t context, PACKey key, PointerType type);
1624 uint64_t StripPAC(uint64_t ptr, PointerType type);
1625
1626 // The common CPUFeatures interface with the set of available features.
1627
1628 CPUFeatures* GetCPUFeatures() {
1629 return cpu_features_auditor_.GetCPUFeatures();
1630 }
1631
1632 void SetCPUFeatures(const CPUFeatures& cpu_features) {
1633 cpu_features_auditor_.SetCPUFeatures(cpu_features);
1634 }
1635
1636 // The set of features that the simulator has encountered.
1637 const CPUFeatures& GetSeenFeatures() {
1638 return cpu_features_auditor_.GetSeenFeatures();
1639 }
1640 void ResetSeenFeatures() { cpu_features_auditor_.ResetSeenFeatures(); }
1641
1642 // Runtime call emulation support.
1643 // It requires VIXL's ABI features, and C++11 or greater.
1644 // Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
1645 // in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
1646 #if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
1647 (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
1648
1649 #define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
1650
1651 // The implementation of the runtime call helpers require the functionality
1652 // provided by `std::index_sequence`. It is only available from C++14, but
1653 // we want runtime call simulation to work from C++11, so we emulate if
1654 // necessary.
1655 #if __cplusplus >= 201402L
1656 template <std::size_t... I>
1657 using local_index_sequence = std::index_sequence<I...>;
1658 template <typename... P>
1659 using __local_index_sequence_for = std::index_sequence_for<P...>;
1660 #else
1661 // Emulate the behaviour of `std::index_sequence` and
1662 // `std::index_sequence_for`.
1663 // Naming follow the `std` names, prefixed with `emulated_`.
1664 template <size_t... I>
1665 struct emulated_index_sequence {};
1666
1667 // A recursive template to create a sequence of indexes.
1668 // The base case (for `N == 0`) is declared outside of the class scope, as
1669 // required by C++.
1670 template <std::size_t N, size_t... I>
1671 struct emulated_make_index_sequence_helper
1672 : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
1673
1674 template <std::size_t N>
1675 struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
1676 };
1677
1678 template <typename... P>
1679 struct emulated_index_sequence_for
1680 : emulated_make_index_sequence<sizeof...(P)> {};
1681
1682 template <std::size_t... I>
1683 using local_index_sequence = emulated_index_sequence<I...>;
1684 template <typename... P>
1685 using __local_index_sequence_for = emulated_index_sequence_for<P...>;
1686 #endif
1687
1688 // Expand the argument tuple and perform the call.
1689 template <typename R, typename... P, std::size_t... I>
1690 R DoRuntimeCall(R (*function)(P...),
1691 std::tuple<P...> arguments,
1692 local_index_sequence<I...>) {
1693 return function(std::get<I>(arguments)...);
1694 }
1695
1696 template <typename R, typename... P>
1697 void RuntimeCallNonVoid(R (*function)(P...)) {
1698 ABI abi;
1699 std::tuple<P...> argument_operands{
1700 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1701 R return_value = DoRuntimeCall(function,
1702 argument_operands,
1703 __local_index_sequence_for<P...>{});
1704 WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
1705 }
1706
1707 template <typename R, typename... P>
1708 void RuntimeCallVoid(R (*function)(P...)) {
1709 ABI abi;
1710 std::tuple<P...> argument_operands{
1711 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1712 DoRuntimeCall(function,
1713 argument_operands,
1714 __local_index_sequence_for<P...>{});
1715 }
1716
1717 // We use `struct` for `void` return type specialisation.
1718 template <typename R, typename... P>
1719 struct RuntimeCallStructHelper {
1720 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1721 R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
1722 simulator->RuntimeCallNonVoid(function);
1723 }
1724 };
1725
1726 // Partial specialization when the return type is `void`.
1727 template <typename... P>
1728 struct RuntimeCallStructHelper<void, P...> {
1729 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1730 void (*function)(P...) =
1731 reinterpret_cast<void (*)(P...)>(function_pointer);
1732 simulator->RuntimeCallVoid(function);
1733 }
1734 };
1735 #endif
1736
1737 protected:
1738 const char* clr_normal;
1739 const char* clr_flag_name;
1740 const char* clr_flag_value;
1741 const char* clr_reg_name;
1742 const char* clr_reg_value;
1743 const char* clr_vreg_name;
1744 const char* clr_vreg_value;
1745 const char* clr_memory_address;
1746 const char* clr_warning;
1747 const char* clr_warning_message;
1748 const char* clr_printf;
1749 const char* clr_branch_marker;
1750
1751 // Simulation helpers ------------------------------------
1752 bool ConditionPassed(Condition cond) {
1753 switch (cond) {
1754 case eq:
1755 return ReadZ();
1756 case ne:
1757 return !ReadZ();
1758 case hs:
1759 return ReadC();
1760 case lo:
1761 return !ReadC();
1762 case mi:
1763 return ReadN();
1764 case pl:
1765 return !ReadN();
1766 case vs:
1767 return ReadV();
1768 case vc:
1769 return !ReadV();
1770 case hi:
1771 return ReadC() && !ReadZ();
1772 case ls:
1773 return !(ReadC() && !ReadZ());
1774 case ge:
1775 return ReadN() == ReadV();
1776 case lt:
1777 return ReadN() != ReadV();
1778 case gt:
1779 return !ReadZ() && (ReadN() == ReadV());
1780 case le:
1781 return !(!ReadZ() && (ReadN() == ReadV()));
1782 case nv:
1783 VIXL_FALLTHROUGH();
1784 case al:
1785 return true;
1786 default:
1787 VIXL_UNREACHABLE();
1788 return false;
1789 }
1790 }
1791
1792 bool ConditionPassed(Instr cond) {
1793 return ConditionPassed(static_cast<Condition>(cond));
1794 }
1795
1796 bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1797
1798 void AddSubHelper(const Instruction* instr, int64_t op2);
1799 uint64_t AddWithCarry(unsigned reg_size,
1800 bool set_flags,
1801 uint64_t left,
1802 uint64_t right,
1803 int carry_in = 0);
1804 void LogicalHelper(const Instruction* instr, int64_t op2);
1805 void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
1806 void LoadStoreHelper(const Instruction* instr,
1807 int64_t offset,
1808 AddrMode addrmode);
1809 void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
1810 template <typename T>
1811 void CompareAndSwapHelper(const Instruction* instr);
1812 template <typename T>
1813 void CompareAndSwapPairHelper(const Instruction* instr);
1814 template <typename T>
1815 void AtomicMemorySimpleHelper(const Instruction* instr);
1816 template <typename T>
1817 void AtomicMemorySwapHelper(const Instruction* instr);
1818 template <typename T>
1819 void LoadAcquireRCpcHelper(const Instruction* instr);
1820 uintptr_t AddressModeHelper(unsigned addr_reg,
1821 int64_t offset,
1822 AddrMode addrmode);
1823 void NEONLoadStoreMultiStructHelper(const Instruction* instr,
1824 AddrMode addr_mode);
1825 void NEONLoadStoreSingleStructHelper(const Instruction* instr,
1826 AddrMode addr_mode);
1827
1828 uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; }
1829
1830 template <typename T>
1831 T* AddressUntag(T* address) {
1832 uintptr_t address_raw = reinterpret_cast<uintptr_t>(address);
1833 return reinterpret_cast<T*>(AddressUntag(address_raw));
1834 }
1835
1836 int64_t ShiftOperand(unsigned reg_size,
1837 int64_t value,
1838 Shift shift_type,
1839 unsigned amount) const;
1840 int64_t ExtendValue(unsigned reg_width,
1841 int64_t value,
1842 Extend extend_type,
1843 unsigned left_shift = 0) const;
1844 uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const;
1845
1846 void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1847 void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
1848 void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1849 void ld2(VectorFormat vform,
1850 LogicVRegister dst1,
1851 LogicVRegister dst2,
1852 uint64_t addr);
1853 void ld2(VectorFormat vform,
1854 LogicVRegister dst1,
1855 LogicVRegister dst2,
1856 int index,
1857 uint64_t addr);
1858 void ld2r(VectorFormat vform,
1859 LogicVRegister dst1,
1860 LogicVRegister dst2,
1861 uint64_t addr);
1862 void ld3(VectorFormat vform,
1863 LogicVRegister dst1,
1864 LogicVRegister dst2,
1865 LogicVRegister dst3,
1866 uint64_t addr);
1867 void ld3(VectorFormat vform,
1868 LogicVRegister dst1,
1869 LogicVRegister dst2,
1870 LogicVRegister dst3,
1871 int index,
1872 uint64_t addr);
1873 void ld3r(VectorFormat vform,
1874 LogicVRegister dst1,
1875 LogicVRegister dst2,
1876 LogicVRegister dst3,
1877 uint64_t addr);
1878 void ld4(VectorFormat vform,
1879 LogicVRegister dst1,
1880 LogicVRegister dst2,
1881 LogicVRegister dst3,
1882 LogicVRegister dst4,
1883 uint64_t addr);
1884 void ld4(VectorFormat vform,
1885 LogicVRegister dst1,
1886 LogicVRegister dst2,
1887 LogicVRegister dst3,
1888 LogicVRegister dst4,
1889 int index,
1890 uint64_t addr);
1891 void ld4r(VectorFormat vform,
1892 LogicVRegister dst1,
1893 LogicVRegister dst2,
1894 LogicVRegister dst3,
1895 LogicVRegister dst4,
1896 uint64_t addr);
1897 void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
1898 void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
1899 void st2(VectorFormat vform,
1900 LogicVRegister src,
1901 LogicVRegister src2,
1902 uint64_t addr);
1903 void st2(VectorFormat vform,
1904 LogicVRegister src,
1905 LogicVRegister src2,
1906 int index,
1907 uint64_t addr);
1908 void st3(VectorFormat vform,
1909 LogicVRegister src,
1910 LogicVRegister src2,
1911 LogicVRegister src3,
1912 uint64_t addr);
1913 void st3(VectorFormat vform,
1914 LogicVRegister src,
1915 LogicVRegister src2,
1916 LogicVRegister src3,
1917 int index,
1918 uint64_t addr);
1919 void st4(VectorFormat vform,
1920 LogicVRegister src,
1921 LogicVRegister src2,
1922 LogicVRegister src3,
1923 LogicVRegister src4,
1924 uint64_t addr);
1925 void st4(VectorFormat vform,
1926 LogicVRegister src,
1927 LogicVRegister src2,
1928 LogicVRegister src3,
1929 LogicVRegister src4,
1930 int index,
1931 uint64_t addr);
1932 LogicVRegister cmp(VectorFormat vform,
1933 LogicVRegister dst,
1934 const LogicVRegister& src1,
1935 const LogicVRegister& src2,
1936 Condition cond);
1937 LogicVRegister cmp(VectorFormat vform,
1938 LogicVRegister dst,
1939 const LogicVRegister& src1,
1940 int imm,
1941 Condition cond);
1942 LogicVRegister cmptst(VectorFormat vform,
1943 LogicVRegister dst,
1944 const LogicVRegister& src1,
1945 const LogicVRegister& src2);
1946 LogicVRegister add(VectorFormat vform,
1947 LogicVRegister dst,
1948 const LogicVRegister& src1,
1949 const LogicVRegister& src2);
1950 LogicVRegister addp(VectorFormat vform,
1951 LogicVRegister dst,
1952 const LogicVRegister& src1,
1953 const LogicVRegister& src2);
1954 LogicVRegister mla(VectorFormat vform,
1955 LogicVRegister dst,
1956 const LogicVRegister& src1,
1957 const LogicVRegister& src2);
1958 LogicVRegister mls(VectorFormat vform,
1959 LogicVRegister dst,
1960 const LogicVRegister& src1,
1961 const LogicVRegister& src2);
1962 LogicVRegister mul(VectorFormat vform,
1963 LogicVRegister dst,
1964 const LogicVRegister& src1,
1965 const LogicVRegister& src2);
1966 LogicVRegister mul(VectorFormat vform,
1967 LogicVRegister dst,
1968 const LogicVRegister& src1,
1969 const LogicVRegister& src2,
1970 int index);
1971 LogicVRegister mla(VectorFormat vform,
1972 LogicVRegister dst,
1973 const LogicVRegister& src1,
1974 const LogicVRegister& src2,
1975 int index);
1976 LogicVRegister mls(VectorFormat vform,
1977 LogicVRegister dst,
1978 const LogicVRegister& src1,
1979 const LogicVRegister& src2,
1980 int index);
1981 LogicVRegister pmul(VectorFormat vform,
1982 LogicVRegister dst,
1983 const LogicVRegister& src1,
1984 const LogicVRegister& src2);
1985
1986 typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
1987 LogicVRegister dst,
1988 const LogicVRegister& src1,
1989 const LogicVRegister& src2,
1990 int index);
1991 LogicVRegister fmul(VectorFormat vform,
1992 LogicVRegister dst,
1993 const LogicVRegister& src1,
1994 const LogicVRegister& src2,
1995 int index);
1996 LogicVRegister fmla(VectorFormat vform,
1997 LogicVRegister dst,
1998 const LogicVRegister& src1,
1999 const LogicVRegister& src2,
2000 int index);
2001 LogicVRegister fmls(VectorFormat vform,
2002 LogicVRegister dst,
2003 const LogicVRegister& src1,
2004 const LogicVRegister& src2,
2005 int index);
2006 LogicVRegister fmulx(VectorFormat vform,
2007 LogicVRegister dst,
2008 const LogicVRegister& src1,
2009 const LogicVRegister& src2,
2010 int index);
2011 LogicVRegister smull(VectorFormat vform,
2012 LogicVRegister dst,
2013 const LogicVRegister& src1,
2014 const LogicVRegister& src2,
2015 int index);
2016 LogicVRegister smull2(VectorFormat vform,
2017 LogicVRegister dst,
2018 const LogicVRegister& src1,
2019 const LogicVRegister& src2,
2020 int index);
2021 LogicVRegister umull(VectorFormat vform,
2022 LogicVRegister dst,
2023 const LogicVRegister& src1,
2024 const LogicVRegister& src2,
2025 int index);
2026 LogicVRegister umull2(VectorFormat vform,
2027 LogicVRegister dst,
2028 const LogicVRegister& src1,
2029 const LogicVRegister& src2,
2030 int index);
2031 LogicVRegister smlal(VectorFormat vform,
2032 LogicVRegister dst,
2033 const LogicVRegister& src1,
2034 const LogicVRegister& src2,
2035 int index);
2036 LogicVRegister smlal2(VectorFormat vform,
2037 LogicVRegister dst,
2038 const LogicVRegister& src1,
2039 const LogicVRegister& src2,
2040 int index);
2041 LogicVRegister umlal(VectorFormat vform,
2042 LogicVRegister dst,
2043 const LogicVRegister& src1,
2044 const LogicVRegister& src2,
2045 int index);
2046 LogicVRegister umlal2(VectorFormat vform,
2047 LogicVRegister dst,
2048 const LogicVRegister& src1,
2049 const LogicVRegister& src2,
2050 int index);
2051 LogicVRegister smlsl(VectorFormat vform,
2052 LogicVRegister dst,
2053 const LogicVRegister& src1,
2054 const LogicVRegister& src2,
2055 int index);
2056 LogicVRegister smlsl2(VectorFormat vform,
2057 LogicVRegister dst,
2058 const LogicVRegister& src1,
2059 const LogicVRegister& src2,
2060 int index);
2061 LogicVRegister umlsl(VectorFormat vform,
2062 LogicVRegister dst,
2063 const LogicVRegister& src1,
2064 const LogicVRegister& src2,
2065 int index);
2066 LogicVRegister umlsl2(VectorFormat vform,
2067 LogicVRegister dst,
2068 const LogicVRegister& src1,
2069 const LogicVRegister& src2,
2070 int index);
2071 LogicVRegister sqdmull(VectorFormat vform,
2072 LogicVRegister dst,
2073 const LogicVRegister& src1,
2074 const LogicVRegister& src2,
2075 int index);
2076 LogicVRegister sqdmull2(VectorFormat vform,
2077 LogicVRegister dst,
2078 const LogicVRegister& src1,
2079 const LogicVRegister& src2,
2080 int index);
2081 LogicVRegister sqdmlal(VectorFormat vform,
2082 LogicVRegister dst,
2083 const LogicVRegister& src1,
2084 const LogicVRegister& src2,
2085 int index);
2086 LogicVRegister sqdmlal2(VectorFormat vform,
2087 LogicVRegister dst,
2088 const LogicVRegister& src1,
2089 const LogicVRegister& src2,
2090 int index);
2091 LogicVRegister sqdmlsl(VectorFormat vform,
2092 LogicVRegister dst,
2093 const LogicVRegister& src1,
2094 const LogicVRegister& src2,
2095 int index);
2096 LogicVRegister sqdmlsl2(VectorFormat vform,
2097 LogicVRegister dst,
2098 const LogicVRegister& src1,
2099 const LogicVRegister& src2,
2100 int index);
2101 LogicVRegister sqdmulh(VectorFormat vform,
2102 LogicVRegister dst,
2103 const LogicVRegister& src1,
2104 const LogicVRegister& src2,
2105 int index);
2106 LogicVRegister sqrdmulh(VectorFormat vform,
2107 LogicVRegister dst,
2108 const LogicVRegister& src1,
2109 const LogicVRegister& src2,
2110 int index);
2111 LogicVRegister sdot(VectorFormat vform,
2112 LogicVRegister dst,
2113 const LogicVRegister& src1,
2114 const LogicVRegister& src2,
2115 int index);
2116 LogicVRegister sqrdmlah(VectorFormat vform,
2117 LogicVRegister dst,
2118 const LogicVRegister& src1,
2119 const LogicVRegister& src2,
2120 int index);
2121 LogicVRegister udot(VectorFormat vform,
2122 LogicVRegister dst,
2123 const LogicVRegister& src1,
2124 const LogicVRegister& src2,
2125 int index);
2126 LogicVRegister sqrdmlsh(VectorFormat vform,
2127 LogicVRegister dst,
2128 const LogicVRegister& src1,
2129 const LogicVRegister& src2,
2130 int index);
2131 LogicVRegister sub(VectorFormat vform,
2132 LogicVRegister dst,
2133 const LogicVRegister& src1,
2134 const LogicVRegister& src2);
2135 LogicVRegister and_(VectorFormat vform,
2136 LogicVRegister dst,
2137 const LogicVRegister& src1,
2138 const LogicVRegister& src2);
2139 LogicVRegister orr(VectorFormat vform,
2140 LogicVRegister dst,
2141 const LogicVRegister& src1,
2142 const LogicVRegister& src2);
2143 LogicVRegister orn(VectorFormat vform,
2144 LogicVRegister dst,
2145 const LogicVRegister& src1,
2146 const LogicVRegister& src2);
2147 LogicVRegister eor(VectorFormat vform,
2148 LogicVRegister dst,
2149 const LogicVRegister& src1,
2150 const LogicVRegister& src2);
2151 LogicVRegister bic(VectorFormat vform,
2152 LogicVRegister dst,
2153 const LogicVRegister& src1,
2154 const LogicVRegister& src2);
2155 LogicVRegister bic(VectorFormat vform,
2156 LogicVRegister dst,
2157 const LogicVRegister& src,
2158 uint64_t imm);
2159 LogicVRegister bif(VectorFormat vform,
2160 LogicVRegister dst,
2161 const LogicVRegister& src1,
2162 const LogicVRegister& src2);
2163 LogicVRegister bit(VectorFormat vform,
2164 LogicVRegister dst,
2165 const LogicVRegister& src1,
2166 const LogicVRegister& src2);
2167 LogicVRegister bsl(VectorFormat vform,
2168 LogicVRegister dst,
2169 const LogicVRegister& src1,
2170 const LogicVRegister& src2);
2171 LogicVRegister cls(VectorFormat vform,
2172 LogicVRegister dst,
2173 const LogicVRegister& src);
2174 LogicVRegister clz(VectorFormat vform,
2175 LogicVRegister dst,
2176 const LogicVRegister& src);
2177 LogicVRegister cnt(VectorFormat vform,
2178 LogicVRegister dst,
2179 const LogicVRegister& src);
2180 LogicVRegister not_(VectorFormat vform,
2181 LogicVRegister dst,
2182 const LogicVRegister& src);
2183 LogicVRegister rbit(VectorFormat vform,
2184 LogicVRegister dst,
2185 const LogicVRegister& src);
2186 LogicVRegister rev(VectorFormat vform,
2187 LogicVRegister dst,
2188 const LogicVRegister& src,
2189 int revSize);
2190 LogicVRegister rev16(VectorFormat vform,
2191 LogicVRegister dst,
2192 const LogicVRegister& src);
2193 LogicVRegister rev32(VectorFormat vform,
2194 LogicVRegister dst,
2195 const LogicVRegister& src);
2196 LogicVRegister rev64(VectorFormat vform,
2197 LogicVRegister dst,
2198 const LogicVRegister& src);
2199 LogicVRegister addlp(VectorFormat vform,
2200 LogicVRegister dst,
2201 const LogicVRegister& src,
2202 bool is_signed,
2203 bool do_accumulate);
2204 LogicVRegister saddlp(VectorFormat vform,
2205 LogicVRegister dst,
2206 const LogicVRegister& src);
2207 LogicVRegister uaddlp(VectorFormat vform,
2208 LogicVRegister dst,
2209 const LogicVRegister& src);
2210 LogicVRegister sadalp(VectorFormat vform,
2211 LogicVRegister dst,
2212 const LogicVRegister& src);
2213 LogicVRegister uadalp(VectorFormat vform,
2214 LogicVRegister dst,
2215 const LogicVRegister& src);
2216 LogicVRegister ext(VectorFormat vform,
2217 LogicVRegister dst,
2218 const LogicVRegister& src1,
2219 const LogicVRegister& src2,
2220 int index);
2221 template <typename T>
2222 LogicVRegister fcadd(VectorFormat vform,
2223 LogicVRegister dst,
2224 const LogicVRegister& src1,
2225 const LogicVRegister& src2,
2226 int rot);
2227 LogicVRegister fcadd(VectorFormat vform,
2228 LogicVRegister dst,
2229 const LogicVRegister& src1,
2230 const LogicVRegister& src2,
2231 int rot);
2232 template <typename T>
2233 LogicVRegister fcmla(VectorFormat vform,
2234 LogicVRegister dst,
2235 const LogicVRegister& src1,
2236 const LogicVRegister& src2,
2237 int index,
2238 int rot);
2239 LogicVRegister fcmla(VectorFormat vform,
2240 LogicVRegister dst,
2241 const LogicVRegister& src1,
2242 const LogicVRegister& src2,
2243 int index,
2244 int rot);
2245 template <typename T>
2246 LogicVRegister fcmla(VectorFormat vform,
2247 LogicVRegister dst,
2248 const LogicVRegister& src1,
2249 const LogicVRegister& src2,
2250 int rot);
2251 LogicVRegister fcmla(VectorFormat vform,
2252 LogicVRegister dst,
2253 const LogicVRegister& src1,
2254 const LogicVRegister& src2,
2255 int rot);
2256 LogicVRegister ins_element(VectorFormat vform,
2257 LogicVRegister dst,
2258 int dst_index,
2259 const LogicVRegister& src,
2260 int src_index);
2261 LogicVRegister ins_immediate(VectorFormat vform,
2262 LogicVRegister dst,
2263 int dst_index,
2264 uint64_t imm);
2265 LogicVRegister dup_element(VectorFormat vform,
2266 LogicVRegister dst,
2267 const LogicVRegister& src,
2268 int src_index);
2269 LogicVRegister dup_immediate(VectorFormat vform,
2270 LogicVRegister dst,
2271 uint64_t imm);
2272 LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2273 LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2274 LogicVRegister orr(VectorFormat vform,
2275 LogicVRegister dst,
2276 const LogicVRegister& src,
2277 uint64_t imm);
2278 LogicVRegister sshl(VectorFormat vform,
2279 LogicVRegister dst,
2280 const LogicVRegister& src1,
2281 const LogicVRegister& src2);
2282 LogicVRegister ushl(VectorFormat vform,
2283 LogicVRegister dst,
2284 const LogicVRegister& src1,
2285 const LogicVRegister& src2);
2286 LogicVRegister sminmax(VectorFormat vform,
2287 LogicVRegister dst,
2288 const LogicVRegister& src1,
2289 const LogicVRegister& src2,
2290 bool max);
2291 LogicVRegister smax(VectorFormat vform,
2292 LogicVRegister dst,
2293 const LogicVRegister& src1,
2294 const LogicVRegister& src2);
2295 LogicVRegister smin(VectorFormat vform,
2296 LogicVRegister dst,
2297 const LogicVRegister& src1,
2298 const LogicVRegister& src2);
2299 LogicVRegister sminmaxp(VectorFormat vform,
2300 LogicVRegister dst,
2301 const LogicVRegister& src1,
2302 const LogicVRegister& src2,
2303 bool max);
2304 LogicVRegister smaxp(VectorFormat vform,
2305 LogicVRegister dst,
2306 const LogicVRegister& src1,
2307 const LogicVRegister& src2);
2308 LogicVRegister sminp(VectorFormat vform,
2309 LogicVRegister dst,
2310 const LogicVRegister& src1,
2311 const LogicVRegister& src2);
2312 LogicVRegister addp(VectorFormat vform,
2313 LogicVRegister dst,
2314 const LogicVRegister& src);
2315 LogicVRegister addv(VectorFormat vform,
2316 LogicVRegister dst,
2317 const LogicVRegister& src);
2318 LogicVRegister uaddlv(VectorFormat vform,
2319 LogicVRegister dst,
2320 const LogicVRegister& src);
2321 LogicVRegister saddlv(VectorFormat vform,
2322 LogicVRegister dst,
2323 const LogicVRegister& src);
2324 LogicVRegister sminmaxv(VectorFormat vform,
2325 LogicVRegister dst,
2326 const LogicVRegister& src,
2327 bool max);
2328 LogicVRegister smaxv(VectorFormat vform,
2329 LogicVRegister dst,
2330 const LogicVRegister& src);
2331 LogicVRegister sminv(VectorFormat vform,
2332 LogicVRegister dst,
2333 const LogicVRegister& src);
2334 LogicVRegister uxtl(VectorFormat vform,
2335 LogicVRegister dst,
2336 const LogicVRegister& src);
2337 LogicVRegister uxtl2(VectorFormat vform,
2338 LogicVRegister dst,
2339 const LogicVRegister& src);
2340 LogicVRegister sxtl(VectorFormat vform,
2341 LogicVRegister dst,
2342 const LogicVRegister& src);
2343 LogicVRegister sxtl2(VectorFormat vform,
2344 LogicVRegister dst,
2345 const LogicVRegister& src);
2346 LogicVRegister tbl(VectorFormat vform,
2347 LogicVRegister dst,
2348 const LogicVRegister& tab,
2349 const LogicVRegister& ind);
2350 LogicVRegister tbl(VectorFormat vform,
2351 LogicVRegister dst,
2352 const LogicVRegister& tab,
2353 const LogicVRegister& tab2,
2354 const LogicVRegister& ind);
2355 LogicVRegister tbl(VectorFormat vform,
2356 LogicVRegister dst,
2357 const LogicVRegister& tab,
2358 const LogicVRegister& tab2,
2359 const LogicVRegister& tab3,
2360 const LogicVRegister& ind);
2361 LogicVRegister tbl(VectorFormat vform,
2362 LogicVRegister dst,
2363 const LogicVRegister& tab,
2364 const LogicVRegister& tab2,
2365 const LogicVRegister& tab3,
2366 const LogicVRegister& tab4,
2367 const LogicVRegister& ind);
2368 LogicVRegister Table(VectorFormat vform,
2369 LogicVRegister dst,
2370 const LogicVRegister& ind,
2371 bool zero_out_of_bounds,
2372 const LogicVRegister* tab1,
2373 const LogicVRegister* tab2 = NULL,
2374 const LogicVRegister* tab3 = NULL,
2375 const LogicVRegister* tab4 = NULL);
2376 LogicVRegister tbx(VectorFormat vform,
2377 LogicVRegister dst,
2378 const LogicVRegister& tab,
2379 const LogicVRegister& ind);
2380 LogicVRegister tbx(VectorFormat vform,
2381 LogicVRegister dst,
2382 const LogicVRegister& tab,
2383 const LogicVRegister& tab2,
2384 const LogicVRegister& ind);
2385 LogicVRegister tbx(VectorFormat vform,
2386 LogicVRegister dst,
2387 const LogicVRegister& tab,
2388 const LogicVRegister& tab2,
2389 const LogicVRegister& tab3,
2390 const LogicVRegister& ind);
2391 LogicVRegister tbx(VectorFormat vform,
2392 LogicVRegister dst,
2393 const LogicVRegister& tab,
2394 const LogicVRegister& tab2,
2395 const LogicVRegister& tab3,
2396 const LogicVRegister& tab4,
2397 const LogicVRegister& ind);
2398 LogicVRegister uaddl(VectorFormat vform,
2399 LogicVRegister dst,
2400 const LogicVRegister& src1,
2401 const LogicVRegister& src2);
2402 LogicVRegister uaddl2(VectorFormat vform,
2403 LogicVRegister dst,
2404 const LogicVRegister& src1,
2405 const LogicVRegister& src2);
2406 LogicVRegister uaddw(VectorFormat vform,
2407 LogicVRegister dst,
2408 const LogicVRegister& src1,
2409 const LogicVRegister& src2);
2410 LogicVRegister uaddw2(VectorFormat vform,
2411 LogicVRegister dst,
2412 const LogicVRegister& src1,
2413 const LogicVRegister& src2);
2414 LogicVRegister saddl(VectorFormat vform,
2415 LogicVRegister dst,
2416 const LogicVRegister& src1,
2417 const LogicVRegister& src2);
2418 LogicVRegister saddl2(VectorFormat vform,
2419 LogicVRegister dst,
2420 const LogicVRegister& src1,
2421 const LogicVRegister& src2);
2422 LogicVRegister saddw(VectorFormat vform,
2423 LogicVRegister dst,
2424 const LogicVRegister& src1,
2425 const LogicVRegister& src2);
2426 LogicVRegister saddw2(VectorFormat vform,
2427 LogicVRegister dst,
2428 const LogicVRegister& src1,
2429 const LogicVRegister& src2);
2430 LogicVRegister usubl(VectorFormat vform,
2431 LogicVRegister dst,
2432 const LogicVRegister& src1,
2433 const LogicVRegister& src2);
2434 LogicVRegister usubl2(VectorFormat vform,
2435 LogicVRegister dst,
2436 const LogicVRegister& src1,
2437 const LogicVRegister& src2);
2438 LogicVRegister usubw(VectorFormat vform,
2439 LogicVRegister dst,
2440 const LogicVRegister& src1,
2441 const LogicVRegister& src2);
2442 LogicVRegister usubw2(VectorFormat vform,
2443 LogicVRegister dst,
2444 const LogicVRegister& src1,
2445 const LogicVRegister& src2);
2446 LogicVRegister ssubl(VectorFormat vform,
2447 LogicVRegister dst,
2448 const LogicVRegister& src1,
2449 const LogicVRegister& src2);
2450 LogicVRegister ssubl2(VectorFormat vform,
2451 LogicVRegister dst,
2452 const LogicVRegister& src1,
2453 const LogicVRegister& src2);
2454 LogicVRegister ssubw(VectorFormat vform,
2455 LogicVRegister dst,
2456 const LogicVRegister& src1,
2457 const LogicVRegister& src2);
2458 LogicVRegister ssubw2(VectorFormat vform,
2459 LogicVRegister dst,
2460 const LogicVRegister& src1,
2461 const LogicVRegister& src2);
2462 LogicVRegister uminmax(VectorFormat vform,
2463 LogicVRegister dst,
2464 const LogicVRegister& src1,
2465 const LogicVRegister& src2,
2466 bool max);
2467 LogicVRegister umax(VectorFormat vform,
2468 LogicVRegister dst,
2469 const LogicVRegister& src1,
2470 const LogicVRegister& src2);
2471 LogicVRegister umin(VectorFormat vform,
2472 LogicVRegister dst,
2473 const LogicVRegister& src1,
2474 const LogicVRegister& src2);
2475 LogicVRegister uminmaxp(VectorFormat vform,
2476 LogicVRegister dst,
2477 const LogicVRegister& src1,
2478 const LogicVRegister& src2,
2479 bool max);
2480 LogicVRegister umaxp(VectorFormat vform,
2481 LogicVRegister dst,
2482 const LogicVRegister& src1,
2483 const LogicVRegister& src2);
2484 LogicVRegister uminp(VectorFormat vform,
2485 LogicVRegister dst,
2486 const LogicVRegister& src1,
2487 const LogicVRegister& src2);
2488 LogicVRegister uminmaxv(VectorFormat vform,
2489 LogicVRegister dst,
2490 const LogicVRegister& src,
2491 bool max);
2492 LogicVRegister umaxv(VectorFormat vform,
2493 LogicVRegister dst,
2494 const LogicVRegister& src);
2495 LogicVRegister uminv(VectorFormat vform,
2496 LogicVRegister dst,
2497 const LogicVRegister& src);
2498 LogicVRegister trn1(VectorFormat vform,
2499 LogicVRegister dst,
2500 const LogicVRegister& src1,
2501 const LogicVRegister& src2);
2502 LogicVRegister trn2(VectorFormat vform,
2503 LogicVRegister dst,
2504 const LogicVRegister& src1,
2505 const LogicVRegister& src2);
2506 LogicVRegister zip1(VectorFormat vform,
2507 LogicVRegister dst,
2508 const LogicVRegister& src1,
2509 const LogicVRegister& src2);
2510 LogicVRegister zip2(VectorFormat vform,
2511 LogicVRegister dst,
2512 const LogicVRegister& src1,
2513 const LogicVRegister& src2);
2514 LogicVRegister uzp1(VectorFormat vform,
2515 LogicVRegister dst,
2516 const LogicVRegister& src1,
2517 const LogicVRegister& src2);
2518 LogicVRegister uzp2(VectorFormat vform,
2519 LogicVRegister dst,
2520 const LogicVRegister& src1,
2521 const LogicVRegister& src2);
2522 LogicVRegister shl(VectorFormat vform,
2523 LogicVRegister dst,
2524 const LogicVRegister& src,
2525 int shift);
2526 LogicVRegister scvtf(VectorFormat vform,
2527 LogicVRegister dst,
2528 const LogicVRegister& src,
2529 int fbits,
2530 FPRounding rounding_mode);
2531 LogicVRegister ucvtf(VectorFormat vform,
2532 LogicVRegister dst,
2533 const LogicVRegister& src,
2534 int fbits,
2535 FPRounding rounding_mode);
2536 LogicVRegister sshll(VectorFormat vform,
2537 LogicVRegister dst,
2538 const LogicVRegister& src,
2539 int shift);
2540 LogicVRegister sshll2(VectorFormat vform,
2541 LogicVRegister dst,
2542 const LogicVRegister& src,
2543 int shift);
2544 LogicVRegister shll(VectorFormat vform,
2545 LogicVRegister dst,
2546 const LogicVRegister& src);
2547 LogicVRegister shll2(VectorFormat vform,
2548 LogicVRegister dst,
2549 const LogicVRegister& src);
2550 LogicVRegister ushll(VectorFormat vform,
2551 LogicVRegister dst,
2552 const LogicVRegister& src,
2553 int shift);
2554 LogicVRegister ushll2(VectorFormat vform,
2555 LogicVRegister dst,
2556 const LogicVRegister& src,
2557 int shift);
2558 LogicVRegister sli(VectorFormat vform,
2559 LogicVRegister dst,
2560 const LogicVRegister& src,
2561 int shift);
2562 LogicVRegister sri(VectorFormat vform,
2563 LogicVRegister dst,
2564 const LogicVRegister& src,
2565 int shift);
2566 LogicVRegister sshr(VectorFormat vform,
2567 LogicVRegister dst,
2568 const LogicVRegister& src,
2569 int shift);
2570 LogicVRegister ushr(VectorFormat vform,
2571 LogicVRegister dst,
2572 const LogicVRegister& src,
2573 int shift);
2574 LogicVRegister ssra(VectorFormat vform,
2575 LogicVRegister dst,
2576 const LogicVRegister& src,
2577 int shift);
2578 LogicVRegister usra(VectorFormat vform,
2579 LogicVRegister dst,
2580 const LogicVRegister& src,
2581 int shift);
2582 LogicVRegister srsra(VectorFormat vform,
2583 LogicVRegister dst,
2584 const LogicVRegister& src,
2585 int shift);
2586 LogicVRegister ursra(VectorFormat vform,
2587 LogicVRegister dst,
2588 const LogicVRegister& src,
2589 int shift);
2590 LogicVRegister suqadd(VectorFormat vform,
2591 LogicVRegister dst,
2592 const LogicVRegister& src);
2593 LogicVRegister usqadd(VectorFormat vform,
2594 LogicVRegister dst,
2595 const LogicVRegister& src);
2596 LogicVRegister sqshl(VectorFormat vform,
2597 LogicVRegister dst,
2598 const LogicVRegister& src,
2599 int shift);
2600 LogicVRegister uqshl(VectorFormat vform,
2601 LogicVRegister dst,
2602 const LogicVRegister& src,
2603 int shift);
2604 LogicVRegister sqshlu(VectorFormat vform,
2605 LogicVRegister dst,
2606 const LogicVRegister& src,
2607 int shift);
2608 LogicVRegister abs(VectorFormat vform,
2609 LogicVRegister dst,
2610 const LogicVRegister& src);
2611 LogicVRegister neg(VectorFormat vform,
2612 LogicVRegister dst,
2613 const LogicVRegister& src);
2614 LogicVRegister extractnarrow(VectorFormat vform,
2615 LogicVRegister dst,
2616 bool dstIsSigned,
2617 const LogicVRegister& src,
2618 bool srcIsSigned);
2619 LogicVRegister xtn(VectorFormat vform,
2620 LogicVRegister dst,
2621 const LogicVRegister& src);
2622 LogicVRegister sqxtn(VectorFormat vform,
2623 LogicVRegister dst,
2624 const LogicVRegister& src);
2625 LogicVRegister uqxtn(VectorFormat vform,
2626 LogicVRegister dst,
2627 const LogicVRegister& src);
2628 LogicVRegister sqxtun(VectorFormat vform,
2629 LogicVRegister dst,
2630 const LogicVRegister& src);
2631 LogicVRegister absdiff(VectorFormat vform,
2632 LogicVRegister dst,
2633 const LogicVRegister& src1,
2634 const LogicVRegister& src2,
2635 bool issigned);
2636 LogicVRegister saba(VectorFormat vform,
2637 LogicVRegister dst,
2638 const LogicVRegister& src1,
2639 const LogicVRegister& src2);
2640 LogicVRegister uaba(VectorFormat vform,
2641 LogicVRegister dst,
2642 const LogicVRegister& src1,
2643 const LogicVRegister& src2);
2644 LogicVRegister shrn(VectorFormat vform,
2645 LogicVRegister dst,
2646 const LogicVRegister& src,
2647 int shift);
2648 LogicVRegister shrn2(VectorFormat vform,
2649 LogicVRegister dst,
2650 const LogicVRegister& src,
2651 int shift);
2652 LogicVRegister rshrn(VectorFormat vform,
2653 LogicVRegister dst,
2654 const LogicVRegister& src,
2655 int shift);
2656 LogicVRegister rshrn2(VectorFormat vform,
2657 LogicVRegister dst,
2658 const LogicVRegister& src,
2659 int shift);
2660 LogicVRegister uqshrn(VectorFormat vform,
2661 LogicVRegister dst,
2662 const LogicVRegister& src,
2663 int shift);
2664 LogicVRegister uqshrn2(VectorFormat vform,
2665 LogicVRegister dst,
2666 const LogicVRegister& src,
2667 int shift);
2668 LogicVRegister uqrshrn(VectorFormat vform,
2669 LogicVRegister dst,
2670 const LogicVRegister& src,
2671 int shift);
2672 LogicVRegister uqrshrn2(VectorFormat vform,
2673 LogicVRegister dst,
2674 const LogicVRegister& src,
2675 int shift);
2676 LogicVRegister sqshrn(VectorFormat vform,
2677 LogicVRegister dst,
2678 const LogicVRegister& src,
2679 int shift);
2680 LogicVRegister sqshrn2(VectorFormat vform,
2681 LogicVRegister dst,
2682 const LogicVRegister& src,
2683 int shift);
2684 LogicVRegister sqrshrn(VectorFormat vform,
2685 LogicVRegister dst,
2686 const LogicVRegister& src,
2687 int shift);
2688 LogicVRegister sqrshrn2(VectorFormat vform,
2689 LogicVRegister dst,
2690 const LogicVRegister& src,
2691 int shift);
2692 LogicVRegister sqshrun(VectorFormat vform,
2693 LogicVRegister dst,
2694 const LogicVRegister& src,
2695 int shift);
2696 LogicVRegister sqshrun2(VectorFormat vform,
2697 LogicVRegister dst,
2698 const LogicVRegister& src,
2699 int shift);
2700 LogicVRegister sqrshrun(VectorFormat vform,
2701 LogicVRegister dst,
2702 const LogicVRegister& src,
2703 int shift);
2704 LogicVRegister sqrshrun2(VectorFormat vform,
2705 LogicVRegister dst,
2706 const LogicVRegister& src,
2707 int shift);
2708 LogicVRegister sqrdmulh(VectorFormat vform,
2709 LogicVRegister dst,
2710 const LogicVRegister& src1,
2711 const LogicVRegister& src2,
2712 bool round = true);
2713 LogicVRegister dot(VectorFormat vform,
2714 LogicVRegister dst,
2715 const LogicVRegister& src1,
2716 const LogicVRegister& src2,
2717 bool is_signed);
2718 LogicVRegister sdot(VectorFormat vform,
2719 LogicVRegister dst,
2720 const LogicVRegister& src1,
2721 const LogicVRegister& src2);
2722 LogicVRegister udot(VectorFormat vform,
2723 LogicVRegister dst,
2724 const LogicVRegister& src1,
2725 const LogicVRegister& src2);
2726 LogicVRegister sqrdmlash(VectorFormat vform,
2727 LogicVRegister dst,
2728 const LogicVRegister& src1,
2729 const LogicVRegister& src2,
2730 bool round = true,
2731 bool sub_op = false);
2732 LogicVRegister sqrdmlah(VectorFormat vform,
2733 LogicVRegister dst,
2734 const LogicVRegister& src1,
2735 const LogicVRegister& src2,
2736 bool round = true);
2737 LogicVRegister sqrdmlsh(VectorFormat vform,
2738 LogicVRegister dst,
2739 const LogicVRegister& src1,
2740 const LogicVRegister& src2,
2741 bool round = true);
2742 LogicVRegister sqdmulh(VectorFormat vform,
2743 LogicVRegister dst,
2744 const LogicVRegister& src1,
2745 const LogicVRegister& src2);
2746 #define NEON_3VREG_LOGIC_LIST(V) \
2747 V(addhn) \
2748 V(addhn2) \
2749 V(raddhn) \
2750 V(raddhn2) \
2751 V(subhn) \
2752 V(subhn2) \
2753 V(rsubhn) \
2754 V(rsubhn2) \
2755 V(pmull) \
2756 V(pmull2) \
2757 V(sabal) \
2758 V(sabal2) \
2759 V(uabal) \
2760 V(uabal2) \
2761 V(sabdl) \
2762 V(sabdl2) \
2763 V(uabdl) \
2764 V(uabdl2) \
2765 V(smull) \
2766 V(smull2) \
2767 V(umull) \
2768 V(umull2) \
2769 V(smlal) \
2770 V(smlal2) \
2771 V(umlal) \
2772 V(umlal2) \
2773 V(smlsl) \
2774 V(smlsl2) \
2775 V(umlsl) \
2776 V(umlsl2) \
2777 V(sqdmlal) \
2778 V(sqdmlal2) \
2779 V(sqdmlsl) \
2780 V(sqdmlsl2) \
2781 V(sqdmull) \
2782 V(sqdmull2)
2783
2784 #define DEFINE_LOGIC_FUNC(FXN) \
2785 LogicVRegister FXN(VectorFormat vform, \
2786 LogicVRegister dst, \
2787 const LogicVRegister& src1, \
2788 const LogicVRegister& src2);
2789 NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
2790 #undef DEFINE_LOGIC_FUNC
2791
2792 #define NEON_FP3SAME_LIST(V) \
2793 V(fadd, FPAdd, false) \
2794 V(fsub, FPSub, true) \
2795 V(fmul, FPMul, true) \
2796 V(fmulx, FPMulx, true) \
2797 V(fdiv, FPDiv, true) \
2798 V(fmax, FPMax, false) \
2799 V(fmin, FPMin, false) \
2800 V(fmaxnm, FPMaxNM, false) \
2801 V(fminnm, FPMinNM, false)
2802
2803 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
2804 template <typename T> \
2805 LogicVRegister FN(VectorFormat vform, \
2806 LogicVRegister dst, \
2807 const LogicVRegister& src1, \
2808 const LogicVRegister& src2); \
2809 LogicVRegister FN(VectorFormat vform, \
2810 LogicVRegister dst, \
2811 const LogicVRegister& src1, \
2812 const LogicVRegister& src2);
2813 NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
2814 #undef DECLARE_NEON_FP_VECTOR_OP
2815
2816 #define NEON_FPPAIRWISE_LIST(V) \
2817 V(faddp, fadd, FPAdd) \
2818 V(fmaxp, fmax, FPMax) \
2819 V(fmaxnmp, fmaxnm, FPMaxNM) \
2820 V(fminp, fmin, FPMin) \
2821 V(fminnmp, fminnm, FPMinNM)
2822
2823 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP) \
2824 LogicVRegister FNP(VectorFormat vform, \
2825 LogicVRegister dst, \
2826 const LogicVRegister& src1, \
2827 const LogicVRegister& src2); \
2828 LogicVRegister FNP(VectorFormat vform, \
2829 LogicVRegister dst, \
2830 const LogicVRegister& src);
2831 NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
2832 #undef DECLARE_NEON_FP_PAIR_OP
2833
2834 template <typename T>
2835 LogicVRegister frecps(VectorFormat vform,
2836 LogicVRegister dst,
2837 const LogicVRegister& src1,
2838 const LogicVRegister& src2);
2839 LogicVRegister frecps(VectorFormat vform,
2840 LogicVRegister dst,
2841 const LogicVRegister& src1,
2842 const LogicVRegister& src2);
2843 template <typename T>
2844 LogicVRegister frsqrts(VectorFormat vform,
2845 LogicVRegister dst,
2846 const LogicVRegister& src1,
2847 const LogicVRegister& src2);
2848 LogicVRegister frsqrts(VectorFormat vform,
2849 LogicVRegister dst,
2850 const LogicVRegister& src1,
2851 const LogicVRegister& src2);
2852 template <typename T>
2853 LogicVRegister fmla(VectorFormat vform,
2854 LogicVRegister dst,
2855 const LogicVRegister& src1,
2856 const LogicVRegister& src2);
2857 LogicVRegister fmla(VectorFormat vform,
2858 LogicVRegister dst,
2859 const LogicVRegister& src1,
2860 const LogicVRegister& src2);
2861 template <typename T>
2862 LogicVRegister fmls(VectorFormat vform,
2863 LogicVRegister dst,
2864 const LogicVRegister& src1,
2865 const LogicVRegister& src2);
2866 LogicVRegister fmls(VectorFormat vform,
2867 LogicVRegister dst,
2868 const LogicVRegister& src1,
2869 const LogicVRegister& src2);
2870 LogicVRegister fnmul(VectorFormat vform,
2871 LogicVRegister dst,
2872 const LogicVRegister& src1,
2873 const LogicVRegister& src2);
2874
2875 template <typename T>
2876 LogicVRegister fcmp(VectorFormat vform,
2877 LogicVRegister dst,
2878 const LogicVRegister& src1,
2879 const LogicVRegister& src2,
2880 Condition cond);
2881 LogicVRegister fcmp(VectorFormat vform,
2882 LogicVRegister dst,
2883 const LogicVRegister& src1,
2884 const LogicVRegister& src2,
2885 Condition cond);
2886 LogicVRegister fabscmp(VectorFormat vform,
2887 LogicVRegister dst,
2888 const LogicVRegister& src1,
2889 const LogicVRegister& src2,
2890 Condition cond);
2891 LogicVRegister fcmp_zero(VectorFormat vform,
2892 LogicVRegister dst,
2893 const LogicVRegister& src,
2894 Condition cond);
2895
2896 template <typename T>
2897 LogicVRegister fneg(VectorFormat vform,
2898 LogicVRegister dst,
2899 const LogicVRegister& src);
2900 LogicVRegister fneg(VectorFormat vform,
2901 LogicVRegister dst,
2902 const LogicVRegister& src);
2903 template <typename T>
2904 LogicVRegister frecpx(VectorFormat vform,
2905 LogicVRegister dst,
2906 const LogicVRegister& src);
2907 LogicVRegister frecpx(VectorFormat vform,
2908 LogicVRegister dst,
2909 const LogicVRegister& src);
2910 template <typename T>
2911 LogicVRegister fabs_(VectorFormat vform,
2912 LogicVRegister dst,
2913 const LogicVRegister& src);
2914 LogicVRegister fabs_(VectorFormat vform,
2915 LogicVRegister dst,
2916 const LogicVRegister& src);
2917 LogicVRegister fabd(VectorFormat vform,
2918 LogicVRegister dst,
2919 const LogicVRegister& src1,
2920 const LogicVRegister& src2);
2921 LogicVRegister frint(VectorFormat vform,
2922 LogicVRegister dst,
2923 const LogicVRegister& src,
2924 FPRounding rounding_mode,
2925 bool inexact_exception = false);
2926 LogicVRegister fcvts(VectorFormat vform,
2927 LogicVRegister dst,
2928 const LogicVRegister& src,
2929 FPRounding rounding_mode,
2930 int fbits = 0);
2931 LogicVRegister fcvtu(VectorFormat vform,
2932 LogicVRegister dst,
2933 const LogicVRegister& src,
2934 FPRounding rounding_mode,
2935 int fbits = 0);
2936 LogicVRegister fcvtl(VectorFormat vform,
2937 LogicVRegister dst,
2938 const LogicVRegister& src);
2939 LogicVRegister fcvtl2(VectorFormat vform,
2940 LogicVRegister dst,
2941 const LogicVRegister& src);
2942 LogicVRegister fcvtn(VectorFormat vform,
2943 LogicVRegister dst,
2944 const LogicVRegister& src);
2945 LogicVRegister fcvtn2(VectorFormat vform,
2946 LogicVRegister dst,
2947 const LogicVRegister& src);
2948 LogicVRegister fcvtxn(VectorFormat vform,
2949 LogicVRegister dst,
2950 const LogicVRegister& src);
2951 LogicVRegister fcvtxn2(VectorFormat vform,
2952 LogicVRegister dst,
2953 const LogicVRegister& src);
2954 LogicVRegister fsqrt(VectorFormat vform,
2955 LogicVRegister dst,
2956 const LogicVRegister& src);
2957 LogicVRegister frsqrte(VectorFormat vform,
2958 LogicVRegister dst,
2959 const LogicVRegister& src);
2960 LogicVRegister frecpe(VectorFormat vform,
2961 LogicVRegister dst,
2962 const LogicVRegister& src,
2963 FPRounding rounding);
2964 LogicVRegister ursqrte(VectorFormat vform,
2965 LogicVRegister dst,
2966 const LogicVRegister& src);
2967 LogicVRegister urecpe(VectorFormat vform,
2968 LogicVRegister dst,
2969 const LogicVRegister& src);
2970
2971 template <typename T>
2972 struct TFPMinMaxOp {
2973 typedef T (Simulator::*type)(T a, T b);
2974 };
2975
2976 template <typename T>
2977 LogicVRegister fminmaxv(VectorFormat vform,
2978 LogicVRegister dst,
2979 const LogicVRegister& src,
2980 typename TFPMinMaxOp<T>::type Op);
2981
2982 LogicVRegister fminv(VectorFormat vform,
2983 LogicVRegister dst,
2984 const LogicVRegister& src);
2985 LogicVRegister fmaxv(VectorFormat vform,
2986 LogicVRegister dst,
2987 const LogicVRegister& src);
2988 LogicVRegister fminnmv(VectorFormat vform,
2989 LogicVRegister dst,
2990 const LogicVRegister& src);
2991 LogicVRegister fmaxnmv(VectorFormat vform,
2992 LogicVRegister dst,
2993 const LogicVRegister& src);
2994
2995 static const uint32_t CRC32_POLY = 0x04C11DB7;
2996 static const uint32_t CRC32C_POLY = 0x1EDC6F41;
2997 uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
2998 template <typename T>
2999 uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
3000 uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
3001
3002 void SysOp_W(int op, int64_t val);
3003
3004 template <typename T>
3005 T FPRecipSqrtEstimate(T op);
3006 template <typename T>
3007 T FPRecipEstimate(T op, FPRounding rounding);
3008 template <typename T, typename R>
3009 R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
3010
3011 void FPCompare(double val0, double val1, FPTrapFlags trap);
3012 double FPRoundInt(double value, FPRounding round_mode);
3013 double recip_sqrt_estimate(double a);
3014 double recip_estimate(double a);
3015 double FPRecipSqrtEstimate(double a);
3016 double FPRecipEstimate(double a);
3017 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
3018 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
3019 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
3020 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
3021 ::vixl::internal::SimFloat16 FixedToFloat16(int64_t src,
3022 int fbits,
3023 FPRounding round_mode);
3024 ::vixl::internal::SimFloat16 UFixedToFloat16(uint64_t src,
3025 int fbits,
3026 FPRounding round_mode);
3027 int16_t FPToInt16(double value, FPRounding rmode);
3028 int32_t FPToInt32(double value, FPRounding rmode);
3029 int64_t FPToInt64(double value, FPRounding rmode);
3030 uint16_t FPToUInt16(double value, FPRounding rmode);
3031 uint32_t FPToUInt32(double value, FPRounding rmode);
3032 uint64_t FPToUInt64(double value, FPRounding rmode);
3033 int32_t FPToFixedJS(double value);
3034
3035 template <typename T>
3036 T FPAdd(T op1, T op2);
3037
3038 template <typename T>
3039 T FPNeg(T op);
3040
3041 template <typename T>
3042 T FPDiv(T op1, T op2);
3043
3044 template <typename T>
3045 T FPMax(T a, T b);
3046
3047 template <typename T>
3048 T FPMaxNM(T a, T b);
3049
3050 template <typename T>
3051 T FPMin(T a, T b);
3052
3053 template <typename T>
3054 T FPMinNM(T a, T b);
3055
3056 template <typename T>
3057 T FPMul(T op1, T op2);
3058
3059 template <typename T>
3060 T FPMulx(T op1, T op2);
3061
3062 template <typename T>
3063 T FPMulAdd(T a, T op1, T op2);
3064
3065 template <typename T>
3066 T FPSqrt(T op);
3067
3068 template <typename T>
3069 T FPSub(T op1, T op2);
3070
3071 template <typename T>
3072 T FPRecipStepFused(T op1, T op2);
3073
3074 template <typename T>
3075 T FPRSqrtStepFused(T op1, T op2);
3076
3077 // This doesn't do anything at the moment. We'll need it if we want support
3078 // for cumulative exception bits or floating-point exceptions.
3079 void FPProcessException() {}
3080
3081 bool FPProcessNaNs(const Instruction* instr);
3082
3083 // Pseudo Printf instruction
3084 void DoPrintf(const Instruction* instr);
3085
3086 // Pseudo-instructions to configure CPU features dynamically.
3087 void DoConfigureCPUFeatures(const Instruction* instr);
3088
3089 void DoSaveCPUFeatures(const Instruction* instr);
3090 void DoRestoreCPUFeatures(const Instruction* instr);
3091
3092 // Simulate a runtime call.
3093 #ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
3094 VIXL_NO_RETURN_IN_DEBUG_MODE
3095 #endif
3096 void DoRuntimeCall(const Instruction* instr);
3097
3098 // Processor state ---------------------------------------
3099
3100 // Simulated monitors for exclusive access instructions.
3101 SimExclusiveLocalMonitor local_monitor_;
3102 SimExclusiveGlobalMonitor global_monitor_;
3103
3104 // Output stream.
3105 FILE* stream_;
3106 PrintDisassembler* print_disasm_;
3107
3108 // Instruction statistics instrumentation.
3109 Instrument* instrumentation_;
3110
3111 // General purpose registers. Register 31 is the stack pointer.
3112 SimRegister registers_[kNumberOfRegisters];
3113
3114 // Vector registers
3115 SimVRegister vregisters_[kNumberOfVRegisters];
3116
3117 // Program Status Register.
3118 // bits[31, 27]: Condition flags N, Z, C, and V.
3119 // (Negative, Zero, Carry, Overflow)
3120 SimSystemRegister nzcv_;
3121
3122 // Floating-Point Control Register
3123 SimSystemRegister fpcr_;
3124
3125 // Only a subset of FPCR features are supported by the simulator. This helper
3126 // checks that the FPCR settings are supported.
3127 //
3128 // This is checked when floating-point instructions are executed, not when
3129 // FPCR is set. This allows generated code to modify FPCR for external
3130 // functions, or to save and restore it when entering and leaving generated
3131 // code.
3132 void AssertSupportedFPCR() {
3133 // No flush-to-zero support.
3134 VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
3135 // Ties-to-even rounding only.
3136 VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
3137
3138 // The simulator does not support half-precision operations so
3139 // GetFpcr().AHP() is irrelevant, and is not checked here.
3140 }
3141
3142 static int CalcNFlag(uint64_t result, unsigned reg_size) {
3143 return (result >> (reg_size - 1)) & 1;
3144 }
3145
3146 static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
3147
3148 static const uint32_t kConditionFlagsMask = 0xf0000000;
3149
3150 // Stack
3151 byte* stack_;
3152 static const int stack_protection_size_ = 256;
3153 // 2 KB stack.
3154 static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
3155 byte* stack_limit_;
3156
3157 Decoder* decoder_;
3158 // Indicates if the pc has been modified by the instruction and should not be
3159 // automatically incremented.
3160 bool pc_modified_;
3161 const Instruction* pc_;
3162
3163 static const char* xreg_names[];
3164 static const char* wreg_names[];
3165 static const char* hreg_names[];
3166 static const char* sreg_names[];
3167 static const char* dreg_names[];
3168 static const char* vreg_names[];
3169
3170 private:
3171 static const PACKey kPACKeyIA;
3172 static const PACKey kPACKeyIB;
3173 static const PACKey kPACKeyDA;
3174 static const PACKey kPACKeyDB;
3175 static const PACKey kPACKeyGA;
3176
3177 template <typename T>
3178 static T FPDefaultNaN();
3179
3180 // Standard NaN processing.
3181 template <typename T>
3182 T FPProcessNaN(T op) {
3183 VIXL_ASSERT(IsNaN(op));
3184 if (IsSignallingNaN(op)) {
3185 FPProcessException();
3186 }
3187 return (ReadDN() == kUseDefaultNaN) ? FPDefaultNaN<T>() : ToQuietNaN(op);
3188 }
3189
3190 template <typename T>
3191 T FPProcessNaNs(T op1, T op2) {
3192 if (IsSignallingNaN(op1)) {
3193 return FPProcessNaN(op1);
3194 } else if (IsSignallingNaN(op2)) {
3195 return FPProcessNaN(op2);
3196 } else if (IsNaN(op1)) {
3197 VIXL_ASSERT(IsQuietNaN(op1));
3198 return FPProcessNaN(op1);
3199 } else if (IsNaN(op2)) {
3200 VIXL_ASSERT(IsQuietNaN(op2));
3201 return FPProcessNaN(op2);
3202 } else {
3203 return 0.0;
3204 }
3205 }
3206
3207 template <typename T>
3208 T FPProcessNaNs3(T op1, T op2, T op3) {
3209 if (IsSignallingNaN(op1)) {
3210 return FPProcessNaN(op1);
3211 } else if (IsSignallingNaN(op2)) {
3212 return FPProcessNaN(op2);
3213 } else if (IsSignallingNaN(op3)) {
3214 return FPProcessNaN(op3);
3215 } else if (IsNaN(op1)) {
3216 VIXL_ASSERT(IsQuietNaN(op1));
3217 return FPProcessNaN(op1);
3218 } else if (IsNaN(op2)) {
3219 VIXL_ASSERT(IsQuietNaN(op2));
3220 return FPProcessNaN(op2);
3221 } else if (IsNaN(op3)) {
3222 VIXL_ASSERT(IsQuietNaN(op3));
3223 return FPProcessNaN(op3);
3224 } else {
3225 return 0.0;
3226 }
3227 }
3228
3229 bool coloured_trace_;
3230
3231 // A set of TraceParameters flags.
3232 int trace_parameters_;
3233
3234 // Indicates whether the instruction instrumentation is active.
3235 bool instruction_stats_;
3236
3237 // Indicates whether the exclusive-access warning has been printed.
3238 bool print_exclusive_access_warning_;
3239 void PrintExclusiveAccessWarning();
3240
3241 CPUFeaturesAuditor cpu_features_auditor_;
3242 std::vector<CPUFeatures> saved_cpu_features_;
3243 };
3244
3245 #if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
3246 // Base case of the recursive template used to emulate C++14
3247 // `std::index_sequence`.
3248 template <size_t... I>
3249 struct Simulator::emulated_make_index_sequence_helper<0, I...>
3250 : Simulator::emulated_index_sequence<I...> {};
3251 #endif
3252
3253 } // namespace aarch64
3254 } // namespace vixl
3255
3256 #endif // VIXL_INCLUDE_SIMULATOR_AARCH64
3257
3258 #endif // VIXL_AARCH64_SIMULATOR_AARCH64_H_
3259