simulator-aarch64.h revision 868bfc49d722d6a233390ec847fa1407820a1eab
1// Copyright 2015, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#ifndef VIXL_AARCH64_SIMULATOR_AARCH64_H_
28#define VIXL_AARCH64_SIMULATOR_AARCH64_H_
29
30#include "globals-vixl.h"
31#include "utils-vixl.h"
32
33#include "aarch64/abi-aarch64.h"
34#include "aarch64/disasm-aarch64.h"
35#include "aarch64/instructions-aarch64.h"
36#include "aarch64/instrument-aarch64.h"
37#include "aarch64/simulator-constants-aarch64.h"
38
39// These are only used for the ABI feature, and depend on checks performed for
40// it.
41#ifdef VIXL_ABI_SUPPORT
42#include <tuple>
43#if __cplusplus >= 201402L
44// Required for `std::index_sequence`
45#include <utility>
46#endif
47#endif
48
49namespace vixl {
50namespace aarch64 {
51
52// Assemble the specified IEEE-754 components into the target type and apply
53// appropriate rounding.
54//  sign:     0 = positive, 1 = negative
55//  exponent: Unbiased IEEE-754 exponent.
56//  mantissa: The mantissa of the input. The top bit (which is not encoded for
57//            normal IEEE-754 values) must not be omitted. This bit has the
58//            value 'pow(2, exponent)'.
59//
60// The input value is assumed to be a normalized value. That is, the input may
61// not be infinity or NaN. If the source value is subnormal, it must be
62// normalized before calling this function such that the highest set bit in the
63// mantissa has the value 'pow(2, exponent)'.
64//
65// Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
66// calling a templated FPRound.
67template <class T, int ebits, int mbits>
68T FPRound(int64_t sign,
69          int64_t exponent,
70          uint64_t mantissa,
71          FPRounding round_mode) {
72  VIXL_ASSERT((sign == 0) || (sign == 1));
73
74  // Only FPTieEven and FPRoundOdd rounding modes are implemented.
75  VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
76
77  // Rounding can promote subnormals to normals, and normals to infinities. For
78  // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
79  // encodable as a float, but rounding based on the low-order mantissa bits
80  // could make it overflow. With ties-to-even rounding, this value would become
81  // an infinity.
82
83  // ---- Rounding Method ----
84  //
85  // The exponent is irrelevant in the rounding operation, so we treat the
86  // lowest-order bit that will fit into the result ('onebit') as having
87  // the value '1'. Similarly, the highest-order bit that won't fit into
88  // the result ('halfbit') has the value '0.5'. The 'point' sits between
89  // 'onebit' and 'halfbit':
90  //
91  //            These bits fit into the result.
92  //               |---------------------|
93  //  mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
94  //                                     ||
95  //                                    / |
96  //                                   /  halfbit
97  //                               onebit
98  //
99  // For subnormal outputs, the range of representable bits is smaller and
100  // the position of onebit and halfbit depends on the exponent of the
101  // input, but the method is otherwise similar.
102  //
103  //   onebit(frac)
104  //     |
105  //     | halfbit(frac)          halfbit(adjusted)
106  //     | /                      /
107  //     | |                      |
108  //  0b00.0 (exact)      -> 0b00.0 (exact)                    -> 0b00
109  //  0b00.0...           -> 0b00.0...                         -> 0b00
110  //  0b00.1 (exact)      -> 0b00.0111..111                    -> 0b00
111  //  0b00.1...           -> 0b00.1...                         -> 0b01
112  //  0b01.0 (exact)      -> 0b01.0 (exact)                    -> 0b01
113  //  0b01.0...           -> 0b01.0...                         -> 0b01
114  //  0b01.1 (exact)      -> 0b01.1 (exact)                    -> 0b10
115  //  0b01.1...           -> 0b01.1...                         -> 0b10
116  //  0b10.0 (exact)      -> 0b10.0 (exact)                    -> 0b10
117  //  0b10.0...           -> 0b10.0...                         -> 0b10
118  //  0b10.1 (exact)      -> 0b10.0111..111                    -> 0b10
119  //  0b10.1...           -> 0b10.1...                         -> 0b11
120  //  0b11.0 (exact)      -> 0b11.0 (exact)                    -> 0b11
121  //  ...                   /             |                      /   |
122  //                       /              |                     /    |
123  //                                                           /     |
124  // adjusted = frac - (halfbit(mantissa) & ~onebit(frac));   /      |
125  //
126  //                   mantissa = (mantissa >> shift) + halfbit(adjusted);
127
128  static const int mantissa_offset = 0;
129  static const int exponent_offset = mantissa_offset + mbits;
130  static const int sign_offset = exponent_offset + ebits;
131  VIXL_ASSERT(sign_offset == (sizeof(T) * 8 - 1));
132
133  // Bail out early for zero inputs.
134  if (mantissa == 0) {
135    return static_cast<T>(sign << sign_offset);
136  }
137
138  // If all bits in the exponent are set, the value is infinite or NaN.
139  // This is true for all binary IEEE-754 formats.
140  static const int infinite_exponent = (1 << ebits) - 1;
141  static const int max_normal_exponent = infinite_exponent - 1;
142
143  // Apply the exponent bias to encode it for the result. Doing this early makes
144  // it easy to detect values that will be infinite or subnormal.
145  exponent += max_normal_exponent >> 1;
146
147  if (exponent > max_normal_exponent) {
148    // Overflow: the input is too large for the result type to represent.
149    if (round_mode == FPTieEven) {
150      // FPTieEven rounding mode handles overflows using infinities.
151      exponent = infinite_exponent;
152      mantissa = 0;
153    } else {
154      VIXL_ASSERT(round_mode == FPRoundOdd);
155      // FPRoundOdd rounding mode handles overflows using the largest magnitude
156      // normal number.
157      exponent = max_normal_exponent;
158      mantissa = (UINT64_C(1) << exponent_offset) - 1;
159    }
160    return static_cast<T>((sign << sign_offset) |
161                          (exponent << exponent_offset) |
162                          (mantissa << mantissa_offset));
163  }
164
165  // Calculate the shift required to move the top mantissa bit to the proper
166  // place in the destination type.
167  const int highest_significant_bit = 63 - CountLeadingZeros(mantissa);
168  int shift = highest_significant_bit - mbits;
169
170  if (exponent <= 0) {
171    // The output will be subnormal (before rounding).
172    // For subnormal outputs, the shift must be adjusted by the exponent. The +1
173    // is necessary because the exponent of a subnormal value (encoded as 0) is
174    // the same as the exponent of the smallest normal value (encoded as 1).
175    shift += -exponent + 1;
176
177    // Handle inputs that would produce a zero output.
178    //
179    // Shifts higher than highest_significant_bit+1 will always produce a zero
180    // result. A shift of exactly highest_significant_bit+1 might produce a
181    // non-zero result after rounding.
182    if (shift > (highest_significant_bit + 1)) {
183      if (round_mode == FPTieEven) {
184        // The result will always be +/-0.0.
185        return static_cast<T>(sign << sign_offset);
186      } else {
187        VIXL_ASSERT(round_mode == FPRoundOdd);
188        VIXL_ASSERT(mantissa != 0);
189        // For FPRoundOdd, if the mantissa is too small to represent and
190        // non-zero return the next "odd" value.
191        return static_cast<T>((sign << sign_offset) | 1);
192      }
193    }
194
195    // Properly encode the exponent for a subnormal output.
196    exponent = 0;
197  } else {
198    // Clear the topmost mantissa bit, since this is not encoded in IEEE-754
199    // normal values.
200    mantissa &= ~(UINT64_C(1) << highest_significant_bit);
201  }
202
203  if (shift > 0) {
204    if (round_mode == FPTieEven) {
205      // We have to shift the mantissa to the right. Some precision is lost, so
206      // we need to apply rounding.
207      uint64_t onebit_mantissa = (mantissa >> (shift)) & 1;
208      uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1;
209      uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa);
210      uint64_t adjusted = mantissa - adjustment;
211      T halfbit_adjusted = (adjusted >> (shift - 1)) & 1;
212
213      T result =
214          static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) |
215                         ((mantissa >> shift) << mantissa_offset));
216
217      // A very large mantissa can overflow during rounding. If this happens,
218      // the exponent should be incremented and the mantissa set to 1.0
219      // (encoded as 0). Applying halfbit_adjusted after assembling the float
220      // has the nice side-effect that this case is handled for free.
221      //
222      // This also handles cases where a very large finite value overflows to
223      // infinity, or where a very large subnormal value overflows to become
224      // normal.
225      return result + halfbit_adjusted;
226    } else {
227      VIXL_ASSERT(round_mode == FPRoundOdd);
228      // If any bits at position halfbit or below are set, onebit (ie. the
229      // bottom bit of the resulting mantissa) must be set.
230      uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1);
231      if (fractional_bits != 0) {
232        mantissa |= UINT64_C(1) << shift;
233      }
234
235      return static_cast<T>((sign << sign_offset) |
236                            (exponent << exponent_offset) |
237                            ((mantissa >> shift) << mantissa_offset));
238    }
239  } else {
240    // We have to shift the mantissa to the left (or not at all). The input
241    // mantissa is exactly representable in the output mantissa, so apply no
242    // rounding correction.
243    return static_cast<T>((sign << sign_offset) |
244                          (exponent << exponent_offset) |
245                          ((mantissa << -shift) << mantissa_offset));
246  }
247}
248
249
250// Representation of memory, with typed getters and setters for access.
251class Memory {
252 public:
253  template <typename T>
254  static T AddressUntag(T address) {
255    // Cast the address using a C-style cast. A reinterpret_cast would be
256    // appropriate, but it can't cast one integral type to another.
257    uint64_t bits = (uint64_t)address;
258    return (T)(bits & ~kAddressTagMask);
259  }
260
261  template <typename T, typename A>
262  static T Read(A address) {
263    T value;
264    address = AddressUntag(address);
265    VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
266                (sizeof(value) == 4) || (sizeof(value) == 8) ||
267                (sizeof(value) == 16));
268    memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
269    return value;
270  }
271
272  template <typename T, typename A>
273  static void Write(A address, T value) {
274    address = AddressUntag(address);
275    VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
276                (sizeof(value) == 4) || (sizeof(value) == 8) ||
277                (sizeof(value) == 16));
278    memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
279  }
280};
281
282// Represent a register (r0-r31, v0-v31).
283template <int kSizeInBytes>
284class SimRegisterBase {
285 public:
286  SimRegisterBase() : written_since_last_log_(false) {}
287
288  // Write the specified value. The value is zero-extended if necessary.
289  template <typename T>
290  void Write(T new_value) {
291    VIXL_STATIC_ASSERT(sizeof(new_value) <= kSizeInBytes);
292    if (sizeof(new_value) < kSizeInBytes) {
293      // All AArch64 registers are zero-extending.
294      memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value));
295    }
296    memcpy(value_, &new_value, sizeof(new_value));
297    NotifyRegisterWrite();
298  }
299  template <typename T>
300  VIXL_DEPRECATED("Write", void Set(T new_value)) {
301    Write(new_value);
302  }
303
304  // Insert a typed value into a register, leaving the rest of the register
305  // unchanged. The lane parameter indicates where in the register the value
306  // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
307  // 0 represents the least significant bits.
308  template <typename T>
309  void Insert(int lane, T new_value) {
310    VIXL_ASSERT(lane >= 0);
311    VIXL_ASSERT((sizeof(new_value) + (lane * sizeof(new_value))) <=
312                kSizeInBytes);
313    memcpy(&value_[lane * sizeof(new_value)], &new_value, sizeof(new_value));
314    NotifyRegisterWrite();
315  }
316
317  // Get the value as the specified type. The value is truncated if necessary.
318  template <typename T>
319  T Get() const {
320    return GetLane<T>(0);
321  }
322
323  // Get the lane value as the specified type. The value is truncated if
324  // necessary.
325  template <typename T>
326  T GetLane(int lane) const {
327    T result;
328    VIXL_ASSERT(lane >= 0);
329    VIXL_ASSERT((sizeof(result) + (lane * sizeof(result))) <= kSizeInBytes);
330    memcpy(&result, &value_[lane * sizeof(result)], sizeof(result));
331    return result;
332  }
333  template <typename T>
334  VIXL_DEPRECATED("GetLane", T Get(int lane) const) {
335    return GetLane(lane);
336  }
337
338  // TODO: Make this return a map of updated bytes, so that we can highlight
339  // updated lanes for load-and-insert. (That never happens for scalar code, but
340  // NEON has some instructions that can update individual lanes.)
341  bool WrittenSinceLastLog() const { return written_since_last_log_; }
342
343  void NotifyRegisterLogged() { written_since_last_log_ = false; }
344
345 protected:
346  uint8_t value_[kSizeInBytes];
347
348  // Helpers to aid with register tracing.
349  bool written_since_last_log_;
350
351  void NotifyRegisterWrite() { written_since_last_log_ = true; }
352};
353typedef SimRegisterBase<kXRegSizeInBytes> SimRegister;   // r0-r31
354typedef SimRegisterBase<kQRegSizeInBytes> SimVRegister;  // v0-v31
355
356// Representation of a vector register, with typed getters and setters for lanes
357// and additional information to represent lane state.
358class LogicVRegister {
359 public:
360  inline LogicVRegister(SimVRegister& other)  // NOLINT
361      : register_(other) {
362    for (unsigned i = 0; i < sizeof(saturated_) / sizeof(saturated_[0]); i++) {
363      saturated_[i] = kNotSaturated;
364    }
365    for (unsigned i = 0; i < sizeof(round_) / sizeof(round_[0]); i++) {
366      round_[i] = 0;
367    }
368  }
369
370  int64_t Int(VectorFormat vform, int index) const {
371    int64_t element;
372    switch (LaneSizeInBitsFromFormat(vform)) {
373      case 8:
374        element = register_.GetLane<int8_t>(index);
375        break;
376      case 16:
377        element = register_.GetLane<int16_t>(index);
378        break;
379      case 32:
380        element = register_.GetLane<int32_t>(index);
381        break;
382      case 64:
383        element = register_.GetLane<int64_t>(index);
384        break;
385      default:
386        VIXL_UNREACHABLE();
387        return 0;
388    }
389    return element;
390  }
391
392  uint64_t Uint(VectorFormat vform, int index) const {
393    uint64_t element;
394    switch (LaneSizeInBitsFromFormat(vform)) {
395      case 8:
396        element = register_.GetLane<uint8_t>(index);
397        break;
398      case 16:
399        element = register_.GetLane<uint16_t>(index);
400        break;
401      case 32:
402        element = register_.GetLane<uint32_t>(index);
403        break;
404      case 64:
405        element = register_.GetLane<uint64_t>(index);
406        break;
407      default:
408        VIXL_UNREACHABLE();
409        return 0;
410    }
411    return element;
412  }
413
414  int64_t IntLeftJustified(VectorFormat vform, int index) const {
415    return Int(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
416  }
417
418  uint64_t UintLeftJustified(VectorFormat vform, int index) const {
419    return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
420  }
421
422  void SetInt(VectorFormat vform, int index, int64_t value) const {
423    switch (LaneSizeInBitsFromFormat(vform)) {
424      case 8:
425        register_.Insert(index, static_cast<int8_t>(value));
426        break;
427      case 16:
428        register_.Insert(index, static_cast<int16_t>(value));
429        break;
430      case 32:
431        register_.Insert(index, static_cast<int32_t>(value));
432        break;
433      case 64:
434        register_.Insert(index, static_cast<int64_t>(value));
435        break;
436      default:
437        VIXL_UNREACHABLE();
438        return;
439    }
440  }
441
442  void SetUint(VectorFormat vform, int index, uint64_t value) const {
443    switch (LaneSizeInBitsFromFormat(vform)) {
444      case 8:
445        register_.Insert(index, static_cast<uint8_t>(value));
446        break;
447      case 16:
448        register_.Insert(index, static_cast<uint16_t>(value));
449        break;
450      case 32:
451        register_.Insert(index, static_cast<uint32_t>(value));
452        break;
453      case 64:
454        register_.Insert(index, static_cast<uint64_t>(value));
455        break;
456      default:
457        VIXL_UNREACHABLE();
458        return;
459    }
460  }
461
462  void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const {
463    switch (LaneSizeInBitsFromFormat(vform)) {
464      case 8:
465        register_.Insert(index, Memory::Read<uint8_t>(addr));
466        break;
467      case 16:
468        register_.Insert(index, Memory::Read<uint16_t>(addr));
469        break;
470      case 32:
471        register_.Insert(index, Memory::Read<uint32_t>(addr));
472        break;
473      case 64:
474        register_.Insert(index, Memory::Read<uint64_t>(addr));
475        break;
476      default:
477        VIXL_UNREACHABLE();
478        return;
479    }
480  }
481
482  void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const {
483    uint64_t value = Uint(vform, index);
484    switch (LaneSizeInBitsFromFormat(vform)) {
485      case 8:
486        Memory::Write(addr, static_cast<uint8_t>(value));
487        break;
488      case 16:
489        Memory::Write(addr, static_cast<uint16_t>(value));
490        break;
491      case 32:
492        Memory::Write(addr, static_cast<uint32_t>(value));
493        break;
494      case 64:
495        Memory::Write(addr, value);
496        break;
497    }
498  }
499
500  template <typename T>
501  T Float(int index) const {
502    return register_.GetLane<T>(index);
503  }
504
505  template <typename T>
506  void SetFloat(int index, T value) const {
507    register_.Insert(index, value);
508  }
509
510  // When setting a result in a register of size less than Q, the top bits of
511  // the Q register must be cleared.
512  void ClearForWrite(VectorFormat vform) const {
513    unsigned size = RegisterSizeInBytesFromFormat(vform);
514    for (unsigned i = size; i < kQRegSizeInBytes; i++) {
515      SetUint(kFormat16B, i, 0);
516    }
517  }
518
519  // Saturation state for each lane of a vector.
520  enum Saturation {
521    kNotSaturated = 0,
522    kSignedSatPositive = 1 << 0,
523    kSignedSatNegative = 1 << 1,
524    kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
525    kSignedSatUndefined = kSignedSatMask,
526    kUnsignedSatPositive = 1 << 2,
527    kUnsignedSatNegative = 1 << 3,
528    kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
529    kUnsignedSatUndefined = kUnsignedSatMask
530  };
531
532  // Getters for saturation state.
533  Saturation GetSignedSaturation(int index) {
534    return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
535  }
536
537  Saturation GetUnsignedSaturation(int index) {
538    return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
539  }
540
541  // Setters for saturation state.
542  void ClearSat(int index) { saturated_[index] = kNotSaturated; }
543
544  void SetSignedSat(int index, bool positive) {
545    SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
546  }
547
548  void SetUnsignedSat(int index, bool positive) {
549    SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
550  }
551
552  void SetSatFlag(int index, Saturation sat) {
553    saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
554    VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined);
555    VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined);
556  }
557
558  // Saturate lanes of a vector based on saturation state.
559  LogicVRegister& SignedSaturate(VectorFormat vform) {
560    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
561      Saturation sat = GetSignedSaturation(i);
562      if (sat == kSignedSatPositive) {
563        SetInt(vform, i, MaxIntFromFormat(vform));
564      } else if (sat == kSignedSatNegative) {
565        SetInt(vform, i, MinIntFromFormat(vform));
566      }
567    }
568    return *this;
569  }
570
571  LogicVRegister& UnsignedSaturate(VectorFormat vform) {
572    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
573      Saturation sat = GetUnsignedSaturation(i);
574      if (sat == kUnsignedSatPositive) {
575        SetUint(vform, i, MaxUintFromFormat(vform));
576      } else if (sat == kUnsignedSatNegative) {
577        SetUint(vform, i, 0);
578      }
579    }
580    return *this;
581  }
582
583  // Getter for rounding state.
584  bool GetRounding(int index) { return round_[index]; }
585
586  // Setter for rounding state.
587  void SetRounding(int index, bool round) { round_[index] = round; }
588
589  // Round lanes of a vector based on rounding state.
590  LogicVRegister& Round(VectorFormat vform) {
591    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
592      SetInt(vform, i, Int(vform, i) + (GetRounding(i) ? 1 : 0));
593    }
594    return *this;
595  }
596
597  // Unsigned halve lanes of a vector, and use the saturation state to set the
598  // top bit.
599  LogicVRegister& Uhalve(VectorFormat vform) {
600    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
601      uint64_t val = Uint(vform, i);
602      SetRounding(i, (val & 1) == 1);
603      val >>= 1;
604      if (GetUnsignedSaturation(i) != kNotSaturated) {
605        // If the operation causes unsigned saturation, the bit shifted into the
606        // most significant bit must be set.
607        val |= (MaxUintFromFormat(vform) >> 1) + 1;
608      }
609      SetInt(vform, i, val);
610    }
611    return *this;
612  }
613
614  // Signed halve lanes of a vector, and use the carry state to set the top bit.
615  LogicVRegister& Halve(VectorFormat vform) {
616    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
617      int64_t val = Int(vform, i);
618      SetRounding(i, (val & 1) == 1);
619      val >>= 1;
620      if (GetSignedSaturation(i) != kNotSaturated) {
621        // If the operation causes signed saturation, the sign bit must be
622        // inverted.
623        val ^= (MaxUintFromFormat(vform) >> 1) + 1;
624      }
625      SetInt(vform, i, val);
626    }
627    return *this;
628  }
629
630 private:
631  SimVRegister& register_;
632
633  // Allocate one saturation state entry per lane; largest register is type Q,
634  // and lanes can be a minimum of one byte wide.
635  Saturation saturated_[kQRegSizeInBytes];
636
637  // Allocate one rounding state entry per lane.
638  bool round_[kQRegSizeInBytes];
639};
640
641// The proper way to initialize a simulated system register (such as NZCV) is as
642// follows:
643//  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
644class SimSystemRegister {
645 public:
646  // The default constructor represents a register which has no writable bits.
647  // It is not possible to set its value to anything other than 0.
648  SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
649
650  uint32_t GetRawValue() const { return value_; }
651  VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) {
652    return GetRawValue();
653  }
654
655  void SetRawValue(uint32_t new_value) {
656    value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
657  }
658
659  uint32_t ExtractBits(int msb, int lsb) const {
660    return ExtractUnsignedBitfield32(msb, lsb, value_);
661  }
662  VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) {
663    return ExtractBits(msb, lsb);
664  }
665
666  int32_t ExtractSignedBits(int msb, int lsb) const {
667    return ExtractSignedBitfield32(msb, lsb, value_);
668  }
669  VIXL_DEPRECATED("ExtractSignedBits",
670                  int32_t SignedBits(int msb, int lsb) const) {
671    return ExtractSignedBits(msb, lsb);
672  }
673
674  void SetBits(int msb, int lsb, uint32_t bits);
675
676  // Default system register values.
677  static SimSystemRegister DefaultValueFor(SystemRegister id);
678
679#define DEFINE_GETTER(Name, HighBit, LowBit, Func)                            \
680  uint32_t Get##Name() const { return this->Func(HighBit, LowBit); }          \
681  VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \
682  void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); }
683#define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
684  static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
685
686  SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
687
688#undef DEFINE_ZERO_BITS
689#undef DEFINE_GETTER
690
691 protected:
692  // Most system registers only implement a few of the bits in the word. Other
693  // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
694  // describes the bits which are not modifiable.
695  SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
696      : value_(value), write_ignore_mask_(write_ignore_mask) {}
697
698  uint32_t value_;
699  uint32_t write_ignore_mask_;
700};
701
702
703class SimExclusiveLocalMonitor {
704 public:
705  SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) {
706    Clear();
707  }
708
709  // Clear the exclusive monitor (like clrex).
710  void Clear() {
711    address_ = 0;
712    size_ = 0;
713  }
714
715  // Clear the exclusive monitor most of the time.
716  void MaybeClear() {
717    if ((seed_ % kSkipClearProbability) != 0) {
718      Clear();
719    }
720
721    // Advance seed_ using a simple linear congruential generator.
722    seed_ = (seed_ * 48271) % 2147483647;
723  }
724
725  // Mark the address range for exclusive access (like load-exclusive).
726  void MarkExclusive(uint64_t address, size_t size) {
727    address_ = address;
728    size_ = size;
729  }
730
731  // Return true if the address range is marked (like store-exclusive).
732  // This helper doesn't implicitly clear the monitor.
733  bool IsExclusive(uint64_t address, size_t size) {
734    VIXL_ASSERT(size > 0);
735    // Be pedantic: Require both the address and the size to match.
736    return (size == size_) && (address == address_);
737  }
738
739 private:
740  uint64_t address_;
741  size_t size_;
742
743  const int kSkipClearProbability;
744  uint32_t seed_;
745};
746
747
748// We can't accurate simulate the global monitor since it depends on external
749// influences. Instead, this implementation occasionally causes accesses to
750// fail, according to kPassProbability.
751class SimExclusiveGlobalMonitor {
752 public:
753  SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {}
754
755  bool IsExclusive(uint64_t address, size_t size) {
756    USE(address, size);
757
758    bool pass = (seed_ % kPassProbability) != 0;
759    // Advance seed_ using a simple linear congruential generator.
760    seed_ = (seed_ * 48271) % 2147483647;
761    return pass;
762  }
763
764 private:
765  const int kPassProbability;
766  uint32_t seed_;
767};
768
769
770class Simulator : public DecoderVisitor {
771 public:
772  explicit Simulator(Decoder* decoder, FILE* stream = stdout);
773  ~Simulator();
774
775  void ResetState();
776
777  // Run the simulator.
778  virtual void Run();
779  void RunFrom(const Instruction* first);
780
781  // Execution ends when the PC hits this address.
782  static const Instruction* kEndOfSimAddress;
783
784  // Simulation helpers.
785  const Instruction* ReadPc() const { return pc_; }
786  VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
787
788  void WritePc(const Instruction* new_pc) {
789    pc_ = Memory::AddressUntag(new_pc);
790    pc_modified_ = true;
791  }
792  VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) {
793    return WritePc(new_pc);
794  }
795
796  void IncrementPc() {
797    if (!pc_modified_) {
798      pc_ = pc_->GetNextInstruction();
799    }
800  }
801  VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); }
802
803  void ExecuteInstruction() {
804    // The program counter should always be aligned.
805    VIXL_ASSERT(IsWordAligned(pc_));
806    pc_modified_ = false;
807    decoder_->Decode(pc_);
808    IncrementPc();
809    LogAllWrittenRegisters();
810  }
811
812// Declare all Visitor functions.
813#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
814  VISITOR_LIST_THAT_RETURN(DECLARE)
815#undef DECLARE
816
817#define DECLARE(A) \
818  VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr);
819  VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
820#undef DECLARE
821
822
823  // Integer register accessors.
824
825  // Basic accessor: Read the register as the specified type.
826  template <typename T>
827  T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
828    VIXL_ASSERT(
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#if defined(VIXL_ABI_SUPPORT) && __cplusplus >= 201103L
1622
1623#define VIXL_SIMULATED_RUNTIME_CALL_SUPPORT
1624
1625// The implementation of the runtime call helpers require the functionality
1626// provided by `std::index_sequence`. It is only available from C++14, but
1627// we want runtime call simulation to work from C++11, so we emulate if
1628// necessary.
1629#if __cplusplus >= 201402L
1630  template <std::size_t... I>
1631  using local_index_sequence = std::index_sequence<I...>;
1632  template <typename... P>
1633  using __local_index_sequence_for = std::index_sequence_for<P...>;
1634#else
1635  // Emulate the behaviour of `std::index_sequence` and
1636  // `std::index_sequence_for`.
1637  // Naming follow the `std` names, prefixed with `emulated_`.
1638  template <size_t... I>
1639  struct emulated_index_sequence {};
1640
1641  // A recursive template to create a sequence of indexes.
1642  // The base case (for `N == 0`) is declared outside of the class scope, as
1643  // required by C++.
1644  template <std::size_t N, size_t... I>
1645  struct emulated_make_index_sequence_helper
1646      : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
1647
1648  template <std::size_t N>
1649  struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
1650  };
1651
1652  template <typename... P>
1653  struct emulated_index_sequence_for
1654      : emulated_make_index_sequence<sizeof...(P)> {};
1655
1656  template <std::size_t... I>
1657  using local_index_sequence = emulated_index_sequence<I...>;
1658  template <typename... P>
1659  using __local_index_sequence_for = emulated_index_sequence_for<P...>;
1660#endif
1661
1662  // Expand the argument tuple and perform the call.
1663  template <typename R, typename... P, std::size_t... I>
1664  R DoRuntimeCall(R (*function)(P...),
1665                  std::tuple<P...> arguments,
1666                  local_index_sequence<I...>) {
1667    return function(std::get<I>(arguments)...);
1668  }
1669
1670  template <typename R, typename... P>
1671  void RuntimeCallNonVoid(R (*function)(P...)) {
1672    ABI abi;
1673    std::tuple<P...> argument_operands{
1674        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1675    R return_value = DoRuntimeCall(function,
1676                                   argument_operands,
1677                                   __local_index_sequence_for<P...>{});
1678    WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
1679  }
1680
1681  template <typename R, typename... P>
1682  void RuntimeCallVoid(R (*function)(P...)) {
1683    ABI abi;
1684    std::tuple<P...> argument_operands{
1685        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1686    DoRuntimeCall(function,
1687                  argument_operands,
1688                  __local_index_sequence_for<P...>{});
1689  }
1690
1691  // We use `struct` for `void` return type specialisation.
1692  template <typename R, typename... P>
1693  struct RuntimeCallStructHelper {
1694    static void Wrapper(Simulator* simulator, void* function_pointer) {
1695      R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
1696      simulator->RuntimeCallNonVoid(function);
1697    }
1698  };
1699
1700  // Partial specialization when the return type is `void`.
1701  template <typename... P>
1702  struct RuntimeCallStructHelper<void, P...> {
1703    static void Wrapper(Simulator* simulator, void* function_pointer) {
1704      void (*function)(P...) =
1705          reinterpret_cast<void (*)(P...)>(function_pointer);
1706      simulator->RuntimeCallVoid(function);
1707    }
1708  };
1709#endif
1710
1711 protected:
1712  const char* clr_normal;
1713  const char* clr_flag_name;
1714  const char* clr_flag_value;
1715  const char* clr_reg_name;
1716  const char* clr_reg_value;
1717  const char* clr_vreg_name;
1718  const char* clr_vreg_value;
1719  const char* clr_memory_address;
1720  const char* clr_warning;
1721  const char* clr_warning_message;
1722  const char* clr_printf;
1723
1724  // Simulation helpers ------------------------------------
1725  bool ConditionPassed(Condition cond) {
1726    switch (cond) {
1727      case eq:
1728        return ReadZ();
1729      case ne:
1730        return !ReadZ();
1731      case hs:
1732        return ReadC();
1733      case lo:
1734        return !ReadC();
1735      case mi:
1736        return ReadN();
1737      case pl:
1738        return !ReadN();
1739      case vs:
1740        return ReadV();
1741      case vc:
1742        return !ReadV();
1743      case hi:
1744        return ReadC() && !ReadZ();
1745      case ls:
1746        return !(ReadC() && !ReadZ());
1747      case ge:
1748        return ReadN() == ReadV();
1749      case lt:
1750        return ReadN() != ReadV();
1751      case gt:
1752        return !ReadZ() && (ReadN() == ReadV());
1753      case le:
1754        return !(!ReadZ() && (ReadN() == ReadV()));
1755      case nv:
1756        VIXL_FALLTHROUGH();
1757      case al:
1758        return true;
1759      default:
1760        VIXL_UNREACHABLE();
1761        return false;
1762    }
1763  }
1764
1765  bool ConditionPassed(Instr cond) {
1766    return ConditionPassed(static_cast<Condition>(cond));
1767  }
1768
1769  bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1770
1771  void AddSubHelper(const Instruction* instr, int64_t op2);
1772  uint64_t AddWithCarry(unsigned reg_size,
1773                        bool set_flags,
1774                        uint64_t left,
1775                        uint64_t right,
1776                        int carry_in = 0);
1777  void LogicalHelper(const Instruction* instr, int64_t op2);
1778  void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
1779  void LoadStoreHelper(const Instruction* instr,
1780                       int64_t offset,
1781                       AddrMode addrmode);
1782  void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
1783  uintptr_t AddressModeHelper(unsigned addr_reg,
1784                              int64_t offset,
1785                              AddrMode addrmode);
1786  void NEONLoadStoreMultiStructHelper(const Instruction* instr,
1787                                      AddrMode addr_mode);
1788  void NEONLoadStoreSingleStructHelper(const Instruction* instr,
1789                                       AddrMode addr_mode);
1790
1791  uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; }
1792
1793  template <typename T>
1794  T* AddressUntag(T* address) {
1795    uintptr_t address_raw = reinterpret_cast<uintptr_t>(address);
1796    return reinterpret_cast<T*>(AddressUntag(address_raw));
1797  }
1798
1799  int64_t ShiftOperand(unsigned reg_size,
1800                       int64_t value,
1801                       Shift shift_type,
1802                       unsigned amount) const;
1803  int64_t ExtendValue(unsigned reg_width,
1804                      int64_t value,
1805                      Extend extend_type,
1806                      unsigned left_shift = 0) const;
1807  uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const;
1808
1809  void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1810  void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
1811  void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1812  void ld2(VectorFormat vform,
1813           LogicVRegister dst1,
1814           LogicVRegister dst2,
1815           uint64_t addr);
1816  void ld2(VectorFormat vform,
1817           LogicVRegister dst1,
1818           LogicVRegister dst2,
1819           int index,
1820           uint64_t addr);
1821  void ld2r(VectorFormat vform,
1822            LogicVRegister dst1,
1823            LogicVRegister dst2,
1824            uint64_t addr);
1825  void ld3(VectorFormat vform,
1826           LogicVRegister dst1,
1827           LogicVRegister dst2,
1828           LogicVRegister dst3,
1829           uint64_t addr);
1830  void ld3(VectorFormat vform,
1831           LogicVRegister dst1,
1832           LogicVRegister dst2,
1833           LogicVRegister dst3,
1834           int index,
1835           uint64_t addr);
1836  void ld3r(VectorFormat vform,
1837            LogicVRegister dst1,
1838            LogicVRegister dst2,
1839            LogicVRegister dst3,
1840            uint64_t addr);
1841  void ld4(VectorFormat vform,
1842           LogicVRegister dst1,
1843           LogicVRegister dst2,
1844           LogicVRegister dst3,
1845           LogicVRegister dst4,
1846           uint64_t addr);
1847  void ld4(VectorFormat vform,
1848           LogicVRegister dst1,
1849           LogicVRegister dst2,
1850           LogicVRegister dst3,
1851           LogicVRegister dst4,
1852           int index,
1853           uint64_t addr);
1854  void ld4r(VectorFormat vform,
1855            LogicVRegister dst1,
1856            LogicVRegister dst2,
1857            LogicVRegister dst3,
1858            LogicVRegister dst4,
1859            uint64_t addr);
1860  void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
1861  void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
1862  void st2(VectorFormat vform,
1863           LogicVRegister src,
1864           LogicVRegister src2,
1865           uint64_t addr);
1866  void st2(VectorFormat vform,
1867           LogicVRegister src,
1868           LogicVRegister src2,
1869           int index,
1870           uint64_t addr);
1871  void st3(VectorFormat vform,
1872           LogicVRegister src,
1873           LogicVRegister src2,
1874           LogicVRegister src3,
1875           uint64_t addr);
1876  void st3(VectorFormat vform,
1877           LogicVRegister src,
1878           LogicVRegister src2,
1879           LogicVRegister src3,
1880           int index,
1881           uint64_t addr);
1882  void st4(VectorFormat vform,
1883           LogicVRegister src,
1884           LogicVRegister src2,
1885           LogicVRegister src3,
1886           LogicVRegister src4,
1887           uint64_t addr);
1888  void st4(VectorFormat vform,
1889           LogicVRegister src,
1890           LogicVRegister src2,
1891           LogicVRegister src3,
1892           LogicVRegister src4,
1893           int index,
1894           uint64_t addr);
1895  LogicVRegister cmp(VectorFormat vform,
1896                     LogicVRegister dst,
1897                     const LogicVRegister& src1,
1898                     const LogicVRegister& src2,
1899                     Condition cond);
1900  LogicVRegister cmp(VectorFormat vform,
1901                     LogicVRegister dst,
1902                     const LogicVRegister& src1,
1903                     int imm,
1904                     Condition cond);
1905  LogicVRegister cmptst(VectorFormat vform,
1906                        LogicVRegister dst,
1907                        const LogicVRegister& src1,
1908                        const LogicVRegister& src2);
1909  LogicVRegister add(VectorFormat vform,
1910                     LogicVRegister dst,
1911                     const LogicVRegister& src1,
1912                     const LogicVRegister& src2);
1913  LogicVRegister addp(VectorFormat vform,
1914                      LogicVRegister dst,
1915                      const LogicVRegister& src1,
1916                      const LogicVRegister& src2);
1917  LogicVRegister mla(VectorFormat vform,
1918                     LogicVRegister dst,
1919                     const LogicVRegister& src1,
1920                     const LogicVRegister& src2);
1921  LogicVRegister mls(VectorFormat vform,
1922                     LogicVRegister dst,
1923                     const LogicVRegister& src1,
1924                     const LogicVRegister& src2);
1925  LogicVRegister mul(VectorFormat vform,
1926                     LogicVRegister dst,
1927                     const LogicVRegister& src1,
1928                     const LogicVRegister& src2);
1929  LogicVRegister mul(VectorFormat vform,
1930                     LogicVRegister dst,
1931                     const LogicVRegister& src1,
1932                     const LogicVRegister& src2,
1933                     int index);
1934  LogicVRegister mla(VectorFormat vform,
1935                     LogicVRegister dst,
1936                     const LogicVRegister& src1,
1937                     const LogicVRegister& src2,
1938                     int index);
1939  LogicVRegister mls(VectorFormat vform,
1940                     LogicVRegister dst,
1941                     const LogicVRegister& src1,
1942                     const LogicVRegister& src2,
1943                     int index);
1944  LogicVRegister pmul(VectorFormat vform,
1945                      LogicVRegister dst,
1946                      const LogicVRegister& src1,
1947                      const LogicVRegister& src2);
1948
1949  typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
1950                                                   LogicVRegister dst,
1951                                                   const LogicVRegister& src1,
1952                                                   const LogicVRegister& src2,
1953                                                   int index);
1954  LogicVRegister fmul(VectorFormat vform,
1955                      LogicVRegister dst,
1956                      const LogicVRegister& src1,
1957                      const LogicVRegister& src2,
1958                      int index);
1959  LogicVRegister fmla(VectorFormat vform,
1960                      LogicVRegister dst,
1961                      const LogicVRegister& src1,
1962                      const LogicVRegister& src2,
1963                      int index);
1964  LogicVRegister fmls(VectorFormat vform,
1965                      LogicVRegister dst,
1966                      const LogicVRegister& src1,
1967                      const LogicVRegister& src2,
1968                      int index);
1969  LogicVRegister fmulx(VectorFormat vform,
1970                       LogicVRegister dst,
1971                       const LogicVRegister& src1,
1972                       const LogicVRegister& src2,
1973                       int index);
1974  LogicVRegister smull(VectorFormat vform,
1975                       LogicVRegister dst,
1976                       const LogicVRegister& src1,
1977                       const LogicVRegister& src2,
1978                       int index);
1979  LogicVRegister smull2(VectorFormat vform,
1980                        LogicVRegister dst,
1981                        const LogicVRegister& src1,
1982                        const LogicVRegister& src2,
1983                        int index);
1984  LogicVRegister umull(VectorFormat vform,
1985                       LogicVRegister dst,
1986                       const LogicVRegister& src1,
1987                       const LogicVRegister& src2,
1988                       int index);
1989  LogicVRegister umull2(VectorFormat vform,
1990                        LogicVRegister dst,
1991                        const LogicVRegister& src1,
1992                        const LogicVRegister& src2,
1993                        int index);
1994  LogicVRegister smlal(VectorFormat vform,
1995                       LogicVRegister dst,
1996                       const LogicVRegister& src1,
1997                       const LogicVRegister& src2,
1998                       int index);
1999  LogicVRegister smlal2(VectorFormat vform,
2000                        LogicVRegister dst,
2001                        const LogicVRegister& src1,
2002                        const LogicVRegister& src2,
2003                        int index);
2004  LogicVRegister umlal(VectorFormat vform,
2005                       LogicVRegister dst,
2006                       const LogicVRegister& src1,
2007                       const LogicVRegister& src2,
2008                       int index);
2009  LogicVRegister umlal2(VectorFormat vform,
2010                        LogicVRegister dst,
2011                        const LogicVRegister& src1,
2012                        const LogicVRegister& src2,
2013                        int index);
2014  LogicVRegister smlsl(VectorFormat vform,
2015                       LogicVRegister dst,
2016                       const LogicVRegister& src1,
2017                       const LogicVRegister& src2,
2018                       int index);
2019  LogicVRegister smlsl2(VectorFormat vform,
2020                        LogicVRegister dst,
2021                        const LogicVRegister& src1,
2022                        const LogicVRegister& src2,
2023                        int index);
2024  LogicVRegister umlsl(VectorFormat vform,
2025                       LogicVRegister dst,
2026                       const LogicVRegister& src1,
2027                       const LogicVRegister& src2,
2028                       int index);
2029  LogicVRegister umlsl2(VectorFormat vform,
2030                        LogicVRegister dst,
2031                        const LogicVRegister& src1,
2032                        const LogicVRegister& src2,
2033                        int index);
2034  LogicVRegister sqdmull(VectorFormat vform,
2035                         LogicVRegister dst,
2036                         const LogicVRegister& src1,
2037                         const LogicVRegister& src2,
2038                         int index);
2039  LogicVRegister sqdmull2(VectorFormat vform,
2040                          LogicVRegister dst,
2041                          const LogicVRegister& src1,
2042                          const LogicVRegister& src2,
2043                          int index);
2044  LogicVRegister sqdmlal(VectorFormat vform,
2045                         LogicVRegister dst,
2046                         const LogicVRegister& src1,
2047                         const LogicVRegister& src2,
2048                         int index);
2049  LogicVRegister sqdmlal2(VectorFormat vform,
2050                          LogicVRegister dst,
2051                          const LogicVRegister& src1,
2052                          const LogicVRegister& src2,
2053                          int index);
2054  LogicVRegister sqdmlsl(VectorFormat vform,
2055                         LogicVRegister dst,
2056                         const LogicVRegister& src1,
2057                         const LogicVRegister& src2,
2058                         int index);
2059  LogicVRegister sqdmlsl2(VectorFormat vform,
2060                          LogicVRegister dst,
2061                          const LogicVRegister& src1,
2062                          const LogicVRegister& src2,
2063                          int index);
2064  LogicVRegister sqdmulh(VectorFormat vform,
2065                         LogicVRegister dst,
2066                         const LogicVRegister& src1,
2067                         const LogicVRegister& src2,
2068                         int index);
2069  LogicVRegister sqrdmulh(VectorFormat vform,
2070                          LogicVRegister dst,
2071                          const LogicVRegister& src1,
2072                          const LogicVRegister& src2,
2073                          int index);
2074  LogicVRegister sub(VectorFormat vform,
2075                     LogicVRegister dst,
2076                     const LogicVRegister& src1,
2077                     const LogicVRegister& src2);
2078  LogicVRegister and_(VectorFormat vform,
2079                      LogicVRegister dst,
2080                      const LogicVRegister& src1,
2081                      const LogicVRegister& src2);
2082  LogicVRegister orr(VectorFormat vform,
2083                     LogicVRegister dst,
2084                     const LogicVRegister& src1,
2085                     const LogicVRegister& src2);
2086  LogicVRegister orn(VectorFormat vform,
2087                     LogicVRegister dst,
2088                     const LogicVRegister& src1,
2089                     const LogicVRegister& src2);
2090  LogicVRegister eor(VectorFormat vform,
2091                     LogicVRegister dst,
2092                     const LogicVRegister& src1,
2093                     const LogicVRegister& src2);
2094  LogicVRegister bic(VectorFormat vform,
2095                     LogicVRegister dst,
2096                     const LogicVRegister& src1,
2097                     const LogicVRegister& src2);
2098  LogicVRegister bic(VectorFormat vform,
2099                     LogicVRegister dst,
2100                     const LogicVRegister& src,
2101                     uint64_t imm);
2102  LogicVRegister bif(VectorFormat vform,
2103                     LogicVRegister dst,
2104                     const LogicVRegister& src1,
2105                     const LogicVRegister& src2);
2106  LogicVRegister bit(VectorFormat vform,
2107                     LogicVRegister dst,
2108                     const LogicVRegister& src1,
2109                     const LogicVRegister& src2);
2110  LogicVRegister bsl(VectorFormat vform,
2111                     LogicVRegister dst,
2112                     const LogicVRegister& src1,
2113                     const LogicVRegister& src2);
2114  LogicVRegister cls(VectorFormat vform,
2115                     LogicVRegister dst,
2116                     const LogicVRegister& src);
2117  LogicVRegister clz(VectorFormat vform,
2118                     LogicVRegister dst,
2119                     const LogicVRegister& src);
2120  LogicVRegister cnt(VectorFormat vform,
2121                     LogicVRegister dst,
2122                     const LogicVRegister& src);
2123  LogicVRegister not_(VectorFormat vform,
2124                      LogicVRegister dst,
2125                      const LogicVRegister& src);
2126  LogicVRegister rbit(VectorFormat vform,
2127                      LogicVRegister dst,
2128                      const LogicVRegister& src);
2129  LogicVRegister rev(VectorFormat vform,
2130                     LogicVRegister dst,
2131                     const LogicVRegister& src,
2132                     int revSize);
2133  LogicVRegister rev16(VectorFormat vform,
2134                       LogicVRegister dst,
2135                       const LogicVRegister& src);
2136  LogicVRegister rev32(VectorFormat vform,
2137                       LogicVRegister dst,
2138                       const LogicVRegister& src);
2139  LogicVRegister rev64(VectorFormat vform,
2140                       LogicVRegister dst,
2141                       const LogicVRegister& src);
2142  LogicVRegister addlp(VectorFormat vform,
2143                       LogicVRegister dst,
2144                       const LogicVRegister& src,
2145                       bool is_signed,
2146                       bool do_accumulate);
2147  LogicVRegister saddlp(VectorFormat vform,
2148                        LogicVRegister dst,
2149                        const LogicVRegister& src);
2150  LogicVRegister uaddlp(VectorFormat vform,
2151                        LogicVRegister dst,
2152                        const LogicVRegister& src);
2153  LogicVRegister sadalp(VectorFormat vform,
2154                        LogicVRegister dst,
2155                        const LogicVRegister& src);
2156  LogicVRegister uadalp(VectorFormat vform,
2157                        LogicVRegister dst,
2158                        const LogicVRegister& src);
2159  LogicVRegister ext(VectorFormat vform,
2160                     LogicVRegister dst,
2161                     const LogicVRegister& src1,
2162                     const LogicVRegister& src2,
2163                     int index);
2164  LogicVRegister ins_element(VectorFormat vform,
2165                             LogicVRegister dst,
2166                             int dst_index,
2167                             const LogicVRegister& src,
2168                             int src_index);
2169  LogicVRegister ins_immediate(VectorFormat vform,
2170                               LogicVRegister dst,
2171                               int dst_index,
2172                               uint64_t imm);
2173  LogicVRegister dup_element(VectorFormat vform,
2174                             LogicVRegister dst,
2175                             const LogicVRegister& src,
2176                             int src_index);
2177  LogicVRegister dup_immediate(VectorFormat vform,
2178                               LogicVRegister dst,
2179                               uint64_t imm);
2180  LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2181  LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2182  LogicVRegister orr(VectorFormat vform,
2183                     LogicVRegister dst,
2184                     const LogicVRegister& src,
2185                     uint64_t imm);
2186  LogicVRegister sshl(VectorFormat vform,
2187                      LogicVRegister dst,
2188                      const LogicVRegister& src1,
2189                      const LogicVRegister& src2);
2190  LogicVRegister ushl(VectorFormat vform,
2191                      LogicVRegister dst,
2192                      const LogicVRegister& src1,
2193                      const LogicVRegister& src2);
2194  LogicVRegister sminmax(VectorFormat vform,
2195                         LogicVRegister dst,
2196                         const LogicVRegister& src1,
2197                         const LogicVRegister& src2,
2198                         bool max);
2199  LogicVRegister smax(VectorFormat vform,
2200                      LogicVRegister dst,
2201                      const LogicVRegister& src1,
2202                      const LogicVRegister& src2);
2203  LogicVRegister smin(VectorFormat vform,
2204                      LogicVRegister dst,
2205                      const LogicVRegister& src1,
2206                      const LogicVRegister& src2);
2207  LogicVRegister sminmaxp(VectorFormat vform,
2208                          LogicVRegister dst,
2209                          int dst_index,
2210                          const LogicVRegister& src,
2211                          bool max);
2212  LogicVRegister smaxp(VectorFormat vform,
2213                       LogicVRegister dst,
2214                       const LogicVRegister& src1,
2215                       const LogicVRegister& src2);
2216  LogicVRegister sminp(VectorFormat vform,
2217                       LogicVRegister dst,
2218                       const LogicVRegister& src1,
2219                       const LogicVRegister& src2);
2220  LogicVRegister addp(VectorFormat vform,
2221                      LogicVRegister dst,
2222                      const LogicVRegister& src);
2223  LogicVRegister addv(VectorFormat vform,
2224                      LogicVRegister dst,
2225                      const LogicVRegister& src);
2226  LogicVRegister uaddlv(VectorFormat vform,
2227                        LogicVRegister dst,
2228                        const LogicVRegister& src);
2229  LogicVRegister saddlv(VectorFormat vform,
2230                        LogicVRegister dst,
2231                        const LogicVRegister& src);
2232  LogicVRegister sminmaxv(VectorFormat vform,
2233                          LogicVRegister dst,
2234                          const LogicVRegister& src,
2235                          bool max);
2236  LogicVRegister smaxv(VectorFormat vform,
2237                       LogicVRegister dst,
2238                       const LogicVRegister& src);
2239  LogicVRegister sminv(VectorFormat vform,
2240                       LogicVRegister dst,
2241                       const LogicVRegister& src);
2242  LogicVRegister uxtl(VectorFormat vform,
2243                      LogicVRegister dst,
2244                      const LogicVRegister& src);
2245  LogicVRegister uxtl2(VectorFormat vform,
2246                       LogicVRegister dst,
2247                       const LogicVRegister& src);
2248  LogicVRegister sxtl(VectorFormat vform,
2249                      LogicVRegister dst,
2250                      const LogicVRegister& src);
2251  LogicVRegister sxtl2(VectorFormat vform,
2252                       LogicVRegister dst,
2253                       const LogicVRegister& src);
2254  LogicVRegister tbl(VectorFormat vform,
2255                     LogicVRegister dst,
2256                     const LogicVRegister& tab,
2257                     const LogicVRegister& ind);
2258  LogicVRegister tbl(VectorFormat vform,
2259                     LogicVRegister dst,
2260                     const LogicVRegister& tab,
2261                     const LogicVRegister& tab2,
2262                     const LogicVRegister& ind);
2263  LogicVRegister tbl(VectorFormat vform,
2264                     LogicVRegister dst,
2265                     const LogicVRegister& tab,
2266                     const LogicVRegister& tab2,
2267                     const LogicVRegister& tab3,
2268                     const LogicVRegister& ind);
2269  LogicVRegister tbl(VectorFormat vform,
2270                     LogicVRegister dst,
2271                     const LogicVRegister& tab,
2272                     const LogicVRegister& tab2,
2273                     const LogicVRegister& tab3,
2274                     const LogicVRegister& tab4,
2275                     const LogicVRegister& ind);
2276  LogicVRegister tbx(VectorFormat vform,
2277                     LogicVRegister dst,
2278                     const LogicVRegister& tab,
2279                     const LogicVRegister& ind);
2280  LogicVRegister tbx(VectorFormat vform,
2281                     LogicVRegister dst,
2282                     const LogicVRegister& tab,
2283                     const LogicVRegister& tab2,
2284                     const LogicVRegister& ind);
2285  LogicVRegister tbx(VectorFormat vform,
2286                     LogicVRegister dst,
2287                     const LogicVRegister& tab,
2288                     const LogicVRegister& tab2,
2289                     const LogicVRegister& tab3,
2290                     const LogicVRegister& ind);
2291  LogicVRegister tbx(VectorFormat vform,
2292                     LogicVRegister dst,
2293                     const LogicVRegister& tab,
2294                     const LogicVRegister& tab2,
2295                     const LogicVRegister& tab3,
2296                     const LogicVRegister& tab4,
2297                     const LogicVRegister& ind);
2298  LogicVRegister uaddl(VectorFormat vform,
2299                       LogicVRegister dst,
2300                       const LogicVRegister& src1,
2301                       const LogicVRegister& src2);
2302  LogicVRegister uaddl2(VectorFormat vform,
2303                        LogicVRegister dst,
2304                        const LogicVRegister& src1,
2305                        const LogicVRegister& src2);
2306  LogicVRegister uaddw(VectorFormat vform,
2307                       LogicVRegister dst,
2308                       const LogicVRegister& src1,
2309                       const LogicVRegister& src2);
2310  LogicVRegister uaddw2(VectorFormat vform,
2311                        LogicVRegister dst,
2312                        const LogicVRegister& src1,
2313                        const LogicVRegister& src2);
2314  LogicVRegister saddl(VectorFormat vform,
2315                       LogicVRegister dst,
2316                       const LogicVRegister& src1,
2317                       const LogicVRegister& src2);
2318  LogicVRegister saddl2(VectorFormat vform,
2319                        LogicVRegister dst,
2320                        const LogicVRegister& src1,
2321                        const LogicVRegister& src2);
2322  LogicVRegister saddw(VectorFormat vform,
2323                       LogicVRegister dst,
2324                       const LogicVRegister& src1,
2325                       const LogicVRegister& src2);
2326  LogicVRegister saddw2(VectorFormat vform,
2327                        LogicVRegister dst,
2328                        const LogicVRegister& src1,
2329                        const LogicVRegister& src2);
2330  LogicVRegister usubl(VectorFormat vform,
2331                       LogicVRegister dst,
2332                       const LogicVRegister& src1,
2333                       const LogicVRegister& src2);
2334  LogicVRegister usubl2(VectorFormat vform,
2335                        LogicVRegister dst,
2336                        const LogicVRegister& src1,
2337                        const LogicVRegister& src2);
2338  LogicVRegister usubw(VectorFormat vform,
2339                       LogicVRegister dst,
2340                       const LogicVRegister& src1,
2341                       const LogicVRegister& src2);
2342  LogicVRegister usubw2(VectorFormat vform,
2343                        LogicVRegister dst,
2344                        const LogicVRegister& src1,
2345                        const LogicVRegister& src2);
2346  LogicVRegister ssubl(VectorFormat vform,
2347                       LogicVRegister dst,
2348                       const LogicVRegister& src1,
2349                       const LogicVRegister& src2);
2350  LogicVRegister ssubl2(VectorFormat vform,
2351                        LogicVRegister dst,
2352                        const LogicVRegister& src1,
2353                        const LogicVRegister& src2);
2354  LogicVRegister ssubw(VectorFormat vform,
2355                       LogicVRegister dst,
2356                       const LogicVRegister& src1,
2357                       const LogicVRegister& src2);
2358  LogicVRegister ssubw2(VectorFormat vform,
2359                        LogicVRegister dst,
2360                        const LogicVRegister& src1,
2361                        const LogicVRegister& src2);
2362  LogicVRegister uminmax(VectorFormat vform,
2363                         LogicVRegister dst,
2364                         const LogicVRegister& src1,
2365                         const LogicVRegister& src2,
2366                         bool max);
2367  LogicVRegister umax(VectorFormat vform,
2368                      LogicVRegister dst,
2369                      const LogicVRegister& src1,
2370                      const LogicVRegister& src2);
2371  LogicVRegister umin(VectorFormat vform,
2372                      LogicVRegister dst,
2373                      const LogicVRegister& src1,
2374                      const LogicVRegister& src2);
2375  LogicVRegister uminmaxp(VectorFormat vform,
2376                          LogicVRegister dst,
2377                          int dst_index,
2378                          const LogicVRegister& src,
2379                          bool max);
2380  LogicVRegister umaxp(VectorFormat vform,
2381                       LogicVRegister dst,
2382                       const LogicVRegister& src1,
2383                       const LogicVRegister& src2);
2384  LogicVRegister uminp(VectorFormat vform,
2385                       LogicVRegister dst,
2386                       const LogicVRegister& src1,
2387                       const LogicVRegister& src2);
2388  LogicVRegister uminmaxv(VectorFormat vform,
2389                          LogicVRegister dst,
2390                          const LogicVRegister& src,
2391                          bool max);
2392  LogicVRegister umaxv(VectorFormat vform,
2393                       LogicVRegister dst,
2394                       const LogicVRegister& src);
2395  LogicVRegister uminv(VectorFormat vform,
2396                       LogicVRegister dst,
2397                       const LogicVRegister& src);
2398  LogicVRegister trn1(VectorFormat vform,
2399                      LogicVRegister dst,
2400                      const LogicVRegister& src1,
2401                      const LogicVRegister& src2);
2402  LogicVRegister trn2(VectorFormat vform,
2403                      LogicVRegister dst,
2404                      const LogicVRegister& src1,
2405                      const LogicVRegister& src2);
2406  LogicVRegister zip1(VectorFormat vform,
2407                      LogicVRegister dst,
2408                      const LogicVRegister& src1,
2409                      const LogicVRegister& src2);
2410  LogicVRegister zip2(VectorFormat vform,
2411                      LogicVRegister dst,
2412                      const LogicVRegister& src1,
2413                      const LogicVRegister& src2);
2414  LogicVRegister uzp1(VectorFormat vform,
2415                      LogicVRegister dst,
2416                      const LogicVRegister& src1,
2417                      const LogicVRegister& src2);
2418  LogicVRegister uzp2(VectorFormat vform,
2419                      LogicVRegister dst,
2420                      const LogicVRegister& src1,
2421                      const LogicVRegister& src2);
2422  LogicVRegister shl(VectorFormat vform,
2423                     LogicVRegister dst,
2424                     const LogicVRegister& src,
2425                     int shift);
2426  LogicVRegister scvtf(VectorFormat vform,
2427                       LogicVRegister dst,
2428                       const LogicVRegister& src,
2429                       int fbits,
2430                       FPRounding rounding_mode);
2431  LogicVRegister ucvtf(VectorFormat vform,
2432                       LogicVRegister dst,
2433                       const LogicVRegister& src,
2434                       int fbits,
2435                       FPRounding rounding_mode);
2436  LogicVRegister sshll(VectorFormat vform,
2437                       LogicVRegister dst,
2438                       const LogicVRegister& src,
2439                       int shift);
2440  LogicVRegister sshll2(VectorFormat vform,
2441                        LogicVRegister dst,
2442                        const LogicVRegister& src,
2443                        int shift);
2444  LogicVRegister shll(VectorFormat vform,
2445                      LogicVRegister dst,
2446                      const LogicVRegister& src);
2447  LogicVRegister shll2(VectorFormat vform,
2448                       LogicVRegister dst,
2449                       const LogicVRegister& src);
2450  LogicVRegister ushll(VectorFormat vform,
2451                       LogicVRegister dst,
2452                       const LogicVRegister& src,
2453                       int shift);
2454  LogicVRegister ushll2(VectorFormat vform,
2455                        LogicVRegister dst,
2456                        const LogicVRegister& src,
2457                        int shift);
2458  LogicVRegister sli(VectorFormat vform,
2459                     LogicVRegister dst,
2460                     const LogicVRegister& src,
2461                     int shift);
2462  LogicVRegister sri(VectorFormat vform,
2463                     LogicVRegister dst,
2464                     const LogicVRegister& src,
2465                     int shift);
2466  LogicVRegister sshr(VectorFormat vform,
2467                      LogicVRegister dst,
2468                      const LogicVRegister& src,
2469                      int shift);
2470  LogicVRegister ushr(VectorFormat vform,
2471                      LogicVRegister dst,
2472                      const LogicVRegister& src,
2473                      int shift);
2474  LogicVRegister ssra(VectorFormat vform,
2475                      LogicVRegister dst,
2476                      const LogicVRegister& src,
2477                      int shift);
2478  LogicVRegister usra(VectorFormat vform,
2479                      LogicVRegister dst,
2480                      const LogicVRegister& src,
2481                      int shift);
2482  LogicVRegister srsra(VectorFormat vform,
2483                       LogicVRegister dst,
2484                       const LogicVRegister& src,
2485                       int shift);
2486  LogicVRegister ursra(VectorFormat vform,
2487                       LogicVRegister dst,
2488                       const LogicVRegister& src,
2489                       int shift);
2490  LogicVRegister suqadd(VectorFormat vform,
2491                        LogicVRegister dst,
2492                        const LogicVRegister& src);
2493  LogicVRegister usqadd(VectorFormat vform,
2494                        LogicVRegister dst,
2495                        const LogicVRegister& src);
2496  LogicVRegister sqshl(VectorFormat vform,
2497                       LogicVRegister dst,
2498                       const LogicVRegister& src,
2499                       int shift);
2500  LogicVRegister uqshl(VectorFormat vform,
2501                       LogicVRegister dst,
2502                       const LogicVRegister& src,
2503                       int shift);
2504  LogicVRegister sqshlu(VectorFormat vform,
2505                        LogicVRegister dst,
2506                        const LogicVRegister& src,
2507                        int shift);
2508  LogicVRegister abs(VectorFormat vform,
2509                     LogicVRegister dst,
2510                     const LogicVRegister& src);
2511  LogicVRegister neg(VectorFormat vform,
2512                     LogicVRegister dst,
2513                     const LogicVRegister& src);
2514  LogicVRegister extractnarrow(VectorFormat vform,
2515                               LogicVRegister dst,
2516                               bool dstIsSigned,
2517                               const LogicVRegister& src,
2518                               bool srcIsSigned);
2519  LogicVRegister xtn(VectorFormat vform,
2520                     LogicVRegister dst,
2521                     const LogicVRegister& src);
2522  LogicVRegister sqxtn(VectorFormat vform,
2523                       LogicVRegister dst,
2524                       const LogicVRegister& src);
2525  LogicVRegister uqxtn(VectorFormat vform,
2526                       LogicVRegister dst,
2527                       const LogicVRegister& src);
2528  LogicVRegister sqxtun(VectorFormat vform,
2529                        LogicVRegister dst,
2530                        const LogicVRegister& src);
2531  LogicVRegister absdiff(VectorFormat vform,
2532                         LogicVRegister dst,
2533                         const LogicVRegister& src1,
2534                         const LogicVRegister& src2,
2535                         bool issigned);
2536  LogicVRegister saba(VectorFormat vform,
2537                      LogicVRegister dst,
2538                      const LogicVRegister& src1,
2539                      const LogicVRegister& src2);
2540  LogicVRegister uaba(VectorFormat vform,
2541                      LogicVRegister dst,
2542                      const LogicVRegister& src1,
2543                      const LogicVRegister& src2);
2544  LogicVRegister shrn(VectorFormat vform,
2545                      LogicVRegister dst,
2546                      const LogicVRegister& src,
2547                      int shift);
2548  LogicVRegister shrn2(VectorFormat vform,
2549                       LogicVRegister dst,
2550                       const LogicVRegister& src,
2551                       int shift);
2552  LogicVRegister rshrn(VectorFormat vform,
2553                       LogicVRegister dst,
2554                       const LogicVRegister& src,
2555                       int shift);
2556  LogicVRegister rshrn2(VectorFormat vform,
2557                        LogicVRegister dst,
2558                        const LogicVRegister& src,
2559                        int shift);
2560  LogicVRegister uqshrn(VectorFormat vform,
2561                        LogicVRegister dst,
2562                        const LogicVRegister& src,
2563                        int shift);
2564  LogicVRegister uqshrn2(VectorFormat vform,
2565                         LogicVRegister dst,
2566                         const LogicVRegister& src,
2567                         int shift);
2568  LogicVRegister uqrshrn(VectorFormat vform,
2569                         LogicVRegister dst,
2570                         const LogicVRegister& src,
2571                         int shift);
2572  LogicVRegister uqrshrn2(VectorFormat vform,
2573                          LogicVRegister dst,
2574                          const LogicVRegister& src,
2575                          int shift);
2576  LogicVRegister sqshrn(VectorFormat vform,
2577                        LogicVRegister dst,
2578                        const LogicVRegister& src,
2579                        int shift);
2580  LogicVRegister sqshrn2(VectorFormat vform,
2581                         LogicVRegister dst,
2582                         const LogicVRegister& src,
2583                         int shift);
2584  LogicVRegister sqrshrn(VectorFormat vform,
2585                         LogicVRegister dst,
2586                         const LogicVRegister& src,
2587                         int shift);
2588  LogicVRegister sqrshrn2(VectorFormat vform,
2589                          LogicVRegister dst,
2590                          const LogicVRegister& src,
2591                          int shift);
2592  LogicVRegister sqshrun(VectorFormat vform,
2593                         LogicVRegister dst,
2594                         const LogicVRegister& src,
2595                         int shift);
2596  LogicVRegister sqshrun2(VectorFormat vform,
2597                          LogicVRegister dst,
2598                          const LogicVRegister& src,
2599                          int shift);
2600  LogicVRegister sqrshrun(VectorFormat vform,
2601                          LogicVRegister dst,
2602                          const LogicVRegister& src,
2603                          int shift);
2604  LogicVRegister sqrshrun2(VectorFormat vform,
2605                           LogicVRegister dst,
2606                           const LogicVRegister& src,
2607                           int shift);
2608  LogicVRegister sqrdmulh(VectorFormat vform,
2609                          LogicVRegister dst,
2610                          const LogicVRegister& src1,
2611                          const LogicVRegister& src2,
2612                          bool round = true);
2613  LogicVRegister sqdmulh(VectorFormat vform,
2614                         LogicVRegister dst,
2615                         const LogicVRegister& src1,
2616                         const LogicVRegister& src2);
2617#define NEON_3VREG_LOGIC_LIST(V) \
2618  V(addhn)                       \
2619  V(addhn2)                      \
2620  V(raddhn)                      \
2621  V(raddhn2)                     \
2622  V(subhn)                       \
2623  V(subhn2)                      \
2624  V(rsubhn)                      \
2625  V(rsubhn2)                     \
2626  V(pmull)                       \
2627  V(pmull2)                      \
2628  V(sabal)                       \
2629  V(sabal2)                      \
2630  V(uabal)                       \
2631  V(uabal2)                      \
2632  V(sabdl)                       \
2633  V(sabdl2)                      \
2634  V(uabdl)                       \
2635  V(uabdl2)                      \
2636  V(smull)                       \
2637  V(smull2)                      \
2638  V(umull)                       \
2639  V(umull2)                      \
2640  V(smlal)                       \
2641  V(smlal2)                      \
2642  V(umlal)                       \
2643  V(umlal2)                      \
2644  V(smlsl)                       \
2645  V(smlsl2)                      \
2646  V(umlsl)                       \
2647  V(umlsl2)                      \
2648  V(sqdmlal)                     \
2649  V(sqdmlal2)                    \
2650  V(sqdmlsl)                     \
2651  V(sqdmlsl2)                    \
2652  V(sqdmull)                     \
2653  V(sqdmull2)
2654
2655#define DEFINE_LOGIC_FUNC(FXN)                   \
2656  LogicVRegister FXN(VectorFormat vform,         \
2657                     LogicVRegister dst,         \
2658                     const LogicVRegister& src1, \
2659                     const LogicVRegister& src2);
2660  NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
2661#undef DEFINE_LOGIC_FUNC
2662
2663#define NEON_FP3SAME_LIST(V) \
2664  V(fadd, FPAdd, false)      \
2665  V(fsub, FPSub, true)       \
2666  V(fmul, FPMul, true)       \
2667  V(fmulx, FPMulx, true)     \
2668  V(fdiv, FPDiv, true)       \
2669  V(fmax, FPMax, false)      \
2670  V(fmin, FPMin, false)      \
2671  V(fmaxnm, FPMaxNM, false)  \
2672  V(fminnm, FPMinNM, false)
2673
2674#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
2675  template <typename T>                            \
2676  LogicVRegister FN(VectorFormat vform,            \
2677                    LogicVRegister dst,            \
2678                    const LogicVRegister& src1,    \
2679                    const LogicVRegister& src2);   \
2680  LogicVRegister FN(VectorFormat vform,            \
2681                    LogicVRegister dst,            \
2682                    const LogicVRegister& src1,    \
2683                    const LogicVRegister& src2);
2684  NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
2685#undef DECLARE_NEON_FP_VECTOR_OP
2686
2687#define NEON_FPPAIRWISE_LIST(V) \
2688  V(faddp, fadd, FPAdd)         \
2689  V(fmaxp, fmax, FPMax)         \
2690  V(fmaxnmp, fmaxnm, FPMaxNM)   \
2691  V(fminp, fmin, FPMin)         \
2692  V(fminnmp, fminnm, FPMinNM)
2693
2694#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)      \
2695  LogicVRegister FNP(VectorFormat vform,          \
2696                     LogicVRegister dst,          \
2697                     const LogicVRegister& src1,  \
2698                     const LogicVRegister& src2); \
2699  LogicVRegister FNP(VectorFormat vform,          \
2700                     LogicVRegister dst,          \
2701                     const LogicVRegister& src);
2702  NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
2703#undef DECLARE_NEON_FP_PAIR_OP
2704
2705  template <typename T>
2706  LogicVRegister frecps(VectorFormat vform,
2707                        LogicVRegister dst,
2708                        const LogicVRegister& src1,
2709                        const LogicVRegister& src2);
2710  LogicVRegister frecps(VectorFormat vform,
2711                        LogicVRegister dst,
2712                        const LogicVRegister& src1,
2713                        const LogicVRegister& src2);
2714  template <typename T>
2715  LogicVRegister frsqrts(VectorFormat vform,
2716                         LogicVRegister dst,
2717                         const LogicVRegister& src1,
2718                         const LogicVRegister& src2);
2719  LogicVRegister frsqrts(VectorFormat vform,
2720                         LogicVRegister dst,
2721                         const LogicVRegister& src1,
2722                         const LogicVRegister& src2);
2723  template <typename T>
2724  LogicVRegister fmla(VectorFormat vform,
2725                      LogicVRegister dst,
2726                      const LogicVRegister& src1,
2727                      const LogicVRegister& src2);
2728  LogicVRegister fmla(VectorFormat vform,
2729                      LogicVRegister dst,
2730                      const LogicVRegister& src1,
2731                      const LogicVRegister& src2);
2732  template <typename T>
2733  LogicVRegister fmls(VectorFormat vform,
2734                      LogicVRegister dst,
2735                      const LogicVRegister& src1,
2736                      const LogicVRegister& src2);
2737  LogicVRegister fmls(VectorFormat vform,
2738                      LogicVRegister dst,
2739                      const LogicVRegister& src1,
2740                      const LogicVRegister& src2);
2741  LogicVRegister fnmul(VectorFormat vform,
2742                       LogicVRegister dst,
2743                       const LogicVRegister& src1,
2744                       const LogicVRegister& src2);
2745
2746  template <typename T>
2747  LogicVRegister fcmp(VectorFormat vform,
2748                      LogicVRegister dst,
2749                      const LogicVRegister& src1,
2750                      const LogicVRegister& src2,
2751                      Condition cond);
2752  LogicVRegister fcmp(VectorFormat vform,
2753                      LogicVRegister dst,
2754                      const LogicVRegister& src1,
2755                      const LogicVRegister& src2,
2756                      Condition cond);
2757  LogicVRegister fabscmp(VectorFormat vform,
2758                         LogicVRegister dst,
2759                         const LogicVRegister& src1,
2760                         const LogicVRegister& src2,
2761                         Condition cond);
2762  LogicVRegister fcmp_zero(VectorFormat vform,
2763                           LogicVRegister dst,
2764                           const LogicVRegister& src,
2765                           Condition cond);
2766
2767  template <typename T>
2768  LogicVRegister fneg(VectorFormat vform,
2769                      LogicVRegister dst,
2770                      const LogicVRegister& src);
2771  LogicVRegister fneg(VectorFormat vform,
2772                      LogicVRegister dst,
2773                      const LogicVRegister& src);
2774  template <typename T>
2775  LogicVRegister frecpx(VectorFormat vform,
2776                        LogicVRegister dst,
2777                        const LogicVRegister& src);
2778  LogicVRegister frecpx(VectorFormat vform,
2779                        LogicVRegister dst,
2780                        const LogicVRegister& src);
2781  template <typename T>
2782  LogicVRegister fabs_(VectorFormat vform,
2783                       LogicVRegister dst,
2784                       const LogicVRegister& src);
2785  LogicVRegister fabs_(VectorFormat vform,
2786                       LogicVRegister dst,
2787                       const LogicVRegister& src);
2788  LogicVRegister fabd(VectorFormat vform,
2789                      LogicVRegister dst,
2790                      const LogicVRegister& src1,
2791                      const LogicVRegister& src2);
2792  LogicVRegister frint(VectorFormat vform,
2793                       LogicVRegister dst,
2794                       const LogicVRegister& src,
2795                       FPRounding rounding_mode,
2796                       bool inexact_exception = false);
2797  LogicVRegister fcvts(VectorFormat vform,
2798                       LogicVRegister dst,
2799                       const LogicVRegister& src,
2800                       FPRounding rounding_mode,
2801                       int fbits = 0);
2802  LogicVRegister fcvtu(VectorFormat vform,
2803                       LogicVRegister dst,
2804                       const LogicVRegister& src,
2805                       FPRounding rounding_mode,
2806                       int fbits = 0);
2807  LogicVRegister fcvtl(VectorFormat vform,
2808                       LogicVRegister dst,
2809                       const LogicVRegister& src);
2810  LogicVRegister fcvtl2(VectorFormat vform,
2811                        LogicVRegister dst,
2812                        const LogicVRegister& src);
2813  LogicVRegister fcvtn(VectorFormat vform,
2814                       LogicVRegister dst,
2815                       const LogicVRegister& src);
2816  LogicVRegister fcvtn2(VectorFormat vform,
2817                        LogicVRegister dst,
2818                        const LogicVRegister& src);
2819  LogicVRegister fcvtxn(VectorFormat vform,
2820                        LogicVRegister dst,
2821                        const LogicVRegister& src);
2822  LogicVRegister fcvtxn2(VectorFormat vform,
2823                         LogicVRegister dst,
2824                         const LogicVRegister& src);
2825  LogicVRegister fsqrt(VectorFormat vform,
2826                       LogicVRegister dst,
2827                       const LogicVRegister& src);
2828  LogicVRegister frsqrte(VectorFormat vform,
2829                         LogicVRegister dst,
2830                         const LogicVRegister& src);
2831  LogicVRegister frecpe(VectorFormat vform,
2832                        LogicVRegister dst,
2833                        const LogicVRegister& src,
2834                        FPRounding rounding);
2835  LogicVRegister ursqrte(VectorFormat vform,
2836                         LogicVRegister dst,
2837                         const LogicVRegister& src);
2838  LogicVRegister urecpe(VectorFormat vform,
2839                        LogicVRegister dst,
2840                        const LogicVRegister& src);
2841
2842  typedef float (Simulator::*FPMinMaxOp)(float a, float b);
2843
2844  LogicVRegister fminmaxv(VectorFormat vform,
2845                          LogicVRegister dst,
2846                          const LogicVRegister& src,
2847                          FPMinMaxOp Op);
2848
2849  LogicVRegister fminv(VectorFormat vform,
2850                       LogicVRegister dst,
2851                       const LogicVRegister& src);
2852  LogicVRegister fmaxv(VectorFormat vform,
2853                       LogicVRegister dst,
2854                       const LogicVRegister& src);
2855  LogicVRegister fminnmv(VectorFormat vform,
2856                         LogicVRegister dst,
2857                         const LogicVRegister& src);
2858  LogicVRegister fmaxnmv(VectorFormat vform,
2859                         LogicVRegister dst,
2860                         const LogicVRegister& src);
2861
2862  static const uint32_t CRC32_POLY = 0x04C11DB7;
2863  static const uint32_t CRC32C_POLY = 0x1EDC6F41;
2864  uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
2865  template <typename T>
2866  uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
2867  uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
2868
2869  void SysOp_W(int op, int64_t val);
2870
2871  template <typename T>
2872  T FPRecipSqrtEstimate(T op);
2873  template <typename T>
2874  T FPRecipEstimate(T op, FPRounding rounding);
2875  template <typename T, typename R>
2876  R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
2877
2878  void FPCompare(double val0, double val1, FPTrapFlags trap);
2879  double FPRoundInt(double value, FPRounding round_mode);
2880  double FPToDouble(float value);
2881  float FPToFloat(double value, FPRounding round_mode);
2882  float FPToFloat(float16 value);
2883  float16 FPToFloat16(float value, FPRounding round_mode);
2884  float16 FPToFloat16(double value, FPRounding round_mode);
2885  double recip_sqrt_estimate(double a);
2886  double recip_estimate(double a);
2887  double FPRecipSqrtEstimate(double a);
2888  double FPRecipEstimate(double a);
2889  double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
2890  double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
2891  float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
2892  float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
2893  int32_t FPToInt32(double value, FPRounding rmode);
2894  int64_t FPToInt64(double value, FPRounding rmode);
2895  uint32_t FPToUInt32(double value, FPRounding rmode);
2896  uint64_t FPToUInt64(double value, FPRounding rmode);
2897
2898  template <typename T>
2899  T FPAdd(T op1, T op2);
2900
2901  template <typename T>
2902  T FPDiv(T op1, T op2);
2903
2904  template <typename T>
2905  T FPMax(T a, T b);
2906
2907  template <typename T>
2908  T FPMaxNM(T a, T b);
2909
2910  template <typename T>
2911  T FPMin(T a, T b);
2912
2913  template <typename T>
2914  T FPMinNM(T a, T b);
2915
2916  template <typename T>
2917  T FPMul(T op1, T op2);
2918
2919  template <typename T>
2920  T FPMulx(T op1, T op2);
2921
2922  template <typename T>
2923  T FPMulAdd(T a, T op1, T op2);
2924
2925  template <typename T>
2926  T FPSqrt(T op);
2927
2928  template <typename T>
2929  T FPSub(T op1, T op2);
2930
2931  template <typename T>
2932  T FPRecipStepFused(T op1, T op2);
2933
2934  template <typename T>
2935  T FPRSqrtStepFused(T op1, T op2);
2936
2937  // This doesn't do anything at the moment. We'll need it if we want support
2938  // for cumulative exception bits or floating-point exceptions.
2939  void FPProcessException() {}
2940
2941  bool FPProcessNaNs(const Instruction* instr);
2942
2943  // Pseudo Printf instruction
2944  void DoPrintf(const Instruction* instr);
2945
2946// Simulate a runtime call.
2947#ifndef VIXL_SIMULATED_RUNTIME_CALL_SUPPORT
2948  VIXL_NO_RETURN_IN_DEBUG_MODE
2949#endif
2950  void DoRuntimeCall(const Instruction* instr);
2951
2952  // Processor state ---------------------------------------
2953
2954  // Simulated monitors for exclusive access instructions.
2955  SimExclusiveLocalMonitor local_monitor_;
2956  SimExclusiveGlobalMonitor global_monitor_;
2957
2958  // Output stream.
2959  FILE* stream_;
2960  PrintDisassembler* print_disasm_;
2961
2962  // Instruction statistics instrumentation.
2963  Instrument* instrumentation_;
2964
2965  // General purpose registers. Register 31 is the stack pointer.
2966  SimRegister registers_[kNumberOfRegisters];
2967
2968  // Vector registers
2969  SimVRegister vregisters_[kNumberOfVRegisters];
2970
2971  // Program Status Register.
2972  // bits[31, 27]: Condition flags N, Z, C, and V.
2973  //               (Negative, Zero, Carry, Overflow)
2974  SimSystemRegister nzcv_;
2975
2976  // Floating-Point Control Register
2977  SimSystemRegister fpcr_;
2978
2979  // Only a subset of FPCR features are supported by the simulator. This helper
2980  // checks that the FPCR settings are supported.
2981  //
2982  // This is checked when floating-point instructions are executed, not when
2983  // FPCR is set. This allows generated code to modify FPCR for external
2984  // functions, or to save and restore it when entering and leaving generated
2985  // code.
2986  void AssertSupportedFPCR() {
2987    // No flush-to-zero support.
2988    VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
2989    // Ties-to-even rounding only.
2990    VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
2991
2992    // The simulator does not support half-precision operations so
2993    // GetFpcr().AHP() is irrelevant, and is not checked here.
2994  }
2995
2996  static int CalcNFlag(uint64_t result, unsigned reg_size) {
2997    return (result >> (reg_size - 1)) & 1;
2998  }
2999
3000  static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
3001
3002  static const uint32_t kConditionFlagsMask = 0xf0000000;
3003
3004  // Stack
3005  byte* stack_;
3006  static const int stack_protection_size_ = 256;
3007  // 2 KB stack.
3008  static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
3009  byte* stack_limit_;
3010
3011  Decoder* decoder_;
3012  // Indicates if the pc has been modified by the instruction and should not be
3013  // automatically incremented.
3014  bool pc_modified_;
3015  const Instruction* pc_;
3016
3017  static const char* xreg_names[];
3018  static const char* wreg_names[];
3019  static const char* sreg_names[];
3020  static const char* dreg_names[];
3021  static const char* vreg_names[];
3022
3023 private:
3024  template <typename T>
3025  static T FPDefaultNaN();
3026
3027  // Standard NaN processing.
3028  template <typename T>
3029  T FPProcessNaN(T op) {
3030    VIXL_ASSERT(std::isnan(op));
3031    if (IsSignallingNaN(op)) {
3032      FPProcessException();
3033    }
3034    return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
3035  }
3036
3037  template <typename T>
3038  T FPProcessNaNs(T op1, T op2) {
3039    if (IsSignallingNaN(op1)) {
3040      return FPProcessNaN(op1);
3041    } else if (IsSignallingNaN(op2)) {
3042      return FPProcessNaN(op2);
3043    } else if (std::isnan(op1)) {
3044      VIXL_ASSERT(IsQuietNaN(op1));
3045      return FPProcessNaN(op1);
3046    } else if (std::isnan(op2)) {
3047      VIXL_ASSERT(IsQuietNaN(op2));
3048      return FPProcessNaN(op2);
3049    } else {
3050      return 0.0;
3051    }
3052  }
3053
3054  template <typename T>
3055  T FPProcessNaNs3(T op1, T op2, T op3) {
3056    if (IsSignallingNaN(op1)) {
3057      return FPProcessNaN(op1);
3058    } else if (IsSignallingNaN(op2)) {
3059      return FPProcessNaN(op2);
3060    } else if (IsSignallingNaN(op3)) {
3061      return FPProcessNaN(op3);
3062    } else if (std::isnan(op1)) {
3063      VIXL_ASSERT(IsQuietNaN(op1));
3064      return FPProcessNaN(op1);
3065    } else if (std::isnan(op2)) {
3066      VIXL_ASSERT(IsQuietNaN(op2));
3067      return FPProcessNaN(op2);
3068    } else if (std::isnan(op3)) {
3069      VIXL_ASSERT(IsQuietNaN(op3));
3070      return FPProcessNaN(op3);
3071    } else {
3072      return 0.0;
3073    }
3074  }
3075
3076  bool coloured_trace_;
3077
3078  // A set of TraceParameters flags.
3079  int trace_parameters_;
3080
3081  // Indicates whether the instruction instrumentation is active.
3082  bool instruction_stats_;
3083
3084  // Indicates whether the exclusive-access warning has been printed.
3085  bool print_exclusive_access_warning_;
3086  void PrintExclusiveAccessWarning();
3087};
3088
3089#if defined(VIXL_ABI_SUPPORT) && __cplusplus >= 201103L && __cplusplus < 201402L
3090// Base case of the recursive template used to emulate C++14
3091// `std::index_sequence`.
3092template <size_t... I>
3093struct Simulator::emulated_make_index_sequence_helper<0, I...>
3094    : Simulator::emulated_index_sequence<I...> {};
3095#endif
3096
3097}  // namespace aarch64
3098}  // namespace vixl
3099
3100#endif  // VIXL_AARCH64_SIMULATOR_AARCH64_H_
3101