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