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