simulator-aarch64.h revision 482d4df29d1466ff87d94e74034f1a8659f1b354
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_HAS_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(
829        code < kNumberOfRegisters ||
830        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
831    if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
832      T result;
833      memset(&result, 0, sizeof(result));
834      return result;
835    }
836    if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
837      code = 31;
838    }
839    return registers_[code].Get<T>();
840  }
841  template <typename T>
842  VIXL_DEPRECATED("ReadRegister",
843                  T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister)
844                      const) {
845    return ReadRegister<T>(code, r31mode);
846  }
847
848  // Common specialized accessors for the ReadRegister() template.
849  int32_t ReadWRegister(unsigned code,
850                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
851    return ReadRegister<int32_t>(code, r31mode);
852  }
853  VIXL_DEPRECATED("ReadWRegister",
854                  int32_t wreg(unsigned code,
855                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
856    return ReadWRegister(code, r31mode);
857  }
858
859  int64_t ReadXRegister(unsigned code,
860                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
861    return ReadRegister<int64_t>(code, r31mode);
862  }
863  VIXL_DEPRECATED("ReadXRegister",
864                  int64_t xreg(unsigned code,
865                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
866    return ReadXRegister(code, r31mode);
867  }
868
869  // As above, with parameterized size and return type. The value is
870  // either zero-extended or truncated to fit, as required.
871  template <typename T>
872  T ReadRegister(unsigned size,
873                 unsigned code,
874                 Reg31Mode r31mode = Reg31IsZeroRegister) const {
875    uint64_t raw;
876    switch (size) {
877      case kWRegSize:
878        raw = ReadRegister<uint32_t>(code, r31mode);
879        break;
880      case kXRegSize:
881        raw = ReadRegister<uint64_t>(code, r31mode);
882        break;
883      default:
884        VIXL_UNREACHABLE();
885        return 0;
886    }
887
888    T result;
889    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
890    // Copy the result and truncate to fit. This assumes a little-endian host.
891    memcpy(&result, &raw, sizeof(result));
892    return result;
893  }
894  template <typename T>
895  VIXL_DEPRECATED("ReadRegister",
896                  T reg(unsigned size,
897                        unsigned code,
898                        Reg31Mode r31mode = Reg31IsZeroRegister) const) {
899    return ReadRegister<T>(size, code, r31mode);
900  }
901
902  // Use int64_t by default if T is not specified.
903  int64_t ReadRegister(unsigned size,
904                       unsigned code,
905                       Reg31Mode r31mode = Reg31IsZeroRegister) const {
906    return ReadRegister<int64_t>(size, code, r31mode);
907  }
908  VIXL_DEPRECATED("ReadRegister",
909                  int64_t reg(unsigned size,
910                              unsigned code,
911                              Reg31Mode r31mode = Reg31IsZeroRegister) const) {
912    return ReadRegister(size, code, r31mode);
913  }
914
915  enum RegLogMode { LogRegWrites, NoRegLog };
916
917  // Write 'value' into an integer register. The value is zero-extended. This
918  // behaviour matches AArch64 register writes.
919  template <typename T>
920  void WriteRegister(unsigned code,
921                     T value,
922                     RegLogMode log_mode = LogRegWrites,
923                     Reg31Mode r31mode = Reg31IsZeroRegister) {
924    VIXL_STATIC_ASSERT((sizeof(T) == kWRegSizeInBytes) ||
925                       (sizeof(T) == kXRegSizeInBytes));
926    VIXL_ASSERT(
927        code < kNumberOfRegisters ||
928        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
929
930    if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
931      return;
932    }
933
934    if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
935      code = 31;
936    }
937
938    registers_[code].Write(value);
939
940    if (log_mode == LogRegWrites) LogRegister(code, r31mode);
941  }
942  template <typename T>
943  VIXL_DEPRECATED("WriteRegister",
944                  void set_reg(unsigned code,
945                               T value,
946                               RegLogMode log_mode = LogRegWrites,
947                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
948    WriteRegister<T>(code, value, log_mode, r31mode);
949  }
950
951  // Common specialized accessors for the set_reg() template.
952  void WriteWRegister(unsigned code,
953                      int32_t value,
954                      RegLogMode log_mode = LogRegWrites,
955                      Reg31Mode r31mode = Reg31IsZeroRegister) {
956    WriteRegister(code, value, log_mode, r31mode);
957  }
958  VIXL_DEPRECATED("WriteWRegister",
959                  void set_wreg(unsigned code,
960                                int32_t value,
961                                RegLogMode log_mode = LogRegWrites,
962                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
963    WriteWRegister(code, value, log_mode, r31mode);
964  }
965
966  void WriteXRegister(unsigned code,
967                      int64_t value,
968                      RegLogMode log_mode = LogRegWrites,
969                      Reg31Mode r31mode = Reg31IsZeroRegister) {
970    WriteRegister(code, value, log_mode, r31mode);
971  }
972  VIXL_DEPRECATED("WriteXRegister",
973                  void set_xreg(unsigned code,
974                                int64_t value,
975                                RegLogMode log_mode = LogRegWrites,
976                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
977    WriteXRegister(code, value, log_mode, r31mode);
978  }
979
980  // As above, with parameterized size and type. The value is either
981  // zero-extended or truncated to fit, as required.
982  template <typename T>
983  void WriteRegister(unsigned size,
984                     unsigned code,
985                     T value,
986                     RegLogMode log_mode = LogRegWrites,
987                     Reg31Mode r31mode = Reg31IsZeroRegister) {
988    // Zero-extend the input.
989    uint64_t raw = 0;
990    VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw));
991    memcpy(&raw, &value, sizeof(value));
992
993    // Write (and possibly truncate) the value.
994    switch (size) {
995      case kWRegSize:
996        WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode);
997        break;
998      case kXRegSize:
999        WriteRegister(code, raw, log_mode, r31mode);
1000        break;
1001      default:
1002        VIXL_UNREACHABLE();
1003        return;
1004    }
1005  }
1006  template <typename T>
1007  VIXL_DEPRECATED("WriteRegister",
1008                  void set_reg(unsigned size,
1009                               unsigned code,
1010                               T value,
1011                               RegLogMode log_mode = LogRegWrites,
1012                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
1013    WriteRegister(size, code, value, log_mode, r31mode);
1014  }
1015
1016  // Common specialized accessors for the set_reg() template.
1017
1018  // Commonly-used special cases.
1019  template <typename T>
1020  void WriteLr(T value) {
1021    WriteRegister(kLinkRegCode, value);
1022  }
1023  template <typename T>
1024  VIXL_DEPRECATED("WriteLr", void set_lr(T value)) {
1025    WriteLr(value);
1026  }
1027
1028  template <typename T>
1029  void WriteSp(T value) {
1030    WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer);
1031  }
1032  template <typename T>
1033  VIXL_DEPRECATED("WriteSp", void set_sp(T value)) {
1034    WriteSp(value);
1035  }
1036
1037  // Vector register accessors.
1038  // These are equivalent to the integer register accessors, but for vector
1039  // registers.
1040
1041  // A structure for representing a 128-bit Q register.
1042  struct qreg_t {
1043    uint8_t val[kQRegSizeInBytes];
1044  };
1045
1046  // Basic accessor: read the register as the specified type.
1047  template <typename T>
1048  T ReadVRegister(unsigned code) const {
1049    VIXL_STATIC_ASSERT(
1050        (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) ||
1051        (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) ||
1052        (sizeof(T) == kQRegSizeInBytes));
1053    VIXL_ASSERT(code < kNumberOfVRegisters);
1054
1055    return vregisters_[code].Get<T>();
1056  }
1057  template <typename T>
1058  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) {
1059    return ReadVRegister<T>(code);
1060  }
1061
1062  // Common specialized accessors for the vreg() template.
1063  int8_t ReadBRegister(unsigned code) const {
1064    return ReadVRegister<int8_t>(code);
1065  }
1066  VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) {
1067    return ReadBRegister(code);
1068  }
1069
1070  int16_t ReadHRegister(unsigned code) const {
1071    return ReadVRegister<int16_t>(code);
1072  }
1073  VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) {
1074    return ReadHRegister(code);
1075  }
1076
1077  float ReadSRegister(unsigned code) const {
1078    return ReadVRegister<float>(code);
1079  }
1080  VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) {
1081    return ReadSRegister(code);
1082  }
1083
1084  uint32_t ReadSRegisterBits(unsigned code) const {
1085    return ReadVRegister<uint32_t>(code);
1086  }
1087  VIXL_DEPRECATED("ReadSRegisterBits",
1088                  uint32_t sreg_bits(unsigned code) const) {
1089    return ReadSRegisterBits(code);
1090  }
1091
1092  double ReadDRegister(unsigned code) const {
1093    return ReadVRegister<double>(code);
1094  }
1095  VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) {
1096    return ReadDRegister(code);
1097  }
1098
1099  uint64_t ReadDRegisterBits(unsigned code) const {
1100    return ReadVRegister<uint64_t>(code);
1101  }
1102  VIXL_DEPRECATED("ReadDRegisterBits",
1103                  uint64_t dreg_bits(unsigned code) const) {
1104    return ReadDRegisterBits(code);
1105  }
1106
1107  qreg_t ReadQRegister(unsigned code) const {
1108    return ReadVRegister<qreg_t>(code);
1109  }
1110  VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) {
1111    return ReadQRegister(code);
1112  }
1113
1114  // As above, with parameterized size and return type. The value is
1115  // either zero-extended or truncated to fit, as required.
1116  template <typename T>
1117  T ReadVRegister(unsigned size, unsigned code) const {
1118    uint64_t raw = 0;
1119    T result;
1120
1121    switch (size) {
1122      case kSRegSize:
1123        raw = ReadVRegister<uint32_t>(code);
1124        break;
1125      case kDRegSize:
1126        raw = ReadVRegister<uint64_t>(code);
1127        break;
1128      default:
1129        VIXL_UNREACHABLE();
1130        break;
1131    }
1132
1133    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
1134    // Copy the result and truncate to fit. This assumes a little-endian host.
1135    memcpy(&result, &raw, sizeof(result));
1136    return result;
1137  }
1138  template <typename T>
1139  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) {
1140    return ReadVRegister<T>(size, code);
1141  }
1142
1143  SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; }
1144  VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) {
1145    return ReadVRegister(code);
1146  }
1147
1148  // Basic accessor: Write the specified value.
1149  template <typename T>
1150  void WriteVRegister(unsigned code,
1151                      T value,
1152                      RegLogMode log_mode = LogRegWrites) {
1153    VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) ||
1154                       (sizeof(value) == kHRegSizeInBytes) ||
1155                       (sizeof(value) == kSRegSizeInBytes) ||
1156                       (sizeof(value) == kDRegSizeInBytes) ||
1157                       (sizeof(value) == kQRegSizeInBytes));
1158    VIXL_ASSERT(code < kNumberOfVRegisters);
1159    vregisters_[code].Write(value);
1160
1161    if (log_mode == LogRegWrites) {
1162      LogVRegister(code, GetPrintRegisterFormat(value));
1163    }
1164  }
1165  template <typename T>
1166  VIXL_DEPRECATED("WriteVRegister",
1167                  void set_vreg(unsigned code,
1168                                T value,
1169                                RegLogMode log_mode = LogRegWrites)) {
1170    WriteVRegister(code, value, log_mode);
1171  }
1172
1173  // Common specialized accessors for the WriteVRegister() template.
1174  void WriteBRegister(unsigned code,
1175                      int8_t value,
1176                      RegLogMode log_mode = LogRegWrites) {
1177    WriteVRegister(code, value, log_mode);
1178  }
1179  VIXL_DEPRECATED("WriteBRegister",
1180                  void set_breg(unsigned code,
1181                                int8_t value,
1182                                RegLogMode log_mode = LogRegWrites)) {
1183    return WriteBRegister(code, value, log_mode);
1184  }
1185
1186  void WriteHRegister(unsigned code,
1187                      int16_t value,
1188                      RegLogMode log_mode = LogRegWrites) {
1189    WriteVRegister(code, value, log_mode);
1190  }
1191  VIXL_DEPRECATED("WriteHRegister",
1192                  void set_hreg(unsigned code,
1193                                int16_t value,
1194                                RegLogMode log_mode = LogRegWrites)) {
1195    return WriteHRegister(code, value, log_mode);
1196  }
1197
1198  void WriteSRegister(unsigned code,
1199                      float value,
1200                      RegLogMode log_mode = LogRegWrites) {
1201    WriteVRegister(code, value, log_mode);
1202  }
1203  VIXL_DEPRECATED("WriteSRegister",
1204                  void set_sreg(unsigned code,
1205                                float value,
1206                                RegLogMode log_mode = LogRegWrites)) {
1207    WriteSRegister(code, value, log_mode);
1208  }
1209
1210  void WriteSRegisterBits(unsigned code,
1211                          uint32_t value,
1212                          RegLogMode log_mode = LogRegWrites) {
1213    WriteVRegister(code, value, log_mode);
1214  }
1215  VIXL_DEPRECATED("WriteSRegisterBits",
1216                  void set_sreg_bits(unsigned code,
1217                                     uint32_t value,
1218                                     RegLogMode log_mode = LogRegWrites)) {
1219    WriteSRegisterBits(code, value, log_mode);
1220  }
1221
1222  void WriteDRegister(unsigned code,
1223                      double value,
1224                      RegLogMode log_mode = LogRegWrites) {
1225    WriteVRegister(code, value, log_mode);
1226  }
1227  VIXL_DEPRECATED("WriteDRegister",
1228                  void set_dreg(unsigned code,
1229                                double value,
1230                                RegLogMode log_mode = LogRegWrites)) {
1231    WriteDRegister(code, value, log_mode);
1232  }
1233
1234  void WriteDRegisterBits(unsigned code,
1235                          uint64_t value,
1236                          RegLogMode log_mode = LogRegWrites) {
1237    WriteVRegister(code, value, log_mode);
1238  }
1239  VIXL_DEPRECATED("WriteDRegisterBits",
1240                  void set_dreg_bits(unsigned code,
1241                                     uint64_t value,
1242                                     RegLogMode log_mode = LogRegWrites)) {
1243    WriteDRegisterBits(code, value, log_mode);
1244  }
1245
1246  void WriteQRegister(unsigned code,
1247                      qreg_t value,
1248                      RegLogMode log_mode = LogRegWrites) {
1249    WriteVRegister(code, value, log_mode);
1250  }
1251  VIXL_DEPRECATED("WriteQRegister",
1252                  void set_qreg(unsigned code,
1253                                qreg_t value,
1254                                RegLogMode log_mode = LogRegWrites)) {
1255    WriteQRegister(code, value, log_mode);
1256  }
1257
1258  template <typename T>
1259  T ReadRegister(Register reg) const {
1260    return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister);
1261  }
1262
1263  template <typename T>
1264  void WriteRegister(Register reg,
1265                     T value,
1266                     RegLogMode log_mode = LogRegWrites) {
1267    WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister);
1268  }
1269
1270  template <typename T>
1271  T ReadVRegister(VRegister vreg) const {
1272    return ReadVRegister<T>(vreg.GetCode());
1273  }
1274
1275  template <typename T>
1276  void WriteVRegister(VRegister vreg,
1277                      T value,
1278                      RegLogMode log_mode = LogRegWrites) {
1279    WriteVRegister<T>(vreg.GetCode(), value, log_mode);
1280  }
1281
1282  template <typename T>
1283  T ReadCPURegister(CPURegister reg) const {
1284    if (reg.IsVRegister()) {
1285      return ReadVRegister<T>(VRegister(reg));
1286    } else {
1287      return ReadRegister<T>(Register(reg));
1288    }
1289  }
1290
1291  template <typename T>
1292  void WriteCPURegister(CPURegister reg,
1293                        T value,
1294                        RegLogMode log_mode = LogRegWrites) {
1295    if (reg.IsVRegister()) {
1296      WriteVRegister<T>(VRegister(reg), value, log_mode);
1297    } else {
1298      WriteRegister<T>(Register(reg), value, log_mode);
1299    }
1300  }
1301
1302  uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
1303
1304  template <typename T>
1305  T ReadGenericOperand(GenericOperand operand) const {
1306    if (operand.IsCPURegister()) {
1307      return ReadCPURegister<T>(operand.GetCPURegister());
1308    } else {
1309      VIXL_ASSERT(operand.IsMemOperand());
1310      return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
1311    }
1312  }
1313
1314  template <typename T>
1315  void WriteGenericOperand(GenericOperand operand,
1316                           T value,
1317                           RegLogMode log_mode = LogRegWrites) {
1318    if (operand.IsCPURegister()) {
1319      WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode);
1320    } else {
1321      VIXL_ASSERT(operand.IsMemOperand());
1322      Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value);
1323    }
1324  }
1325
1326  bool ReadN() const { return nzcv_.GetN() != 0; }
1327  VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); }
1328
1329  bool ReadZ() const { return nzcv_.GetZ() != 0; }
1330  VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); }
1331
1332  bool ReadC() const { return nzcv_.GetC() != 0; }
1333  VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); }
1334
1335  bool ReadV() const { return nzcv_.GetV() != 0; }
1336  VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); }
1337
1338  SimSystemRegister& ReadNzcv() { return nzcv_; }
1339  VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); }
1340
1341  // TODO: Find a way to make the fpcr_ members return the proper types, so
1342  // these accessors are not necessary.
1343  FPRounding ReadRMode() const {
1344    return static_cast<FPRounding>(fpcr_.GetRMode());
1345  }
1346  VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); }
1347
1348  bool ReadDN() const { return fpcr_.GetDN() != 0; }
1349  VIXL_DEPRECATED("ReadDN", bool DN()) { return ReadDN(); }
1350
1351  SimSystemRegister& ReadFpcr() { return fpcr_; }
1352  VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); }
1353
1354  // Specify relevant register formats for Print(V)Register and related helpers.
1355  enum PrintRegisterFormat {
1356    // The lane size.
1357    kPrintRegLaneSizeB = 0 << 0,
1358    kPrintRegLaneSizeH = 1 << 0,
1359    kPrintRegLaneSizeS = 2 << 0,
1360    kPrintRegLaneSizeW = kPrintRegLaneSizeS,
1361    kPrintRegLaneSizeD = 3 << 0,
1362    kPrintRegLaneSizeX = kPrintRegLaneSizeD,
1363    kPrintRegLaneSizeQ = 4 << 0,
1364
1365    kPrintRegLaneSizeOffset = 0,
1366    kPrintRegLaneSizeMask = 7 << 0,
1367
1368    // The lane count.
1369    kPrintRegAsScalar = 0,
1370    kPrintRegAsDVector = 1 << 3,
1371    kPrintRegAsQVector = 2 << 3,
1372
1373    kPrintRegAsVectorMask = 3 << 3,
1374
1375    // Indicate floating-point format lanes. (This flag is only supported for S-
1376    // and D-sized lanes.)
1377    kPrintRegAsFP = 1 << 5,
1378
1379    // Supported combinations.
1380
1381    kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
1382    kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
1383    kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1384    kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1385
1386    kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
1387    kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
1388    kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
1389    kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
1390    kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
1391    kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
1392    kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
1393    kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
1394    kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
1395    kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1396    kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
1397    kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
1398    kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
1399    kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
1400    kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1401    kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
1402    kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
1403  };
1404
1405  unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
1406    return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
1407  }
1408
1409  unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
1410    return 1 << GetPrintRegLaneSizeInBytesLog2(format);
1411  }
1412
1413  unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
1414    if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2;
1415    if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2;
1416
1417    // Scalar types.
1418    return GetPrintRegLaneSizeInBytesLog2(format);
1419  }
1420
1421  unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
1422    return 1 << GetPrintRegSizeInBytesLog2(format);
1423  }
1424
1425  unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
1426    unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
1427    unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
1428    VIXL_ASSERT(reg_size_log2 >= lane_size_log2);
1429    return 1 << (reg_size_log2 - lane_size_log2);
1430  }
1431
1432  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size,
1433                                                    unsigned lane_size);
1434
1435  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) {
1436    return GetPrintRegisterFormatForSize(size, size);
1437  }
1438
1439  PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) {
1440    switch (size) {
1441      default:
1442        VIXL_UNREACHABLE();
1443        return kPrintDReg;
1444      case kDRegSizeInBytes:
1445        return kPrintDReg;
1446      case kSRegSizeInBytes:
1447        return kPrintSReg;
1448    }
1449  }
1450
1451  PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
1452    if ((GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) ||
1453        (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) {
1454      return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
1455    }
1456    return format;
1457  }
1458
1459  template <typename T>
1460  PrintRegisterFormat GetPrintRegisterFormat(T value) {
1461    return GetPrintRegisterFormatForSize(sizeof(value));
1462  }
1463
1464  PrintRegisterFormat GetPrintRegisterFormat(double value) {
1465    VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes);
1466    return GetPrintRegisterFormatForSizeFP(sizeof(value));
1467  }
1468
1469  PrintRegisterFormat GetPrintRegisterFormat(float value) {
1470    VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes);
1471    return GetPrintRegisterFormatForSizeFP(sizeof(value));
1472  }
1473
1474  PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
1475  PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
1476
1477  // Print all registers of the specified types.
1478  void PrintRegisters();
1479  void PrintVRegisters();
1480  void PrintSystemRegisters();
1481
1482  // As above, but only print the registers that have been updated.
1483  void PrintWrittenRegisters();
1484  void PrintWrittenVRegisters();
1485
1486  // As above, but respect LOG_REG and LOG_VREG.
1487  void LogWrittenRegisters() {
1488    if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters();
1489  }
1490  void LogWrittenVRegisters() {
1491    if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters();
1492  }
1493  void LogAllWrittenRegisters() {
1494    LogWrittenRegisters();
1495    LogWrittenVRegisters();
1496  }
1497
1498  // Print individual register values (after update).
1499  void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
1500  void PrintVRegister(unsigned code, PrintRegisterFormat format);
1501  void PrintSystemRegister(SystemRegister id);
1502
1503  // Like Print* (above), but respect GetTraceParameters().
1504  void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
1505    if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode);
1506  }
1507  void LogVRegister(unsigned code, PrintRegisterFormat format) {
1508    if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format);
1509  }
1510  void LogSystemRegister(SystemRegister id) {
1511    if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id);
1512  }
1513
1514  // Print memory accesses.
1515  void PrintRead(uintptr_t address,
1516                 unsigned reg_code,
1517                 PrintRegisterFormat format);
1518  void PrintWrite(uintptr_t address,
1519                  unsigned reg_code,
1520                  PrintRegisterFormat format);
1521  void PrintVRead(uintptr_t address,
1522                  unsigned reg_code,
1523                  PrintRegisterFormat format,
1524                  unsigned lane);
1525  void PrintVWrite(uintptr_t address,
1526                   unsigned reg_code,
1527                   PrintRegisterFormat format,
1528                   unsigned lane);
1529
1530  // Like Print* (above), but respect GetTraceParameters().
1531  void LogRead(uintptr_t address,
1532               unsigned reg_code,
1533               PrintRegisterFormat format) {
1534    if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format);
1535  }
1536  void LogWrite(uintptr_t address,
1537                unsigned reg_code,
1538                PrintRegisterFormat format) {
1539    if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
1540  }
1541  void LogVRead(uintptr_t address,
1542                unsigned reg_code,
1543                PrintRegisterFormat format,
1544                unsigned lane = 0) {
1545    if (GetTraceParameters() & LOG_VREGS) {
1546      PrintVRead(address, reg_code, format, lane);
1547    }
1548  }
1549  void LogVWrite(uintptr_t address,
1550                 unsigned reg_code,
1551                 PrintRegisterFormat format,
1552                 unsigned lane = 0) {
1553    if (GetTraceParameters() & LOG_WRITE) {
1554      PrintVWrite(address, reg_code, format, lane);
1555    }
1556  }
1557
1558  // Helper functions for register tracing.
1559  void PrintRegisterRawHelper(unsigned code,
1560                              Reg31Mode r31mode,
1561                              int size_in_bytes = kXRegSizeInBytes);
1562  void PrintVRegisterRawHelper(unsigned code,
1563                               int bytes = kQRegSizeInBytes,
1564                               int lsb = 0);
1565  void PrintVRegisterFPHelper(unsigned code,
1566                              unsigned lane_size_in_bytes,
1567                              int lane_count = 1,
1568                              int rightmost_lane = 0);
1569
1570  VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
1571  void DoTrace(const Instruction* instr);
1572  void DoLog(const Instruction* instr);
1573
1574  static const char* WRegNameForCode(unsigned code,
1575                                     Reg31Mode mode = Reg31IsZeroRegister);
1576  static const char* XRegNameForCode(unsigned code,
1577                                     Reg31Mode mode = Reg31IsZeroRegister);
1578  static const char* SRegNameForCode(unsigned code);
1579  static const char* DRegNameForCode(unsigned code);
1580  static const char* VRegNameForCode(unsigned code);
1581
1582  bool IsColouredTrace() const { return coloured_trace_; }
1583  VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) {
1584    return IsColouredTrace();
1585  }
1586
1587  void SetColouredTrace(bool value);
1588  VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) {
1589    SetColouredTrace(value);
1590  }
1591
1592  // Values for traces parameters defined in simulator-constants-aarch64.h in
1593  // enum TraceParameters.
1594  int GetTraceParameters() const { return trace_parameters_; }
1595  VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) {
1596    return GetTraceParameters();
1597  }
1598
1599  void SetTraceParameters(int parameters);
1600  VIXL_DEPRECATED("SetTraceParameters",
1601                  void set_trace_parameters(int parameters)) {
1602    SetTraceParameters(parameters);
1603  }
1604
1605  void SetInstructionStats(bool value);
1606  VIXL_DEPRECATED("SetInstructionStats",
1607                  void set_instruction_stats(bool value)) {
1608    SetInstructionStats(value);
1609  }
1610
1611  // Clear the simulated local monitor to force the next store-exclusive
1612  // instruction to fail.
1613  void ClearLocalMonitor() { local_monitor_.Clear(); }
1614
1615  void SilenceExclusiveAccessWarning() {
1616    print_exclusive_access_warning_ = false;
1617  }
1618
1619// Runtime call emulation support.
1620// It requires VIXL's ABI features, and C++11 or greater.
1621// Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
1622// in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
1623#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
1624    (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
1625
1626#define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
1627
1628// The implementation of the runtime call helpers require the functionality
1629// provided by `std::index_sequence`. It is only available from C++14, but
1630// we want runtime call simulation to work from C++11, so we emulate if
1631// necessary.
1632#if __cplusplus >= 201402L
1633  template <std::size_t... I>
1634  using local_index_sequence = std::index_sequence<I...>;
1635  template <typename... P>
1636  using __local_index_sequence_for = std::index_sequence_for<P...>;
1637#else
1638  // Emulate the behaviour of `std::index_sequence` and
1639  // `std::index_sequence_for`.
1640  // Naming follow the `std` names, prefixed with `emulated_`.
1641  template <size_t... I>
1642  struct emulated_index_sequence {};
1643
1644  // A recursive template to create a sequence of indexes.
1645  // The base case (for `N == 0`) is declared outside of the class scope, as
1646  // required by C++.
1647  template <std::size_t N, size_t... I>
1648  struct emulated_make_index_sequence_helper
1649      : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
1650
1651  template <std::size_t N>
1652  struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
1653  };
1654
1655  template <typename... P>
1656  struct emulated_index_sequence_for
1657      : emulated_make_index_sequence<sizeof...(P)> {};
1658
1659  template <std::size_t... I>
1660  using local_index_sequence = emulated_index_sequence<I...>;
1661  template <typename... P>
1662  using __local_index_sequence_for = emulated_index_sequence_for<P...>;
1663#endif
1664
1665  // Expand the argument tuple and perform the call.
1666  template <typename R, typename... P, std::size_t... I>
1667  R DoRuntimeCall(R (*function)(P...),
1668                  std::tuple<P...> arguments,
1669                  local_index_sequence<I...>) {
1670    return function(std::get<I>(arguments)...);
1671  }
1672
1673  template <typename R, typename... P>
1674  void RuntimeCallNonVoid(R (*function)(P...)) {
1675    ABI abi;
1676    std::tuple<P...> argument_operands{
1677        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1678    R return_value = DoRuntimeCall(function,
1679                                   argument_operands,
1680                                   __local_index_sequence_for<P...>{});
1681    WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
1682  }
1683
1684  template <typename R, typename... P>
1685  void RuntimeCallVoid(R (*function)(P...)) {
1686    ABI abi;
1687    std::tuple<P...> argument_operands{
1688        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1689    DoRuntimeCall(function,
1690                  argument_operands,
1691                  __local_index_sequence_for<P...>{});
1692  }
1693
1694  // We use `struct` for `void` return type specialisation.
1695  template <typename R, typename... P>
1696  struct RuntimeCallStructHelper {
1697    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1698      R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
1699      simulator->RuntimeCallNonVoid(function);
1700    }
1701  };
1702
1703  // Partial specialization when the return type is `void`.
1704  template <typename... P>
1705  struct RuntimeCallStructHelper<void, P...> {
1706    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1707      void (*function)(P...) =
1708          reinterpret_cast<void (*)(P...)>(function_pointer);
1709      simulator->RuntimeCallVoid(function);
1710    }
1711  };
1712#endif
1713
1714 protected:
1715  const char* clr_normal;
1716  const char* clr_flag_name;
1717  const char* clr_flag_value;
1718  const char* clr_reg_name;
1719  const char* clr_reg_value;
1720  const char* clr_vreg_name;
1721  const char* clr_vreg_value;
1722  const char* clr_memory_address;
1723  const char* clr_warning;
1724  const char* clr_warning_message;
1725  const char* clr_printf;
1726
1727  // Simulation helpers ------------------------------------
1728  bool ConditionPassed(Condition cond) {
1729    switch (cond) {
1730      case eq:
1731        return ReadZ();
1732      case ne:
1733        return !ReadZ();
1734      case hs:
1735        return ReadC();
1736      case lo:
1737        return !ReadC();
1738      case mi:
1739        return ReadN();
1740      case pl:
1741        return !ReadN();
1742      case vs:
1743        return ReadV();
1744      case vc:
1745        return !ReadV();
1746      case hi:
1747        return ReadC() && !ReadZ();
1748      case ls:
1749        return !(ReadC() && !ReadZ());
1750      case ge:
1751        return ReadN() == ReadV();
1752      case lt:
1753        return ReadN() != ReadV();
1754      case gt:
1755        return !ReadZ() && (ReadN() == ReadV());
1756      case le:
1757        return !(!ReadZ() && (ReadN() == ReadV()));
1758      case nv:
1759        VIXL_FALLTHROUGH();
1760      case al:
1761        return true;
1762      default:
1763        VIXL_UNREACHABLE();
1764        return false;
1765    }
1766  }
1767
1768  bool ConditionPassed(Instr cond) {
1769    return ConditionPassed(static_cast<Condition>(cond));
1770  }
1771
1772  bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1773
1774  void AddSubHelper(const Instruction* instr, int64_t op2);
1775  uint64_t AddWithCarry(unsigned reg_size,
1776                        bool set_flags,
1777                        uint64_t left,
1778                        uint64_t right,
1779                        int carry_in = 0);
1780  void LogicalHelper(const Instruction* instr, int64_t op2);
1781  void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
1782  void LoadStoreHelper(const Instruction* instr,
1783                       int64_t offset,
1784                       AddrMode addrmode);
1785  void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
1786  uintptr_t AddressModeHelper(unsigned addr_reg,
1787                              int64_t offset,
1788                              AddrMode addrmode);
1789  void NEONLoadStoreMultiStructHelper(const Instruction* instr,
1790                                      AddrMode addr_mode);
1791  void NEONLoadStoreSingleStructHelper(const Instruction* instr,
1792                                       AddrMode addr_mode);
1793
1794  uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; }
1795
1796  template <typename T>
1797  T* AddressUntag(T* address) {
1798    uintptr_t address_raw = reinterpret_cast<uintptr_t>(address);
1799    return reinterpret_cast<T*>(AddressUntag(address_raw));
1800  }
1801
1802  int64_t ShiftOperand(unsigned reg_size,
1803                       int64_t value,
1804                       Shift shift_type,
1805                       unsigned amount) const;
1806  int64_t ExtendValue(unsigned reg_width,
1807                      int64_t value,
1808                      Extend extend_type,
1809                      unsigned left_shift = 0) const;
1810  uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const;
1811
1812  void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1813  void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
1814  void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1815  void ld2(VectorFormat vform,
1816           LogicVRegister dst1,
1817           LogicVRegister dst2,
1818           uint64_t addr);
1819  void ld2(VectorFormat vform,
1820           LogicVRegister dst1,
1821           LogicVRegister dst2,
1822           int index,
1823           uint64_t addr);
1824  void ld2r(VectorFormat vform,
1825            LogicVRegister dst1,
1826            LogicVRegister dst2,
1827            uint64_t addr);
1828  void ld3(VectorFormat vform,
1829           LogicVRegister dst1,
1830           LogicVRegister dst2,
1831           LogicVRegister dst3,
1832           uint64_t addr);
1833  void ld3(VectorFormat vform,
1834           LogicVRegister dst1,
1835           LogicVRegister dst2,
1836           LogicVRegister dst3,
1837           int index,
1838           uint64_t addr);
1839  void ld3r(VectorFormat vform,
1840            LogicVRegister dst1,
1841            LogicVRegister dst2,
1842            LogicVRegister dst3,
1843            uint64_t addr);
1844  void ld4(VectorFormat vform,
1845           LogicVRegister dst1,
1846           LogicVRegister dst2,
1847           LogicVRegister dst3,
1848           LogicVRegister dst4,
1849           uint64_t addr);
1850  void ld4(VectorFormat vform,
1851           LogicVRegister dst1,
1852           LogicVRegister dst2,
1853           LogicVRegister dst3,
1854           LogicVRegister dst4,
1855           int index,
1856           uint64_t addr);
1857  void ld4r(VectorFormat vform,
1858            LogicVRegister dst1,
1859            LogicVRegister dst2,
1860            LogicVRegister dst3,
1861            LogicVRegister dst4,
1862            uint64_t addr);
1863  void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
1864  void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
1865  void st2(VectorFormat vform,
1866           LogicVRegister src,
1867           LogicVRegister src2,
1868           uint64_t addr);
1869  void st2(VectorFormat vform,
1870           LogicVRegister src,
1871           LogicVRegister src2,
1872           int index,
1873           uint64_t addr);
1874  void st3(VectorFormat vform,
1875           LogicVRegister src,
1876           LogicVRegister src2,
1877           LogicVRegister src3,
1878           uint64_t addr);
1879  void st3(VectorFormat vform,
1880           LogicVRegister src,
1881           LogicVRegister src2,
1882           LogicVRegister src3,
1883           int index,
1884           uint64_t addr);
1885  void st4(VectorFormat vform,
1886           LogicVRegister src,
1887           LogicVRegister src2,
1888           LogicVRegister src3,
1889           LogicVRegister src4,
1890           uint64_t addr);
1891  void st4(VectorFormat vform,
1892           LogicVRegister src,
1893           LogicVRegister src2,
1894           LogicVRegister src3,
1895           LogicVRegister src4,
1896           int index,
1897           uint64_t addr);
1898  LogicVRegister cmp(VectorFormat vform,
1899                     LogicVRegister dst,
1900                     const LogicVRegister& src1,
1901                     const LogicVRegister& src2,
1902                     Condition cond);
1903  LogicVRegister cmp(VectorFormat vform,
1904                     LogicVRegister dst,
1905                     const LogicVRegister& src1,
1906                     int imm,
1907                     Condition cond);
1908  LogicVRegister cmptst(VectorFormat vform,
1909                        LogicVRegister dst,
1910                        const LogicVRegister& src1,
1911                        const LogicVRegister& src2);
1912  LogicVRegister add(VectorFormat vform,
1913                     LogicVRegister dst,
1914                     const LogicVRegister& src1,
1915                     const LogicVRegister& src2);
1916  LogicVRegister addp(VectorFormat vform,
1917                      LogicVRegister dst,
1918                      const LogicVRegister& src1,
1919                      const LogicVRegister& src2);
1920  LogicVRegister mla(VectorFormat vform,
1921                     LogicVRegister dst,
1922                     const LogicVRegister& src1,
1923                     const LogicVRegister& src2);
1924  LogicVRegister mls(VectorFormat vform,
1925                     LogicVRegister dst,
1926                     const LogicVRegister& src1,
1927                     const LogicVRegister& src2);
1928  LogicVRegister mul(VectorFormat vform,
1929                     LogicVRegister dst,
1930                     const LogicVRegister& src1,
1931                     const LogicVRegister& src2);
1932  LogicVRegister mul(VectorFormat vform,
1933                     LogicVRegister dst,
1934                     const LogicVRegister& src1,
1935                     const LogicVRegister& src2,
1936                     int index);
1937  LogicVRegister mla(VectorFormat vform,
1938                     LogicVRegister dst,
1939                     const LogicVRegister& src1,
1940                     const LogicVRegister& src2,
1941                     int index);
1942  LogicVRegister mls(VectorFormat vform,
1943                     LogicVRegister dst,
1944                     const LogicVRegister& src1,
1945                     const LogicVRegister& src2,
1946                     int index);
1947  LogicVRegister pmul(VectorFormat vform,
1948                      LogicVRegister dst,
1949                      const LogicVRegister& src1,
1950                      const LogicVRegister& src2);
1951
1952  typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
1953                                                   LogicVRegister dst,
1954                                                   const LogicVRegister& src1,
1955                                                   const LogicVRegister& src2,
1956                                                   int index);
1957  LogicVRegister fmul(VectorFormat vform,
1958                      LogicVRegister dst,
1959                      const LogicVRegister& src1,
1960                      const LogicVRegister& src2,
1961                      int index);
1962  LogicVRegister fmla(VectorFormat vform,
1963                      LogicVRegister dst,
1964                      const LogicVRegister& src1,
1965                      const LogicVRegister& src2,
1966                      int index);
1967  LogicVRegister fmls(VectorFormat vform,
1968                      LogicVRegister dst,
1969                      const LogicVRegister& src1,
1970                      const LogicVRegister& src2,
1971                      int index);
1972  LogicVRegister fmulx(VectorFormat vform,
1973                       LogicVRegister dst,
1974                       const LogicVRegister& src1,
1975                       const LogicVRegister& src2,
1976                       int index);
1977  LogicVRegister smull(VectorFormat vform,
1978                       LogicVRegister dst,
1979                       const LogicVRegister& src1,
1980                       const LogicVRegister& src2,
1981                       int index);
1982  LogicVRegister smull2(VectorFormat vform,
1983                        LogicVRegister dst,
1984                        const LogicVRegister& src1,
1985                        const LogicVRegister& src2,
1986                        int index);
1987  LogicVRegister umull(VectorFormat vform,
1988                       LogicVRegister dst,
1989                       const LogicVRegister& src1,
1990                       const LogicVRegister& src2,
1991                       int index);
1992  LogicVRegister umull2(VectorFormat vform,
1993                        LogicVRegister dst,
1994                        const LogicVRegister& src1,
1995                        const LogicVRegister& src2,
1996                        int index);
1997  LogicVRegister smlal(VectorFormat vform,
1998                       LogicVRegister dst,
1999                       const LogicVRegister& src1,
2000                       const LogicVRegister& src2,
2001                       int index);
2002  LogicVRegister smlal2(VectorFormat vform,
2003                        LogicVRegister dst,
2004                        const LogicVRegister& src1,
2005                        const LogicVRegister& src2,
2006                        int index);
2007  LogicVRegister umlal(VectorFormat vform,
2008                       LogicVRegister dst,
2009                       const LogicVRegister& src1,
2010                       const LogicVRegister& src2,
2011                       int index);
2012  LogicVRegister umlal2(VectorFormat vform,
2013                        LogicVRegister dst,
2014                        const LogicVRegister& src1,
2015                        const LogicVRegister& src2,
2016                        int index);
2017  LogicVRegister smlsl(VectorFormat vform,
2018                       LogicVRegister dst,
2019                       const LogicVRegister& src1,
2020                       const LogicVRegister& src2,
2021                       int index);
2022  LogicVRegister smlsl2(VectorFormat vform,
2023                        LogicVRegister dst,
2024                        const LogicVRegister& src1,
2025                        const LogicVRegister& src2,
2026                        int index);
2027  LogicVRegister umlsl(VectorFormat vform,
2028                       LogicVRegister dst,
2029                       const LogicVRegister& src1,
2030                       const LogicVRegister& src2,
2031                       int index);
2032  LogicVRegister umlsl2(VectorFormat vform,
2033                        LogicVRegister dst,
2034                        const LogicVRegister& src1,
2035                        const LogicVRegister& src2,
2036                        int index);
2037  LogicVRegister sqdmull(VectorFormat vform,
2038                         LogicVRegister dst,
2039                         const LogicVRegister& src1,
2040                         const LogicVRegister& src2,
2041                         int index);
2042  LogicVRegister sqdmull2(VectorFormat vform,
2043                          LogicVRegister dst,
2044                          const LogicVRegister& src1,
2045                          const LogicVRegister& src2,
2046                          int index);
2047  LogicVRegister sqdmlal(VectorFormat vform,
2048                         LogicVRegister dst,
2049                         const LogicVRegister& src1,
2050                         const LogicVRegister& src2,
2051                         int index);
2052  LogicVRegister sqdmlal2(VectorFormat vform,
2053                          LogicVRegister dst,
2054                          const LogicVRegister& src1,
2055                          const LogicVRegister& src2,
2056                          int index);
2057  LogicVRegister sqdmlsl(VectorFormat vform,
2058                         LogicVRegister dst,
2059                         const LogicVRegister& src1,
2060                         const LogicVRegister& src2,
2061                         int index);
2062  LogicVRegister sqdmlsl2(VectorFormat vform,
2063                          LogicVRegister dst,
2064                          const LogicVRegister& src1,
2065                          const LogicVRegister& src2,
2066                          int index);
2067  LogicVRegister sqdmulh(VectorFormat vform,
2068                         LogicVRegister dst,
2069                         const LogicVRegister& src1,
2070                         const LogicVRegister& src2,
2071                         int index);
2072  LogicVRegister sqrdmulh(VectorFormat vform,
2073                          LogicVRegister dst,
2074                          const LogicVRegister& src1,
2075                          const LogicVRegister& src2,
2076                          int index);
2077  LogicVRegister sub(VectorFormat vform,
2078                     LogicVRegister dst,
2079                     const LogicVRegister& src1,
2080                     const LogicVRegister& src2);
2081  LogicVRegister and_(VectorFormat vform,
2082                      LogicVRegister dst,
2083                      const LogicVRegister& src1,
2084                      const LogicVRegister& src2);
2085  LogicVRegister orr(VectorFormat vform,
2086                     LogicVRegister dst,
2087                     const LogicVRegister& src1,
2088                     const LogicVRegister& src2);
2089  LogicVRegister orn(VectorFormat vform,
2090                     LogicVRegister dst,
2091                     const LogicVRegister& src1,
2092                     const LogicVRegister& src2);
2093  LogicVRegister eor(VectorFormat vform,
2094                     LogicVRegister dst,
2095                     const LogicVRegister& src1,
2096                     const LogicVRegister& src2);
2097  LogicVRegister bic(VectorFormat vform,
2098                     LogicVRegister dst,
2099                     const LogicVRegister& src1,
2100                     const LogicVRegister& src2);
2101  LogicVRegister bic(VectorFormat vform,
2102                     LogicVRegister dst,
2103                     const LogicVRegister& src,
2104                     uint64_t imm);
2105  LogicVRegister bif(VectorFormat vform,
2106                     LogicVRegister dst,
2107                     const LogicVRegister& src1,
2108                     const LogicVRegister& src2);
2109  LogicVRegister bit(VectorFormat vform,
2110                     LogicVRegister dst,
2111                     const LogicVRegister& src1,
2112                     const LogicVRegister& src2);
2113  LogicVRegister bsl(VectorFormat vform,
2114                     LogicVRegister dst,
2115                     const LogicVRegister& src1,
2116                     const LogicVRegister& src2);
2117  LogicVRegister cls(VectorFormat vform,
2118                     LogicVRegister dst,
2119                     const LogicVRegister& src);
2120  LogicVRegister clz(VectorFormat vform,
2121                     LogicVRegister dst,
2122                     const LogicVRegister& src);
2123  LogicVRegister cnt(VectorFormat vform,
2124                     LogicVRegister dst,
2125                     const LogicVRegister& src);
2126  LogicVRegister not_(VectorFormat vform,
2127                      LogicVRegister dst,
2128                      const LogicVRegister& src);
2129  LogicVRegister rbit(VectorFormat vform,
2130                      LogicVRegister dst,
2131                      const LogicVRegister& src);
2132  LogicVRegister rev(VectorFormat vform,
2133                     LogicVRegister dst,
2134                     const LogicVRegister& src,
2135                     int revSize);
2136  LogicVRegister rev16(VectorFormat vform,
2137                       LogicVRegister dst,
2138                       const LogicVRegister& src);
2139  LogicVRegister rev32(VectorFormat vform,
2140                       LogicVRegister dst,
2141                       const LogicVRegister& src);
2142  LogicVRegister rev64(VectorFormat vform,
2143                       LogicVRegister dst,
2144                       const LogicVRegister& src);
2145  LogicVRegister addlp(VectorFormat vform,
2146                       LogicVRegister dst,
2147                       const LogicVRegister& src,
2148                       bool is_signed,
2149                       bool do_accumulate);
2150  LogicVRegister saddlp(VectorFormat vform,
2151                        LogicVRegister dst,
2152                        const LogicVRegister& src);
2153  LogicVRegister uaddlp(VectorFormat vform,
2154                        LogicVRegister dst,
2155                        const LogicVRegister& src);
2156  LogicVRegister sadalp(VectorFormat vform,
2157                        LogicVRegister dst,
2158                        const LogicVRegister& src);
2159  LogicVRegister uadalp(VectorFormat vform,
2160                        LogicVRegister dst,
2161                        const LogicVRegister& src);
2162  LogicVRegister ext(VectorFormat vform,
2163                     LogicVRegister dst,
2164                     const LogicVRegister& src1,
2165                     const LogicVRegister& src2,
2166                     int index);
2167  LogicVRegister ins_element(VectorFormat vform,
2168                             LogicVRegister dst,
2169                             int dst_index,
2170                             const LogicVRegister& src,
2171                             int src_index);
2172  LogicVRegister ins_immediate(VectorFormat vform,
2173                               LogicVRegister dst,
2174                               int dst_index,
2175                               uint64_t imm);
2176  LogicVRegister dup_element(VectorFormat vform,
2177                             LogicVRegister dst,
2178                             const LogicVRegister& src,
2179                             int src_index);
2180  LogicVRegister dup_immediate(VectorFormat vform,
2181                               LogicVRegister dst,
2182                               uint64_t imm);
2183  LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2184  LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2185  LogicVRegister orr(VectorFormat vform,
2186                     LogicVRegister dst,
2187                     const LogicVRegister& src,
2188                     uint64_t imm);
2189  LogicVRegister sshl(VectorFormat vform,
2190                      LogicVRegister dst,
2191                      const LogicVRegister& src1,
2192                      const LogicVRegister& src2);
2193  LogicVRegister ushl(VectorFormat vform,
2194                      LogicVRegister dst,
2195                      const LogicVRegister& src1,
2196                      const LogicVRegister& src2);
2197  LogicVRegister sminmax(VectorFormat vform,
2198                         LogicVRegister dst,
2199                         const LogicVRegister& src1,
2200                         const LogicVRegister& src2,
2201                         bool max);
2202  LogicVRegister smax(VectorFormat vform,
2203                      LogicVRegister dst,
2204                      const LogicVRegister& src1,
2205                      const LogicVRegister& src2);
2206  LogicVRegister smin(VectorFormat vform,
2207                      LogicVRegister dst,
2208                      const LogicVRegister& src1,
2209                      const LogicVRegister& src2);
2210  LogicVRegister sminmaxp(VectorFormat vform,
2211                          LogicVRegister dst,
2212                          int dst_index,
2213                          const LogicVRegister& src,
2214                          bool max);
2215  LogicVRegister smaxp(VectorFormat vform,
2216                       LogicVRegister dst,
2217                       const LogicVRegister& src1,
2218                       const LogicVRegister& src2);
2219  LogicVRegister sminp(VectorFormat vform,
2220                       LogicVRegister dst,
2221                       const LogicVRegister& src1,
2222                       const LogicVRegister& src2);
2223  LogicVRegister addp(VectorFormat vform,
2224                      LogicVRegister dst,
2225                      const LogicVRegister& src);
2226  LogicVRegister addv(VectorFormat vform,
2227                      LogicVRegister dst,
2228                      const LogicVRegister& src);
2229  LogicVRegister uaddlv(VectorFormat vform,
2230                        LogicVRegister dst,
2231                        const LogicVRegister& src);
2232  LogicVRegister saddlv(VectorFormat vform,
2233                        LogicVRegister dst,
2234                        const LogicVRegister& src);
2235  LogicVRegister sminmaxv(VectorFormat vform,
2236                          LogicVRegister dst,
2237                          const LogicVRegister& src,
2238                          bool max);
2239  LogicVRegister smaxv(VectorFormat vform,
2240                       LogicVRegister dst,
2241                       const LogicVRegister& src);
2242  LogicVRegister sminv(VectorFormat vform,
2243                       LogicVRegister dst,
2244                       const LogicVRegister& src);
2245  LogicVRegister uxtl(VectorFormat vform,
2246                      LogicVRegister dst,
2247                      const LogicVRegister& src);
2248  LogicVRegister uxtl2(VectorFormat vform,
2249                       LogicVRegister dst,
2250                       const LogicVRegister& src);
2251  LogicVRegister sxtl(VectorFormat vform,
2252                      LogicVRegister dst,
2253                      const LogicVRegister& src);
2254  LogicVRegister sxtl2(VectorFormat vform,
2255                       LogicVRegister dst,
2256                       const LogicVRegister& src);
2257  LogicVRegister tbl(VectorFormat vform,
2258                     LogicVRegister dst,
2259                     const LogicVRegister& tab,
2260                     const LogicVRegister& ind);
2261  LogicVRegister tbl(VectorFormat vform,
2262                     LogicVRegister dst,
2263                     const LogicVRegister& tab,
2264                     const LogicVRegister& tab2,
2265                     const LogicVRegister& ind);
2266  LogicVRegister tbl(VectorFormat vform,
2267                     LogicVRegister dst,
2268                     const LogicVRegister& tab,
2269                     const LogicVRegister& tab2,
2270                     const LogicVRegister& tab3,
2271                     const LogicVRegister& ind);
2272  LogicVRegister tbl(VectorFormat vform,
2273                     LogicVRegister dst,
2274                     const LogicVRegister& tab,
2275                     const LogicVRegister& tab2,
2276                     const LogicVRegister& tab3,
2277                     const LogicVRegister& tab4,
2278                     const LogicVRegister& ind);
2279  LogicVRegister tbx(VectorFormat vform,
2280                     LogicVRegister dst,
2281                     const LogicVRegister& tab,
2282                     const LogicVRegister& ind);
2283  LogicVRegister tbx(VectorFormat vform,
2284                     LogicVRegister dst,
2285                     const LogicVRegister& tab,
2286                     const LogicVRegister& tab2,
2287                     const LogicVRegister& ind);
2288  LogicVRegister tbx(VectorFormat vform,
2289                     LogicVRegister dst,
2290                     const LogicVRegister& tab,
2291                     const LogicVRegister& tab2,
2292                     const LogicVRegister& tab3,
2293                     const LogicVRegister& ind);
2294  LogicVRegister tbx(VectorFormat vform,
2295                     LogicVRegister dst,
2296                     const LogicVRegister& tab,
2297                     const LogicVRegister& tab2,
2298                     const LogicVRegister& tab3,
2299                     const LogicVRegister& tab4,
2300                     const LogicVRegister& ind);
2301  LogicVRegister uaddl(VectorFormat vform,
2302                       LogicVRegister dst,
2303                       const LogicVRegister& src1,
2304                       const LogicVRegister& src2);
2305  LogicVRegister uaddl2(VectorFormat vform,
2306                        LogicVRegister dst,
2307                        const LogicVRegister& src1,
2308                        const LogicVRegister& src2);
2309  LogicVRegister uaddw(VectorFormat vform,
2310                       LogicVRegister dst,
2311                       const LogicVRegister& src1,
2312                       const LogicVRegister& src2);
2313  LogicVRegister uaddw2(VectorFormat vform,
2314                        LogicVRegister dst,
2315                        const LogicVRegister& src1,
2316                        const LogicVRegister& src2);
2317  LogicVRegister saddl(VectorFormat vform,
2318                       LogicVRegister dst,
2319                       const LogicVRegister& src1,
2320                       const LogicVRegister& src2);
2321  LogicVRegister saddl2(VectorFormat vform,
2322                        LogicVRegister dst,
2323                        const LogicVRegister& src1,
2324                        const LogicVRegister& src2);
2325  LogicVRegister saddw(VectorFormat vform,
2326                       LogicVRegister dst,
2327                       const LogicVRegister& src1,
2328                       const LogicVRegister& src2);
2329  LogicVRegister saddw2(VectorFormat vform,
2330                        LogicVRegister dst,
2331                        const LogicVRegister& src1,
2332                        const LogicVRegister& src2);
2333  LogicVRegister usubl(VectorFormat vform,
2334                       LogicVRegister dst,
2335                       const LogicVRegister& src1,
2336                       const LogicVRegister& src2);
2337  LogicVRegister usubl2(VectorFormat vform,
2338                        LogicVRegister dst,
2339                        const LogicVRegister& src1,
2340                        const LogicVRegister& src2);
2341  LogicVRegister usubw(VectorFormat vform,
2342                       LogicVRegister dst,
2343                       const LogicVRegister& src1,
2344                       const LogicVRegister& src2);
2345  LogicVRegister usubw2(VectorFormat vform,
2346                        LogicVRegister dst,
2347                        const LogicVRegister& src1,
2348                        const LogicVRegister& src2);
2349  LogicVRegister ssubl(VectorFormat vform,
2350                       LogicVRegister dst,
2351                       const LogicVRegister& src1,
2352                       const LogicVRegister& src2);
2353  LogicVRegister ssubl2(VectorFormat vform,
2354                        LogicVRegister dst,
2355                        const LogicVRegister& src1,
2356                        const LogicVRegister& src2);
2357  LogicVRegister ssubw(VectorFormat vform,
2358                       LogicVRegister dst,
2359                       const LogicVRegister& src1,
2360                       const LogicVRegister& src2);
2361  LogicVRegister ssubw2(VectorFormat vform,
2362                        LogicVRegister dst,
2363                        const LogicVRegister& src1,
2364                        const LogicVRegister& src2);
2365  LogicVRegister uminmax(VectorFormat vform,
2366                         LogicVRegister dst,
2367                         const LogicVRegister& src1,
2368                         const LogicVRegister& src2,
2369                         bool max);
2370  LogicVRegister umax(VectorFormat vform,
2371                      LogicVRegister dst,
2372                      const LogicVRegister& src1,
2373                      const LogicVRegister& src2);
2374  LogicVRegister umin(VectorFormat vform,
2375                      LogicVRegister dst,
2376                      const LogicVRegister& src1,
2377                      const LogicVRegister& src2);
2378  LogicVRegister uminmaxp(VectorFormat vform,
2379                          LogicVRegister dst,
2380                          int dst_index,
2381                          const LogicVRegister& src,
2382                          bool max);
2383  LogicVRegister umaxp(VectorFormat vform,
2384                       LogicVRegister dst,
2385                       const LogicVRegister& src1,
2386                       const LogicVRegister& src2);
2387  LogicVRegister uminp(VectorFormat vform,
2388                       LogicVRegister dst,
2389                       const LogicVRegister& src1,
2390                       const LogicVRegister& src2);
2391  LogicVRegister uminmaxv(VectorFormat vform,
2392                          LogicVRegister dst,
2393                          const LogicVRegister& src,
2394                          bool max);
2395  LogicVRegister umaxv(VectorFormat vform,
2396                       LogicVRegister dst,
2397                       const LogicVRegister& src);
2398  LogicVRegister uminv(VectorFormat vform,
2399                       LogicVRegister dst,
2400                       const LogicVRegister& src);
2401  LogicVRegister trn1(VectorFormat vform,
2402                      LogicVRegister dst,
2403                      const LogicVRegister& src1,
2404                      const LogicVRegister& src2);
2405  LogicVRegister trn2(VectorFormat vform,
2406                      LogicVRegister dst,
2407                      const LogicVRegister& src1,
2408                      const LogicVRegister& src2);
2409  LogicVRegister zip1(VectorFormat vform,
2410                      LogicVRegister dst,
2411                      const LogicVRegister& src1,
2412                      const LogicVRegister& src2);
2413  LogicVRegister zip2(VectorFormat vform,
2414                      LogicVRegister dst,
2415                      const LogicVRegister& src1,
2416                      const LogicVRegister& src2);
2417  LogicVRegister uzp1(VectorFormat vform,
2418                      LogicVRegister dst,
2419                      const LogicVRegister& src1,
2420                      const LogicVRegister& src2);
2421  LogicVRegister uzp2(VectorFormat vform,
2422                      LogicVRegister dst,
2423                      const LogicVRegister& src1,
2424                      const LogicVRegister& src2);
2425  LogicVRegister shl(VectorFormat vform,
2426                     LogicVRegister dst,
2427                     const LogicVRegister& src,
2428                     int shift);
2429  LogicVRegister scvtf(VectorFormat vform,
2430                       LogicVRegister dst,
2431                       const LogicVRegister& src,
2432                       int fbits,
2433                       FPRounding rounding_mode);
2434  LogicVRegister ucvtf(VectorFormat vform,
2435                       LogicVRegister dst,
2436                       const LogicVRegister& src,
2437                       int fbits,
2438                       FPRounding rounding_mode);
2439  LogicVRegister sshll(VectorFormat vform,
2440                       LogicVRegister dst,
2441                       const LogicVRegister& src,
2442                       int shift);
2443  LogicVRegister sshll2(VectorFormat vform,
2444                        LogicVRegister dst,
2445                        const LogicVRegister& src,
2446                        int shift);
2447  LogicVRegister shll(VectorFormat vform,
2448                      LogicVRegister dst,
2449                      const LogicVRegister& src);
2450  LogicVRegister shll2(VectorFormat vform,
2451                       LogicVRegister dst,
2452                       const LogicVRegister& src);
2453  LogicVRegister ushll(VectorFormat vform,
2454                       LogicVRegister dst,
2455                       const LogicVRegister& src,
2456                       int shift);
2457  LogicVRegister ushll2(VectorFormat vform,
2458                        LogicVRegister dst,
2459                        const LogicVRegister& src,
2460                        int shift);
2461  LogicVRegister sli(VectorFormat vform,
2462                     LogicVRegister dst,
2463                     const LogicVRegister& src,
2464                     int shift);
2465  LogicVRegister sri(VectorFormat vform,
2466                     LogicVRegister dst,
2467                     const LogicVRegister& src,
2468                     int shift);
2469  LogicVRegister sshr(VectorFormat vform,
2470                      LogicVRegister dst,
2471                      const LogicVRegister& src,
2472                      int shift);
2473  LogicVRegister ushr(VectorFormat vform,
2474                      LogicVRegister dst,
2475                      const LogicVRegister& src,
2476                      int shift);
2477  LogicVRegister ssra(VectorFormat vform,
2478                      LogicVRegister dst,
2479                      const LogicVRegister& src,
2480                      int shift);
2481  LogicVRegister usra(VectorFormat vform,
2482                      LogicVRegister dst,
2483                      const LogicVRegister& src,
2484                      int shift);
2485  LogicVRegister srsra(VectorFormat vform,
2486                       LogicVRegister dst,
2487                       const LogicVRegister& src,
2488                       int shift);
2489  LogicVRegister ursra(VectorFormat vform,
2490                       LogicVRegister dst,
2491                       const LogicVRegister& src,
2492                       int shift);
2493  LogicVRegister suqadd(VectorFormat vform,
2494                        LogicVRegister dst,
2495                        const LogicVRegister& src);
2496  LogicVRegister usqadd(VectorFormat vform,
2497                        LogicVRegister dst,
2498                        const LogicVRegister& src);
2499  LogicVRegister sqshl(VectorFormat vform,
2500                       LogicVRegister dst,
2501                       const LogicVRegister& src,
2502                       int shift);
2503  LogicVRegister uqshl(VectorFormat vform,
2504                       LogicVRegister dst,
2505                       const LogicVRegister& src,
2506                       int shift);
2507  LogicVRegister sqshlu(VectorFormat vform,
2508                        LogicVRegister dst,
2509                        const LogicVRegister& src,
2510                        int shift);
2511  LogicVRegister abs(VectorFormat vform,
2512                     LogicVRegister dst,
2513                     const LogicVRegister& src);
2514  LogicVRegister neg(VectorFormat vform,
2515                     LogicVRegister dst,
2516                     const LogicVRegister& src);
2517  LogicVRegister extractnarrow(VectorFormat vform,
2518                               LogicVRegister dst,
2519                               bool dstIsSigned,
2520                               const LogicVRegister& src,
2521                               bool srcIsSigned);
2522  LogicVRegister xtn(VectorFormat vform,
2523                     LogicVRegister dst,
2524                     const LogicVRegister& src);
2525  LogicVRegister sqxtn(VectorFormat vform,
2526                       LogicVRegister dst,
2527                       const LogicVRegister& src);
2528  LogicVRegister uqxtn(VectorFormat vform,
2529                       LogicVRegister dst,
2530                       const LogicVRegister& src);
2531  LogicVRegister sqxtun(VectorFormat vform,
2532                        LogicVRegister dst,
2533                        const LogicVRegister& src);
2534  LogicVRegister absdiff(VectorFormat vform,
2535                         LogicVRegister dst,
2536                         const LogicVRegister& src1,
2537                         const LogicVRegister& src2,
2538                         bool issigned);
2539  LogicVRegister saba(VectorFormat vform,
2540                      LogicVRegister dst,
2541                      const LogicVRegister& src1,
2542                      const LogicVRegister& src2);
2543  LogicVRegister uaba(VectorFormat vform,
2544                      LogicVRegister dst,
2545                      const LogicVRegister& src1,
2546                      const LogicVRegister& src2);
2547  LogicVRegister shrn(VectorFormat vform,
2548                      LogicVRegister dst,
2549                      const LogicVRegister& src,
2550                      int shift);
2551  LogicVRegister shrn2(VectorFormat vform,
2552                       LogicVRegister dst,
2553                       const LogicVRegister& src,
2554                       int shift);
2555  LogicVRegister rshrn(VectorFormat vform,
2556                       LogicVRegister dst,
2557                       const LogicVRegister& src,
2558                       int shift);
2559  LogicVRegister rshrn2(VectorFormat vform,
2560                        LogicVRegister dst,
2561                        const LogicVRegister& src,
2562                        int shift);
2563  LogicVRegister uqshrn(VectorFormat vform,
2564                        LogicVRegister dst,
2565                        const LogicVRegister& src,
2566                        int shift);
2567  LogicVRegister uqshrn2(VectorFormat vform,
2568                         LogicVRegister dst,
2569                         const LogicVRegister& src,
2570                         int shift);
2571  LogicVRegister uqrshrn(VectorFormat vform,
2572                         LogicVRegister dst,
2573                         const LogicVRegister& src,
2574                         int shift);
2575  LogicVRegister uqrshrn2(VectorFormat vform,
2576                          LogicVRegister dst,
2577                          const LogicVRegister& src,
2578                          int shift);
2579  LogicVRegister sqshrn(VectorFormat vform,
2580                        LogicVRegister dst,
2581                        const LogicVRegister& src,
2582                        int shift);
2583  LogicVRegister sqshrn2(VectorFormat vform,
2584                         LogicVRegister dst,
2585                         const LogicVRegister& src,
2586                         int shift);
2587  LogicVRegister sqrshrn(VectorFormat vform,
2588                         LogicVRegister dst,
2589                         const LogicVRegister& src,
2590                         int shift);
2591  LogicVRegister sqrshrn2(VectorFormat vform,
2592                          LogicVRegister dst,
2593                          const LogicVRegister& src,
2594                          int shift);
2595  LogicVRegister sqshrun(VectorFormat vform,
2596                         LogicVRegister dst,
2597                         const LogicVRegister& src,
2598                         int shift);
2599  LogicVRegister sqshrun2(VectorFormat vform,
2600                          LogicVRegister dst,
2601                          const LogicVRegister& src,
2602                          int shift);
2603  LogicVRegister sqrshrun(VectorFormat vform,
2604                          LogicVRegister dst,
2605                          const LogicVRegister& src,
2606                          int shift);
2607  LogicVRegister sqrshrun2(VectorFormat vform,
2608                           LogicVRegister dst,
2609                           const LogicVRegister& src,
2610                           int shift);
2611  LogicVRegister sqrdmulh(VectorFormat vform,
2612                          LogicVRegister dst,
2613                          const LogicVRegister& src1,
2614                          const LogicVRegister& src2,
2615                          bool round = true);
2616  LogicVRegister sqdmulh(VectorFormat vform,
2617                         LogicVRegister dst,
2618                         const LogicVRegister& src1,
2619                         const LogicVRegister& src2);
2620#define NEON_3VREG_LOGIC_LIST(V) \
2621  V(addhn)                       \
2622  V(addhn2)                      \
2623  V(raddhn)                      \
2624  V(raddhn2)                     \
2625  V(subhn)                       \
2626  V(subhn2)                      \
2627  V(rsubhn)                      \
2628  V(rsubhn2)                     \
2629  V(pmull)                       \
2630  V(pmull2)                      \
2631  V(sabal)                       \
2632  V(sabal2)                      \
2633  V(uabal)                       \
2634  V(uabal2)                      \
2635  V(sabdl)                       \
2636  V(sabdl2)                      \
2637  V(uabdl)                       \
2638  V(uabdl2)                      \
2639  V(smull)                       \
2640  V(smull2)                      \
2641  V(umull)                       \
2642  V(umull2)                      \
2643  V(smlal)                       \
2644  V(smlal2)                      \
2645  V(umlal)                       \
2646  V(umlal2)                      \
2647  V(smlsl)                       \
2648  V(smlsl2)                      \
2649  V(umlsl)                       \
2650  V(umlsl2)                      \
2651  V(sqdmlal)                     \
2652  V(sqdmlal2)                    \
2653  V(sqdmlsl)                     \
2654  V(sqdmlsl2)                    \
2655  V(sqdmull)                     \
2656  V(sqdmull2)
2657
2658#define DEFINE_LOGIC_FUNC(FXN)                   \
2659  LogicVRegister FXN(VectorFormat vform,         \
2660                     LogicVRegister dst,         \
2661                     const LogicVRegister& src1, \
2662                     const LogicVRegister& src2);
2663  NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
2664#undef DEFINE_LOGIC_FUNC
2665
2666#define NEON_FP3SAME_LIST(V) \
2667  V(fadd, FPAdd, false)      \
2668  V(fsub, FPSub, true)       \
2669  V(fmul, FPMul, true)       \
2670  V(fmulx, FPMulx, true)     \
2671  V(fdiv, FPDiv, true)       \
2672  V(fmax, FPMax, false)      \
2673  V(fmin, FPMin, false)      \
2674  V(fmaxnm, FPMaxNM, false)  \
2675  V(fminnm, FPMinNM, false)
2676
2677#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
2678  template <typename T>                            \
2679  LogicVRegister FN(VectorFormat vform,            \
2680                    LogicVRegister dst,            \
2681                    const LogicVRegister& src1,    \
2682                    const LogicVRegister& src2);   \
2683  LogicVRegister FN(VectorFormat vform,            \
2684                    LogicVRegister dst,            \
2685                    const LogicVRegister& src1,    \
2686                    const LogicVRegister& src2);
2687  NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
2688#undef DECLARE_NEON_FP_VECTOR_OP
2689
2690#define NEON_FPPAIRWISE_LIST(V) \
2691  V(faddp, fadd, FPAdd)         \
2692  V(fmaxp, fmax, FPMax)         \
2693  V(fmaxnmp, fmaxnm, FPMaxNM)   \
2694  V(fminp, fmin, FPMin)         \
2695  V(fminnmp, fminnm, FPMinNM)
2696
2697#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)      \
2698  LogicVRegister FNP(VectorFormat vform,          \
2699                     LogicVRegister dst,          \
2700                     const LogicVRegister& src1,  \
2701                     const LogicVRegister& src2); \
2702  LogicVRegister FNP(VectorFormat vform,          \
2703                     LogicVRegister dst,          \
2704                     const LogicVRegister& src);
2705  NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
2706#undef DECLARE_NEON_FP_PAIR_OP
2707
2708  template <typename T>
2709  LogicVRegister frecps(VectorFormat vform,
2710                        LogicVRegister dst,
2711                        const LogicVRegister& src1,
2712                        const LogicVRegister& src2);
2713  LogicVRegister frecps(VectorFormat vform,
2714                        LogicVRegister dst,
2715                        const LogicVRegister& src1,
2716                        const LogicVRegister& src2);
2717  template <typename T>
2718  LogicVRegister frsqrts(VectorFormat vform,
2719                         LogicVRegister dst,
2720                         const LogicVRegister& src1,
2721                         const LogicVRegister& src2);
2722  LogicVRegister frsqrts(VectorFormat vform,
2723                         LogicVRegister dst,
2724                         const LogicVRegister& src1,
2725                         const LogicVRegister& src2);
2726  template <typename T>
2727  LogicVRegister fmla(VectorFormat vform,
2728                      LogicVRegister dst,
2729                      const LogicVRegister& src1,
2730                      const LogicVRegister& src2);
2731  LogicVRegister fmla(VectorFormat vform,
2732                      LogicVRegister dst,
2733                      const LogicVRegister& src1,
2734                      const LogicVRegister& src2);
2735  template <typename T>
2736  LogicVRegister fmls(VectorFormat vform,
2737                      LogicVRegister dst,
2738                      const LogicVRegister& src1,
2739                      const LogicVRegister& src2);
2740  LogicVRegister fmls(VectorFormat vform,
2741                      LogicVRegister dst,
2742                      const LogicVRegister& src1,
2743                      const LogicVRegister& src2);
2744  LogicVRegister fnmul(VectorFormat vform,
2745                       LogicVRegister dst,
2746                       const LogicVRegister& src1,
2747                       const LogicVRegister& src2);
2748
2749  template <typename T>
2750  LogicVRegister fcmp(VectorFormat vform,
2751                      LogicVRegister dst,
2752                      const LogicVRegister& src1,
2753                      const LogicVRegister& src2,
2754                      Condition cond);
2755  LogicVRegister fcmp(VectorFormat vform,
2756                      LogicVRegister dst,
2757                      const LogicVRegister& src1,
2758                      const LogicVRegister& src2,
2759                      Condition cond);
2760  LogicVRegister fabscmp(VectorFormat vform,
2761                         LogicVRegister dst,
2762                         const LogicVRegister& src1,
2763                         const LogicVRegister& src2,
2764                         Condition cond);
2765  LogicVRegister fcmp_zero(VectorFormat vform,
2766                           LogicVRegister dst,
2767                           const LogicVRegister& src,
2768                           Condition cond);
2769
2770  template <typename T>
2771  LogicVRegister fneg(VectorFormat vform,
2772                      LogicVRegister dst,
2773                      const LogicVRegister& src);
2774  LogicVRegister fneg(VectorFormat vform,
2775                      LogicVRegister dst,
2776                      const LogicVRegister& src);
2777  template <typename T>
2778  LogicVRegister frecpx(VectorFormat vform,
2779                        LogicVRegister dst,
2780                        const LogicVRegister& src);
2781  LogicVRegister frecpx(VectorFormat vform,
2782                        LogicVRegister dst,
2783                        const LogicVRegister& src);
2784  template <typename T>
2785  LogicVRegister fabs_(VectorFormat vform,
2786                       LogicVRegister dst,
2787                       const LogicVRegister& src);
2788  LogicVRegister fabs_(VectorFormat vform,
2789                       LogicVRegister dst,
2790                       const LogicVRegister& src);
2791  LogicVRegister fabd(VectorFormat vform,
2792                      LogicVRegister dst,
2793                      const LogicVRegister& src1,
2794                      const LogicVRegister& src2);
2795  LogicVRegister frint(VectorFormat vform,
2796                       LogicVRegister dst,
2797                       const LogicVRegister& src,
2798                       FPRounding rounding_mode,
2799                       bool inexact_exception = false);
2800  LogicVRegister fcvts(VectorFormat vform,
2801                       LogicVRegister dst,
2802                       const LogicVRegister& src,
2803                       FPRounding rounding_mode,
2804                       int fbits = 0);
2805  LogicVRegister fcvtu(VectorFormat vform,
2806                       LogicVRegister dst,
2807                       const LogicVRegister& src,
2808                       FPRounding rounding_mode,
2809                       int fbits = 0);
2810  LogicVRegister fcvtl(VectorFormat vform,
2811                       LogicVRegister dst,
2812                       const LogicVRegister& src);
2813  LogicVRegister fcvtl2(VectorFormat vform,
2814                        LogicVRegister dst,
2815                        const LogicVRegister& src);
2816  LogicVRegister fcvtn(VectorFormat vform,
2817                       LogicVRegister dst,
2818                       const LogicVRegister& src);
2819  LogicVRegister fcvtn2(VectorFormat vform,
2820                        LogicVRegister dst,
2821                        const LogicVRegister& src);
2822  LogicVRegister fcvtxn(VectorFormat vform,
2823                        LogicVRegister dst,
2824                        const LogicVRegister& src);
2825  LogicVRegister fcvtxn2(VectorFormat vform,
2826                         LogicVRegister dst,
2827                         const LogicVRegister& src);
2828  LogicVRegister fsqrt(VectorFormat vform,
2829                       LogicVRegister dst,
2830                       const LogicVRegister& src);
2831  LogicVRegister frsqrte(VectorFormat vform,
2832                         LogicVRegister dst,
2833                         const LogicVRegister& src);
2834  LogicVRegister frecpe(VectorFormat vform,
2835                        LogicVRegister dst,
2836                        const LogicVRegister& src,
2837                        FPRounding rounding);
2838  LogicVRegister ursqrte(VectorFormat vform,
2839                         LogicVRegister dst,
2840                         const LogicVRegister& src);
2841  LogicVRegister urecpe(VectorFormat vform,
2842                        LogicVRegister dst,
2843                        const LogicVRegister& src);
2844
2845  typedef float (Simulator::*FPMinMaxOp)(float a, float b);
2846
2847  LogicVRegister fminmaxv(VectorFormat vform,
2848                          LogicVRegister dst,
2849                          const LogicVRegister& src,
2850                          FPMinMaxOp Op);
2851
2852  LogicVRegister fminv(VectorFormat vform,
2853                       LogicVRegister dst,
2854                       const LogicVRegister& src);
2855  LogicVRegister fmaxv(VectorFormat vform,
2856                       LogicVRegister dst,
2857                       const LogicVRegister& src);
2858  LogicVRegister fminnmv(VectorFormat vform,
2859                         LogicVRegister dst,
2860                         const LogicVRegister& src);
2861  LogicVRegister fmaxnmv(VectorFormat vform,
2862                         LogicVRegister dst,
2863                         const LogicVRegister& src);
2864
2865  static const uint32_t CRC32_POLY = 0x04C11DB7;
2866  static const uint32_t CRC32C_POLY = 0x1EDC6F41;
2867  uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
2868  template <typename T>
2869  uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
2870  uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
2871
2872  void SysOp_W(int op, int64_t val);
2873
2874  template <typename T>
2875  T FPRecipSqrtEstimate(T op);
2876  template <typename T>
2877  T FPRecipEstimate(T op, FPRounding rounding);
2878  template <typename T, typename R>
2879  R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
2880
2881  void FPCompare(double val0, double val1, FPTrapFlags trap);
2882  double FPRoundInt(double value, FPRounding round_mode);
2883  double FPToDouble(float value);
2884  float FPToFloat(double value, FPRounding round_mode);
2885  float FPToFloat(float16 value);
2886  float16 FPToFloat16(float value, FPRounding round_mode);
2887  float16 FPToFloat16(double value, FPRounding round_mode);
2888  double recip_sqrt_estimate(double a);
2889  double recip_estimate(double a);
2890  double FPRecipSqrtEstimate(double a);
2891  double FPRecipEstimate(double a);
2892  double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
2893  double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
2894  float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
2895  float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
2896  int32_t FPToInt32(double value, FPRounding rmode);
2897  int64_t FPToInt64(double value, FPRounding rmode);
2898  uint32_t FPToUInt32(double value, FPRounding rmode);
2899  uint64_t FPToUInt64(double value, FPRounding rmode);
2900
2901  template <typename T>
2902  T FPAdd(T op1, T op2);
2903
2904  template <typename T>
2905  T FPDiv(T op1, T op2);
2906
2907  template <typename T>
2908  T FPMax(T a, T b);
2909
2910  template <typename T>
2911  T FPMaxNM(T a, T b);
2912
2913  template <typename T>
2914  T FPMin(T a, T b);
2915
2916  template <typename T>
2917  T FPMinNM(T a, T b);
2918
2919  template <typename T>
2920  T FPMul(T op1, T op2);
2921
2922  template <typename T>
2923  T FPMulx(T op1, T op2);
2924
2925  template <typename T>
2926  T FPMulAdd(T a, T op1, T op2);
2927
2928  template <typename T>
2929  T FPSqrt(T op);
2930
2931  template <typename T>
2932  T FPSub(T op1, T op2);
2933
2934  template <typename T>
2935  T FPRecipStepFused(T op1, T op2);
2936
2937  template <typename T>
2938  T FPRSqrtStepFused(T op1, T op2);
2939
2940  // This doesn't do anything at the moment. We'll need it if we want support
2941  // for cumulative exception bits or floating-point exceptions.
2942  void FPProcessException() {}
2943
2944  bool FPProcessNaNs(const Instruction* instr);
2945
2946  // Pseudo Printf instruction
2947  void DoPrintf(const Instruction* instr);
2948
2949// Simulate a runtime call.
2950#ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
2951  VIXL_NO_RETURN_IN_DEBUG_MODE
2952#endif
2953  void DoRuntimeCall(const Instruction* instr);
2954
2955  // Processor state ---------------------------------------
2956
2957  // Simulated monitors for exclusive access instructions.
2958  SimExclusiveLocalMonitor local_monitor_;
2959  SimExclusiveGlobalMonitor global_monitor_;
2960
2961  // Output stream.
2962  FILE* stream_;
2963  PrintDisassembler* print_disasm_;
2964
2965  // Instruction statistics instrumentation.
2966  Instrument* instrumentation_;
2967
2968  // General purpose registers. Register 31 is the stack pointer.
2969  SimRegister registers_[kNumberOfRegisters];
2970
2971  // Vector registers
2972  SimVRegister vregisters_[kNumberOfVRegisters];
2973
2974  // Program Status Register.
2975  // bits[31, 27]: Condition flags N, Z, C, and V.
2976  //               (Negative, Zero, Carry, Overflow)
2977  SimSystemRegister nzcv_;
2978
2979  // Floating-Point Control Register
2980  SimSystemRegister fpcr_;
2981
2982  // Only a subset of FPCR features are supported by the simulator. This helper
2983  // checks that the FPCR settings are supported.
2984  //
2985  // This is checked when floating-point instructions are executed, not when
2986  // FPCR is set. This allows generated code to modify FPCR for external
2987  // functions, or to save and restore it when entering and leaving generated
2988  // code.
2989  void AssertSupportedFPCR() {
2990    // No flush-to-zero support.
2991    VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
2992    // Ties-to-even rounding only.
2993    VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
2994
2995    // The simulator does not support half-precision operations so
2996    // GetFpcr().AHP() is irrelevant, and is not checked here.
2997  }
2998
2999  static int CalcNFlag(uint64_t result, unsigned reg_size) {
3000    return (result >> (reg_size - 1)) & 1;
3001  }
3002
3003  static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
3004
3005  static const uint32_t kConditionFlagsMask = 0xf0000000;
3006
3007  // Stack
3008  byte* stack_;
3009  static const int stack_protection_size_ = 256;
3010  // 2 KB stack.
3011  static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
3012  byte* stack_limit_;
3013
3014  Decoder* decoder_;
3015  // Indicates if the pc has been modified by the instruction and should not be
3016  // automatically incremented.
3017  bool pc_modified_;
3018  const Instruction* pc_;
3019
3020  static const char* xreg_names[];
3021  static const char* wreg_names[];
3022  static const char* sreg_names[];
3023  static const char* dreg_names[];
3024  static const char* vreg_names[];
3025
3026 private:
3027  template <typename T>
3028  static T FPDefaultNaN();
3029
3030  // Standard NaN processing.
3031  template <typename T>
3032  T FPProcessNaN(T op) {
3033    VIXL_ASSERT(std::isnan(op));
3034    if (IsSignallingNaN(op)) {
3035      FPProcessException();
3036    }
3037    return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
3038  }
3039
3040  template <typename T>
3041  T FPProcessNaNs(T op1, T op2) {
3042    if (IsSignallingNaN(op1)) {
3043      return FPProcessNaN(op1);
3044    } else if (IsSignallingNaN(op2)) {
3045      return FPProcessNaN(op2);
3046    } else if (std::isnan(op1)) {
3047      VIXL_ASSERT(IsQuietNaN(op1));
3048      return FPProcessNaN(op1);
3049    } else if (std::isnan(op2)) {
3050      VIXL_ASSERT(IsQuietNaN(op2));
3051      return FPProcessNaN(op2);
3052    } else {
3053      return 0.0;
3054    }
3055  }
3056
3057  template <typename T>
3058  T FPProcessNaNs3(T op1, T op2, T op3) {
3059    if (IsSignallingNaN(op1)) {
3060      return FPProcessNaN(op1);
3061    } else if (IsSignallingNaN(op2)) {
3062      return FPProcessNaN(op2);
3063    } else if (IsSignallingNaN(op3)) {
3064      return FPProcessNaN(op3);
3065    } else if (std::isnan(op1)) {
3066      VIXL_ASSERT(IsQuietNaN(op1));
3067      return FPProcessNaN(op1);
3068    } else if (std::isnan(op2)) {
3069      VIXL_ASSERT(IsQuietNaN(op2));
3070      return FPProcessNaN(op2);
3071    } else if (std::isnan(op3)) {
3072      VIXL_ASSERT(IsQuietNaN(op3));
3073      return FPProcessNaN(op3);
3074    } else {
3075      return 0.0;
3076    }
3077  }
3078
3079  bool coloured_trace_;
3080
3081  // A set of TraceParameters flags.
3082  int trace_parameters_;
3083
3084  // Indicates whether the instruction instrumentation is active.
3085  bool instruction_stats_;
3086
3087  // Indicates whether the exclusive-access warning has been printed.
3088  bool print_exclusive_access_warning_;
3089  void PrintExclusiveAccessWarning();
3090};
3091
3092#if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
3093// Base case of the recursive template used to emulate C++14
3094// `std::index_sequence`.
3095template <size_t... I>
3096struct Simulator::emulated_make_index_sequence_helper<0, I...>
3097    : Simulator::emulated_index_sequence<I...> {};
3098#endif
3099
3100}  // namespace aarch64
3101}  // namespace vixl
3102
3103#endif  // VIXL_AARCH64_SIMULATOR_AARCH64_H_
3104