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