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