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