Home | History | Annotate | Download | only in arm64
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_
      6 #define V8_ARM64_SIMULATOR_ARM64_H_
      7 
      8 #include <stdarg.h>
      9 #include <vector>
     10 
     11 #include "src/allocation.h"
     12 #include "src/arm64/assembler-arm64.h"
     13 #include "src/arm64/decoder-arm64.h"
     14 #include "src/arm64/disasm-arm64.h"
     15 #include "src/arm64/instrument-arm64.h"
     16 #include "src/assembler.h"
     17 #include "src/base/compiler-specific.h"
     18 #include "src/globals.h"
     19 #include "src/simulator-base.h"
     20 #include "src/utils.h"
     21 
     22 namespace v8 {
     23 namespace internal {
     24 
     25 #if defined(USE_SIMULATOR)
     26 
     27 // Assemble the specified IEEE-754 components into the target type and apply
     28 // appropriate rounding.
     29 //  sign:     0 = positive, 1 = negative
     30 //  exponent: Unbiased IEEE-754 exponent.
     31 //  mantissa: The mantissa of the input. The top bit (which is not encoded for
     32 //            normal IEEE-754 values) must not be omitted. This bit has the
     33 //            value 'pow(2, exponent)'.
     34 //
     35 // The input value is assumed to be a normalized value. That is, the input may
     36 // not be infinity or NaN. If the source value is subnormal, it must be
     37 // normalized before calling this function such that the highest set bit in the
     38 // mantissa has the value 'pow(2, exponent)'.
     39 //
     40 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
     41 // calling a templated FPRound.
     42 template <class T, int ebits, int mbits>
     43 T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa,
     44           FPRounding round_mode) {
     45   static_assert((sizeof(T) * 8) >= (1 + ebits + mbits),
     46                 "destination type T not large enough");
     47   static_assert(sizeof(T) <= sizeof(uint64_t),
     48                 "maximum size of destination type T is 64 bits");
     49   static_assert(std::is_unsigned<T>::value,
     50                 "destination type T must be unsigned");
     51 
     52   DCHECK((sign == 0) || (sign == 1));
     53 
     54   // Only FPTieEven and FPRoundOdd rounding modes are implemented.
     55   DCHECK((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
     56 
     57   // Rounding can promote subnormals to normals, and normals to infinities. For
     58   // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
     59   // encodable as a float, but rounding based on the low-order mantissa bits
     60   // could make it overflow. With ties-to-even rounding, this value would become
     61   // an infinity.
     62 
     63   // ---- Rounding Method ----
     64   //
     65   // The exponent is irrelevant in the rounding operation, so we treat the
     66   // lowest-order bit that will fit into the result ('onebit') as having
     67   // the value '1'. Similarly, the highest-order bit that won't fit into
     68   // the result ('halfbit') has the value '0.5'. The 'point' sits between
     69   // 'onebit' and 'halfbit':
     70   //
     71   //            These bits fit into the result.
     72   //               |---------------------|
     73   //  mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     74   //                                     ||
     75   //                                    / |
     76   //                                   /  halfbit
     77   //                               onebit
     78   //
     79   // For subnormal outputs, the range of representable bits is smaller and
     80   // the position of onebit and halfbit depends on the exponent of the
     81   // input, but the method is otherwise similar.
     82   //
     83   //   onebit(frac)
     84   //     |
     85   //     | halfbit(frac)          halfbit(adjusted)
     86   //     | /                      /
     87   //     | |                      |
     88   //  0b00.0 (exact)      -> 0b00.0 (exact)                    -> 0b00
     89   //  0b00.0...           -> 0b00.0...                         -> 0b00
     90   //  0b00.1 (exact)      -> 0b00.0111..111                    -> 0b00
     91   //  0b00.1...           -> 0b00.1...                         -> 0b01
     92   //  0b01.0 (exact)      -> 0b01.0 (exact)                    -> 0b01
     93   //  0b01.0...           -> 0b01.0...                         -> 0b01
     94   //  0b01.1 (exact)      -> 0b01.1 (exact)                    -> 0b10
     95   //  0b01.1...           -> 0b01.1...                         -> 0b10
     96   //  0b10.0 (exact)      -> 0b10.0 (exact)                    -> 0b10
     97   //  0b10.0...           -> 0b10.0...                         -> 0b10
     98   //  0b10.1 (exact)      -> 0b10.0111..111                    -> 0b10
     99   //  0b10.1...           -> 0b10.1...                         -> 0b11
    100   //  0b11.0 (exact)      -> 0b11.0 (exact)                    -> 0b11
    101   //  ...                   /             |                      /   |
    102   //                       /              |                     /    |
    103   //                                                           /     |
    104   // adjusted = frac - (halfbit(mantissa) & ~onebit(frac));   /      |
    105   //
    106   //                   mantissa = (mantissa >> shift) + halfbit(adjusted);
    107 
    108   const int mantissa_offset = 0;
    109   const int exponent_offset = mantissa_offset + mbits;
    110   const int sign_offset = exponent_offset + ebits;
    111   DCHECK_EQ(sign_offset, static_cast<int>(sizeof(T) * 8 - 1));
    112 
    113   // Bail out early for zero inputs.
    114   if (mantissa == 0) {
    115     return static_cast<T>(sign << sign_offset);
    116   }
    117 
    118   // If all bits in the exponent are set, the value is infinite or NaN.
    119   // This is true for all binary IEEE-754 formats.
    120   const int infinite_exponent = (1 << ebits) - 1;
    121   const int max_normal_exponent = infinite_exponent - 1;
    122 
    123   // Apply the exponent bias to encode it for the result. Doing this early makes
    124   // it easy to detect values that will be infinite or subnormal.
    125   exponent += max_normal_exponent >> 1;
    126 
    127   if (exponent > max_normal_exponent) {
    128     // Overflow: the input is too large for the result type to represent.
    129     if (round_mode == FPTieEven) {
    130       // FPTieEven rounding mode handles overflows using infinities.
    131       exponent = infinite_exponent;
    132       mantissa = 0;
    133     } else {
    134       DCHECK_EQ(round_mode, FPRoundOdd);
    135       // FPRoundOdd rounding mode handles overflows using the largest magnitude
    136       // normal number.
    137       exponent = max_normal_exponent;
    138       mantissa = (UINT64_C(1) << exponent_offset) - 1;
    139     }
    140     return static_cast<T>((sign << sign_offset) |
    141                           (exponent << exponent_offset) |
    142                           (mantissa << mantissa_offset));
    143   }
    144 
    145   // Calculate the shift required to move the top mantissa bit to the proper
    146   // place in the destination type.
    147   const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64);
    148   int shift = highest_significant_bit - mbits;
    149 
    150   if (exponent <= 0) {
    151     // The output will be subnormal (before rounding).
    152     // For subnormal outputs, the shift must be adjusted by the exponent. The +1
    153     // is necessary because the exponent of a subnormal value (encoded as 0) is
    154     // the same as the exponent of the smallest normal value (encoded as 1).
    155     shift += -exponent + 1;
    156 
    157     // Handle inputs that would produce a zero output.
    158     //
    159     // Shifts higher than highest_significant_bit+1 will always produce a zero
    160     // result. A shift of exactly highest_significant_bit+1 might produce a
    161     // non-zero result after rounding.
    162     if (shift > (highest_significant_bit + 1)) {
    163       if (round_mode == FPTieEven) {
    164         // The result will always be +/-0.0.
    165         return static_cast<T>(sign << sign_offset);
    166       } else {
    167         DCHECK_EQ(round_mode, FPRoundOdd);
    168         DCHECK_NE(mantissa, 0U);
    169         // For FPRoundOdd, if the mantissa is too small to represent and
    170         // non-zero return the next "odd" value.
    171         return static_cast<T>((sign << sign_offset) | 1);
    172       }
    173     }
    174 
    175     // Properly encode the exponent for a subnormal output.
    176     exponent = 0;
    177   } else {
    178     // Clear the topmost mantissa bit, since this is not encoded in IEEE-754
    179     // normal values.
    180     mantissa &= ~(UINT64_C(1) << highest_significant_bit);
    181   }
    182 
    183   if (shift > 0) {
    184     if (round_mode == FPTieEven) {
    185       // We have to shift the mantissa to the right. Some precision is lost, so
    186       // we need to apply rounding.
    187       uint64_t onebit_mantissa = (mantissa >> (shift)) & 1;
    188       uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1;
    189       uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa);
    190       uint64_t adjusted = mantissa - adjustment;
    191       T halfbit_adjusted = (adjusted >> (shift - 1)) & 1;
    192 
    193       T result =
    194           static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) |
    195                          ((mantissa >> shift) << mantissa_offset));
    196 
    197       // A very large mantissa can overflow during rounding. If this happens,
    198       // the exponent should be incremented and the mantissa set to 1.0
    199       // (encoded as 0). Applying halfbit_adjusted after assembling the float
    200       // has the nice side-effect that this case is handled for free.
    201       //
    202       // This also handles cases where a very large finite value overflows to
    203       // infinity, or where a very large subnormal value overflows to become
    204       // normal.
    205       return result + halfbit_adjusted;
    206     } else {
    207       DCHECK_EQ(round_mode, FPRoundOdd);
    208       // If any bits at position halfbit or below are set, onebit (ie. the
    209       // bottom bit of the resulting mantissa) must be set.
    210       uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1);
    211       if (fractional_bits != 0) {
    212         mantissa |= UINT64_C(1) << shift;
    213       }
    214 
    215       return static_cast<T>((sign << sign_offset) |
    216                             (exponent << exponent_offset) |
    217                             ((mantissa >> shift) << mantissa_offset));
    218     }
    219   } else {
    220     // We have to shift the mantissa to the left (or not at all). The input
    221     // mantissa is exactly representable in the output mantissa, so apply no
    222     // rounding correction.
    223     return static_cast<T>((sign << sign_offset) |
    224                           (exponent << exponent_offset) |
    225                           ((mantissa << -shift) << mantissa_offset));
    226   }
    227 }
    228 
    229 class CachePage {
    230   // TODO(all): Simulate instruction cache.
    231 };
    232 
    233 // Representation of memory, with typed getters and setters for access.
    234 class SimMemory {
    235  public:
    236   template <typename T>
    237   static T AddressUntag(T address) {
    238     // Cast the address using a C-style cast. A reinterpret_cast would be
    239     // appropriate, but it can't cast one integral type to another.
    240     uint64_t bits = (uint64_t)address;
    241     return (T)(bits & ~kAddressTagMask);
    242   }
    243 
    244   template <typename T, typename A>
    245   static T Read(A address) {
    246     T value;
    247     address = AddressUntag(address);
    248     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) ||
    249            (sizeof(value) == 4) || (sizeof(value) == 8) ||
    250            (sizeof(value) == 16));
    251     memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
    252     return value;
    253   }
    254 
    255   template <typename T, typename A>
    256   static void Write(A address, T value) {
    257     address = AddressUntag(address);
    258     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) ||
    259            (sizeof(value) == 4) || (sizeof(value) == 8) ||
    260            (sizeof(value) == 16));
    261     memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
    262   }
    263 };
    264 
    265 // The proper way to initialize a simulated system register (such as NZCV) is as
    266 // follows:
    267 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
    268 class SimSystemRegister {
    269  public:
    270   // The default constructor represents a register which has no writable bits.
    271   // It is not possible to set its value to anything other than 0.
    272   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { }
    273 
    274   uint32_t RawValue() const {
    275     return value_;
    276   }
    277 
    278   void SetRawValue(uint32_t new_value) {
    279     value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
    280   }
    281 
    282   uint32_t Bits(int msb, int lsb) const {
    283     return unsigned_bitextract_32(msb, lsb, value_);
    284   }
    285 
    286   int32_t SignedBits(int msb, int lsb) const {
    287     return signed_bitextract_32(msb, lsb, value_);
    288   }
    289 
    290   void SetBits(int msb, int lsb, uint32_t bits);
    291 
    292   // Default system register values.
    293   static SimSystemRegister DefaultValueFor(SystemRegister id);
    294 
    295 #define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type)                       \
    296   Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); }       \
    297   void Set##Name(Type bits) {                                                  \
    298     SetBits(HighBit, LowBit, static_cast<Type>(bits));                         \
    299   }
    300 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask)                                   \
    301   static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
    302   SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
    303 #undef DEFINE_ZERO_BITS
    304 #undef DEFINE_GETTER
    305 
    306  protected:
    307   // Most system registers only implement a few of the bits in the word. Other
    308   // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
    309   // describes the bits which are not modifiable.
    310   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
    311       : value_(value), write_ignore_mask_(write_ignore_mask) { }
    312 
    313   uint32_t value_;
    314   uint32_t write_ignore_mask_;
    315 };
    316 
    317 
    318 // Represent a register (r0-r31, v0-v31).
    319 template <int kSizeInBytes>
    320 class SimRegisterBase {
    321  public:
    322   template<typename T>
    323   void Set(T new_value) {
    324     static_assert(sizeof(new_value) <= kSizeInBytes,
    325                   "Size of new_value must be <= size of template type.");
    326     if (sizeof(new_value) < kSizeInBytes) {
    327       // All AArch64 registers are zero-extending.
    328       memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value));
    329     }
    330     memcpy(&value_, &new_value, sizeof(T));
    331     NotifyRegisterWrite();
    332   }
    333 
    334   // Insert a typed value into a register, leaving the rest of the register
    335   // unchanged. The lane parameter indicates where in the register the value
    336   // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
    337   // 0 represents the least significant bits.
    338   template <typename T>
    339   void Insert(int lane, T new_value) {
    340     DCHECK_GE(lane, 0);
    341     DCHECK_LE(sizeof(new_value) + (lane * sizeof(new_value)),
    342               static_cast<unsigned>(kSizeInBytes));
    343     memcpy(&value_[lane * sizeof(new_value)], &new_value, sizeof(new_value));
    344     NotifyRegisterWrite();
    345   }
    346 
    347   template <typename T>
    348   T Get(int lane = 0) const {
    349     T result;
    350     DCHECK_GE(lane, 0);
    351     DCHECK_LE(sizeof(result) + (lane * sizeof(result)),
    352               static_cast<unsigned>(kSizeInBytes));
    353     memcpy(&result, &value_[lane * sizeof(result)], sizeof(result));
    354     return result;
    355   }
    356 
    357   // TODO(all): Make this return a map of updated bytes, so that we can
    358   // highlight updated lanes for load-and-insert. (That never happens for scalar
    359   // code, but NEON has some instructions that can update individual lanes.)
    360   bool WrittenSinceLastLog() const { return written_since_last_log_; }
    361 
    362   void NotifyRegisterLogged() { written_since_last_log_ = false; }
    363 
    364  protected:
    365   uint8_t value_[kSizeInBytes];
    366 
    367   // Helpers to aid with register tracing.
    368   bool written_since_last_log_;
    369 
    370   void NotifyRegisterWrite() { written_since_last_log_ = true; }
    371 };
    372 
    373 typedef SimRegisterBase<kXRegSize> SimRegister;   // r0-r31
    374 typedef SimRegisterBase<kQRegSize> SimVRegister;  // v0-v31
    375 
    376 // Representation of a vector register, with typed getters and setters for lanes
    377 // and additional information to represent lane state.
    378 class LogicVRegister {
    379  public:
    380   inline LogicVRegister(SimVRegister& other)  // NOLINT
    381       : register_(other) {
    382     for (unsigned i = 0; i < arraysize(saturated_); i++) {
    383       saturated_[i] = kNotSaturated;
    384     }
    385     for (unsigned i = 0; i < arraysize(round_); i++) {
    386       round_[i] = false;
    387     }
    388   }
    389 
    390   int64_t Int(VectorFormat vform, int index) const {
    391     int64_t element;
    392     switch (LaneSizeInBitsFromFormat(vform)) {
    393       case 8:
    394         element = register_.Get<int8_t>(index);
    395         break;
    396       case 16:
    397         element = register_.Get<int16_t>(index);
    398         break;
    399       case 32:
    400         element = register_.Get<int32_t>(index);
    401         break;
    402       case 64:
    403         element = register_.Get<int64_t>(index);
    404         break;
    405       default:
    406         UNREACHABLE();
    407         return 0;
    408     }
    409     return element;
    410   }
    411 
    412   uint64_t Uint(VectorFormat vform, int index) const {
    413     uint64_t element;
    414     switch (LaneSizeInBitsFromFormat(vform)) {
    415       case 8:
    416         element = register_.Get<uint8_t>(index);
    417         break;
    418       case 16:
    419         element = register_.Get<uint16_t>(index);
    420         break;
    421       case 32:
    422         element = register_.Get<uint32_t>(index);
    423         break;
    424       case 64:
    425         element = register_.Get<uint64_t>(index);
    426         break;
    427       default:
    428         UNREACHABLE();
    429         return 0;
    430     }
    431     return element;
    432   }
    433 
    434   uint64_t UintLeftJustified(VectorFormat vform, int index) const {
    435     return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
    436   }
    437 
    438   int64_t IntLeftJustified(VectorFormat vform, int index) const {
    439     uint64_t value = UintLeftJustified(vform, index);
    440     int64_t result;
    441     memcpy(&result, &value, sizeof(result));
    442     return result;
    443   }
    444 
    445   void SetInt(VectorFormat vform, int index, int64_t value) const {
    446     switch (LaneSizeInBitsFromFormat(vform)) {
    447       case 8:
    448         register_.Insert(index, static_cast<int8_t>(value));
    449         break;
    450       case 16:
    451         register_.Insert(index, static_cast<int16_t>(value));
    452         break;
    453       case 32:
    454         register_.Insert(index, static_cast<int32_t>(value));
    455         break;
    456       case 64:
    457         register_.Insert(index, static_cast<int64_t>(value));
    458         break;
    459       default:
    460         UNREACHABLE();
    461         return;
    462     }
    463   }
    464 
    465   void SetIntArray(VectorFormat vform, const int64_t* src) const {
    466     ClearForWrite(vform);
    467     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    468       SetInt(vform, i, src[i]);
    469     }
    470   }
    471 
    472   void SetUint(VectorFormat vform, int index, uint64_t value) const {
    473     switch (LaneSizeInBitsFromFormat(vform)) {
    474       case 8:
    475         register_.Insert(index, static_cast<uint8_t>(value));
    476         break;
    477       case 16:
    478         register_.Insert(index, static_cast<uint16_t>(value));
    479         break;
    480       case 32:
    481         register_.Insert(index, static_cast<uint32_t>(value));
    482         break;
    483       case 64:
    484         register_.Insert(index, static_cast<uint64_t>(value));
    485         break;
    486       default:
    487         UNREACHABLE();
    488         return;
    489     }
    490   }
    491 
    492   void SetUintArray(VectorFormat vform, const uint64_t* src) const {
    493     ClearForWrite(vform);
    494     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    495       SetUint(vform, i, src[i]);
    496     }
    497   }
    498 
    499   void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const;
    500 
    501   void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const;
    502 
    503   template <typename T>
    504   T Float(int index) const {
    505     return register_.Get<T>(index);
    506   }
    507 
    508   template <typename T>
    509   void SetFloat(int index, T value) const {
    510     register_.Insert(index, value);
    511   }
    512 
    513   // When setting a result in a register of size less than Q, the top bits of
    514   // the Q register must be cleared.
    515   void ClearForWrite(VectorFormat vform) const {
    516     unsigned size = RegisterSizeInBytesFromFormat(vform);
    517     for (unsigned i = size; i < kQRegSize; i++) {
    518       SetUint(kFormat16B, i, 0);
    519     }
    520   }
    521 
    522   // Saturation state for each lane of a vector.
    523   enum Saturation {
    524     kNotSaturated = 0,
    525     kSignedSatPositive = 1 << 0,
    526     kSignedSatNegative = 1 << 1,
    527     kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
    528     kSignedSatUndefined = kSignedSatMask,
    529     kUnsignedSatPositive = 1 << 2,
    530     kUnsignedSatNegative = 1 << 3,
    531     kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
    532     kUnsignedSatUndefined = kUnsignedSatMask
    533   };
    534 
    535   // Getters for saturation state.
    536   Saturation GetSignedSaturation(int index) {
    537     return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
    538   }
    539 
    540   Saturation GetUnsignedSaturation(int index) {
    541     return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
    542   }
    543 
    544   // Setters for saturation state.
    545   void ClearSat(int index) { saturated_[index] = kNotSaturated; }
    546 
    547   void SetSignedSat(int index, bool positive) {
    548     SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
    549   }
    550 
    551   void SetUnsignedSat(int index, bool positive) {
    552     SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
    553   }
    554 
    555   void SetSatFlag(int index, Saturation sat) {
    556     saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
    557     DCHECK_NE(sat & kUnsignedSatMask, kUnsignedSatUndefined);
    558     DCHECK_NE(sat & kSignedSatMask, kSignedSatUndefined);
    559   }
    560 
    561   // Saturate lanes of a vector based on saturation state.
    562   LogicVRegister& SignedSaturate(VectorFormat vform) {
    563     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    564       Saturation sat = GetSignedSaturation(i);
    565       if (sat == kSignedSatPositive) {
    566         SetInt(vform, i, MaxIntFromFormat(vform));
    567       } else if (sat == kSignedSatNegative) {
    568         SetInt(vform, i, MinIntFromFormat(vform));
    569       }
    570     }
    571     return *this;
    572   }
    573 
    574   LogicVRegister& UnsignedSaturate(VectorFormat vform) {
    575     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    576       Saturation sat = GetUnsignedSaturation(i);
    577       if (sat == kUnsignedSatPositive) {
    578         SetUint(vform, i, MaxUintFromFormat(vform));
    579       } else if (sat == kUnsignedSatNegative) {
    580         SetUint(vform, i, 0);
    581       }
    582     }
    583     return *this;
    584   }
    585 
    586   // Getter for rounding state.
    587   bool GetRounding(int index) { return round_[index]; }
    588 
    589   // Setter for rounding state.
    590   void SetRounding(int index, bool round) { round_[index] = round; }
    591 
    592   // Round lanes of a vector based on rounding state.
    593   LogicVRegister& Round(VectorFormat vform) {
    594     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    595       SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0));
    596     }
    597     return *this;
    598   }
    599 
    600   // Unsigned halve lanes of a vector, and use the saturation state to set the
    601   // top bit.
    602   LogicVRegister& Uhalve(VectorFormat vform) {
    603     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    604       uint64_t val = Uint(vform, i);
    605       SetRounding(i, (val & 1) == 1);
    606       val >>= 1;
    607       if (GetUnsignedSaturation(i) != kNotSaturated) {
    608         // If the operation causes unsigned saturation, the bit shifted into the
    609         // most significant bit must be set.
    610         val |= (MaxUintFromFormat(vform) >> 1) + 1;
    611       }
    612       SetInt(vform, i, val);
    613     }
    614     return *this;
    615   }
    616 
    617   // Signed halve lanes of a vector, and use the carry state to set the top bit.
    618   LogicVRegister& Halve(VectorFormat vform) {
    619     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
    620       int64_t val = Int(vform, i);
    621       SetRounding(i, (val & 1) == 1);
    622       val >>= 1;
    623       if (GetSignedSaturation(i) != kNotSaturated) {
    624         // If the operation causes signed saturation, the sign bit must be
    625         // inverted.
    626         val ^= (MaxUintFromFormat(vform) >> 1) + 1;
    627       }
    628       SetInt(vform, i, val);
    629     }
    630     return *this;
    631   }
    632 
    633  private:
    634   SimVRegister& register_;
    635 
    636   // Allocate one saturation state entry per lane; largest register is type Q,
    637   // and lanes can be a minimum of one byte wide.
    638   Saturation saturated_[kQRegSize];
    639 
    640   // Allocate one rounding state entry per lane.
    641   bool round_[kQRegSize];
    642 };
    643 
    644 // Using multiple inheritance here is permitted because {DecoderVisitor} is a
    645 // pure interface class with only pure virtual methods.
    646 class Simulator : public DecoderVisitor, public SimulatorBase {
    647  public:
    648   static void SetRedirectInstruction(Instruction* instruction);
    649   static bool ICacheMatch(void* one, void* two) { return false; }
    650   static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start,
    651                           size_t size) {
    652     USE(i_cache);
    653     USE(start);
    654     USE(size);
    655   }
    656 
    657   explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
    658                      Isolate* isolate = nullptr, FILE* stream = stderr);
    659   Simulator();
    660   ~Simulator();
    661 
    662   // System functions.
    663 
    664   V8_EXPORT_PRIVATE static Simulator* current(v8::internal::Isolate* isolate);
    665 
    666   // A wrapper class that stores an argument for one of the above Call
    667   // functions.
    668   //
    669   // Only arguments up to 64 bits in size are supported.
    670   class CallArgument {
    671    public:
    672     template<typename T>
    673     explicit CallArgument(T argument) {
    674       bits_ = 0;
    675       DCHECK(sizeof(argument) <= sizeof(bits_));
    676       memcpy(&bits_, &argument, sizeof(argument));
    677       type_ = X_ARG;
    678     }
    679 
    680     explicit CallArgument(double argument) {
    681       DCHECK(sizeof(argument) == sizeof(bits_));
    682       memcpy(&bits_, &argument, sizeof(argument));
    683       type_ = D_ARG;
    684     }
    685 
    686     explicit CallArgument(float argument) {
    687       // TODO(all): CallArgument(float) is untested, remove this check once
    688       //            tested.
    689       UNIMPLEMENTED();
    690       // Make the D register a NaN to try to trap errors if the callee expects a
    691       // double. If it expects a float, the callee should ignore the top word.
    692       DCHECK(sizeof(kFP64SignallingNaN) == sizeof(bits_));
    693       memcpy(&bits_, &kFP64SignallingNaN, sizeof(kFP64SignallingNaN));
    694       // Write the float payload to the S register.
    695       DCHECK(sizeof(argument) <= sizeof(bits_));
    696       memcpy(&bits_, &argument, sizeof(argument));
    697       type_ = D_ARG;
    698     }
    699 
    700     // This indicates the end of the arguments list, so that CallArgument
    701     // objects can be passed into varargs functions.
    702     static CallArgument End() { return CallArgument(); }
    703 
    704     int64_t bits() const { return bits_; }
    705     bool IsEnd() const { return type_ == NO_ARG; }
    706     bool IsX() const { return type_ == X_ARG; }
    707     bool IsD() const { return type_ == D_ARG; }
    708 
    709    private:
    710     enum CallArgumentType { X_ARG, D_ARG, NO_ARG };
    711 
    712     // All arguments are aligned to at least 64 bits and we don't support
    713     // passing bigger arguments, so the payload size can be fixed at 64 bits.
    714     int64_t bits_;
    715     CallArgumentType type_;
    716 
    717     CallArgument() { type_ = NO_ARG; }
    718   };
    719 
    720   // Call an arbitrary function taking an arbitrary number of arguments.
    721   template <typename Return, typename... Args>
    722   Return Call(Address entry, Args... args) {
    723     // Convert all arguments to CallArgument.
    724     CallArgument call_args[] = {CallArgument(args)..., CallArgument::End()};
    725     CallImpl(entry, call_args);
    726     return ReadReturn<Return>();
    727   }
    728 
    729   // Start the debugging command line.
    730   void Debug();
    731 
    732   bool GetValue(const char* desc, int64_t* value);
    733 
    734   bool PrintValue(const char* desc);
    735 
    736   // Push an address onto the JS stack.
    737   uintptr_t PushAddress(uintptr_t address);
    738 
    739   // Pop an address from the JS stack.
    740   uintptr_t PopAddress();
    741 
    742   // Accessor to the internal simulator stack area.
    743   uintptr_t StackLimit(uintptr_t c_limit) const;
    744 
    745   void ResetState();
    746 
    747   void DoRuntimeCall(Instruction* instr);
    748 
    749   // Run the simulator.
    750   static const Instruction* kEndOfSimAddress;
    751   void DecodeInstruction();
    752   void Run();
    753   void RunFrom(Instruction* start);
    754 
    755   // Simulation helpers.
    756   template <typename T>
    757   void set_pc(T new_pc) {
    758     DCHECK(sizeof(T) == sizeof(pc_));
    759     memcpy(&pc_, &new_pc, sizeof(T));
    760     pc_modified_ = true;
    761   }
    762   Instruction* pc() { return pc_; }
    763 
    764   void increment_pc() {
    765     if (!pc_modified_) {
    766       pc_ = pc_->following();
    767     }
    768 
    769     pc_modified_ = false;
    770   }
    771 
    772   virtual void Decode(Instruction* instr) {
    773     decoder_->Decode(instr);
    774   }
    775 
    776   void ExecuteInstruction() {
    777     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstrSize));
    778     CheckBreakNext();
    779     Decode(pc_);
    780     increment_pc();
    781     LogAllWrittenRegisters();
    782     CheckBreakpoints();
    783   }
    784 
    785   // Declare all Visitor functions.
    786   #define DECLARE(A)  void Visit##A(Instruction* instr);
    787   VISITOR_LIST(DECLARE)
    788   #undef DECLARE
    789 
    790   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
    791     return ((code == 31) && (r31mode == Reg31IsZeroRegister));
    792   }
    793 
    794   // Register accessors.
    795   // Return 'size' bits of the value of an integer register, as the specified
    796   // type. The value is zero-extended to fill the result.
    797   //
    798   template<typename T>
    799   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    800     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters));
    801     if (IsZeroRegister(code, r31mode)) {
    802       return 0;
    803     }
    804     return registers_[code].Get<T>();
    805   }
    806 
    807   // Common specialized accessors for the reg() template.
    808   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    809     return reg<int32_t>(code, r31mode);
    810   }
    811 
    812   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
    813     return reg<int64_t>(code, r31mode);
    814   }
    815 
    816   enum RegLogMode { LogRegWrites, NoRegLog };
    817 
    818   // Write 'value' into an integer register. The value is zero-extended. This
    819   // behaviour matches AArch64 register writes.
    820   template<typename T>
    821   void set_reg(unsigned code, T value,
    822                Reg31Mode r31mode = Reg31IsZeroRegister) {
    823     set_reg_no_log(code, value, r31mode);
    824     LogRegister(code, r31mode);
    825   }
    826 
    827   // Common specialized accessors for the set_reg() template.
    828   void set_wreg(unsigned code, int32_t value,
    829                 Reg31Mode r31mode = Reg31IsZeroRegister) {
    830     set_reg(code, value, r31mode);
    831   }
    832 
    833   void set_xreg(unsigned code, int64_t value,
    834                 Reg31Mode r31mode = Reg31IsZeroRegister) {
    835     set_reg(code, value, r31mode);
    836   }
    837 
    838   // As above, but don't automatically log the register update.
    839   template <typename T>
    840   void set_reg_no_log(unsigned code, T value,
    841                       Reg31Mode r31mode = Reg31IsZeroRegister) {
    842     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters));
    843     if (!IsZeroRegister(code, r31mode)) {
    844       registers_[code].Set(value);
    845     }
    846   }
    847 
    848   void set_wreg_no_log(unsigned code, int32_t value,
    849                        Reg31Mode r31mode = Reg31IsZeroRegister) {
    850     set_reg_no_log(code, value, r31mode);
    851   }
    852 
    853   void set_xreg_no_log(unsigned code, int64_t value,
    854                        Reg31Mode r31mode = Reg31IsZeroRegister) {
    855     set_reg_no_log(code, value, r31mode);
    856   }
    857 
    858   // Commonly-used special cases.
    859   template<typename T>
    860   void set_lr(T value) {
    861     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kPointerSize));
    862     set_reg(kLinkRegCode, value);
    863   }
    864 
    865   template<typename T>
    866   void set_sp(T value) {
    867     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kPointerSize));
    868     set_reg(31, value, Reg31IsStackPointer);
    869   }
    870 
    871   // Vector register accessors.
    872   // These are equivalent to the integer register accessors, but for vector
    873   // registers.
    874 
    875   // A structure for representing a 128-bit Q register.
    876   struct qreg_t {
    877     uint8_t val[kQRegSize];
    878   };
    879 
    880   // Basic accessor: read the register as the specified type.
    881   template <typename T>
    882   T vreg(unsigned code) const {
    883     static_assert((sizeof(T) == kBRegSize) || (sizeof(T) == kHRegSize) ||
    884                       (sizeof(T) == kSRegSize) || (sizeof(T) == kDRegSize) ||
    885                       (sizeof(T) == kQRegSize),
    886                   "Template type must match size of register.");
    887     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
    888 
    889     return vregisters_[code].Get<T>();
    890   }
    891 
    892   inline SimVRegister& vreg(unsigned code) { return vregisters_[code]; }
    893 
    894   int64_t sp() { return xreg(31, Reg31IsStackPointer); }
    895   int64_t fp() {
    896       return xreg(kFramePointerRegCode, Reg31IsStackPointer);
    897   }
    898   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
    899 
    900   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); }
    901 
    902   // Common specialized accessors for the vreg() template.
    903   uint8_t breg(unsigned code) const { return vreg<uint8_t>(code); }
    904 
    905   float hreg(unsigned code) const { return vreg<uint16_t>(code); }
    906 
    907   float sreg(unsigned code) const { return vreg<float>(code); }
    908 
    909   uint32_t sreg_bits(unsigned code) const { return vreg<uint32_t>(code); }
    910 
    911   double dreg(unsigned code) const { return vreg<double>(code); }
    912 
    913   uint64_t dreg_bits(unsigned code) const { return vreg<uint64_t>(code); }
    914 
    915   qreg_t qreg(unsigned code) const { return vreg<qreg_t>(code); }
    916 
    917   // As above, with parameterized size and return type. The value is
    918   // either zero-extended or truncated to fit, as required.
    919   template <typename T>
    920   T vreg(unsigned size, unsigned code) const {
    921     uint64_t raw = 0;
    922     T result;
    923 
    924     switch (size) {
    925       case kSRegSize:
    926         raw = vreg<uint32_t>(code);
    927         break;
    928       case kDRegSize:
    929         raw = vreg<uint64_t>(code);
    930         break;
    931       default:
    932         UNREACHABLE();
    933     }
    934 
    935     static_assert(sizeof(result) <= sizeof(raw),
    936                   "Template type must be <= 64 bits.");
    937     // Copy the result and truncate to fit. This assumes a little-endian host.
    938     memcpy(&result, &raw, sizeof(result));
    939     return result;
    940   }
    941 
    942   // Write 'value' into a floating-point register. The value is zero-extended.
    943   // This behaviour matches AArch64 register writes.
    944   template <typename T>
    945   void set_vreg(unsigned code, T value, RegLogMode log_mode = LogRegWrites) {
    946     static_assert(
    947         (sizeof(value) == kBRegSize) || (sizeof(value) == kHRegSize) ||
    948             (sizeof(value) == kSRegSize) || (sizeof(value) == kDRegSize) ||
    949             (sizeof(value) == kQRegSize),
    950         "Template type must match size of register.");
    951     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
    952     vregisters_[code].Set(value);
    953 
    954     if (log_mode == LogRegWrites) {
    955       LogVRegister(code, GetPrintRegisterFormat(value));
    956     }
    957   }
    958 
    959   // Common specialized accessors for the set_vreg() template.
    960   void set_breg(unsigned code, int8_t value,
    961                 RegLogMode log_mode = LogRegWrites) {
    962     set_vreg(code, value, log_mode);
    963   }
    964 
    965   void set_hreg(unsigned code, int16_t value,
    966                 RegLogMode log_mode = LogRegWrites) {
    967     set_vreg(code, value, log_mode);
    968   }
    969 
    970   void set_sreg(unsigned code, float value,
    971                 RegLogMode log_mode = LogRegWrites) {
    972     set_vreg(code, value, log_mode);
    973   }
    974 
    975   void set_sreg_bits(unsigned code, uint32_t value,
    976                      RegLogMode log_mode = LogRegWrites) {
    977     set_vreg(code, value, log_mode);
    978   }
    979 
    980   void set_dreg(unsigned code, double value,
    981                 RegLogMode log_mode = LogRegWrites) {
    982     set_vreg(code, value, log_mode);
    983   }
    984 
    985   void set_dreg_bits(unsigned code, uint64_t value,
    986                      RegLogMode log_mode = LogRegWrites) {
    987     set_vreg(code, value, log_mode);
    988   }
    989 
    990   void set_qreg(unsigned code, qreg_t value,
    991                 RegLogMode log_mode = LogRegWrites) {
    992     set_vreg(code, value, log_mode);
    993   }
    994 
    995   // As above, but don't automatically log the register update.
    996   template <typename T>
    997   void set_vreg_no_log(unsigned code, T value) {
    998     STATIC_ASSERT((sizeof(value) == kBRegSize) ||
    999                   (sizeof(value) == kHRegSize) ||
   1000                   (sizeof(value) == kSRegSize) ||
   1001                   (sizeof(value) == kDRegSize) || (sizeof(value) == kQRegSize));
   1002     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
   1003     vregisters_[code].Set(value);
   1004   }
   1005 
   1006   void set_breg_no_log(unsigned code, uint8_t value) {
   1007     set_vreg_no_log(code, value);
   1008   }
   1009 
   1010   void set_hreg_no_log(unsigned code, uint16_t value) {
   1011     set_vreg_no_log(code, value);
   1012   }
   1013 
   1014   void set_sreg_no_log(unsigned code, float value) {
   1015     set_vreg_no_log(code, value);
   1016   }
   1017 
   1018   void set_dreg_no_log(unsigned code, double value) {
   1019     set_vreg_no_log(code, value);
   1020   }
   1021 
   1022   void set_qreg_no_log(unsigned code, qreg_t value) {
   1023     set_vreg_no_log(code, value);
   1024   }
   1025 
   1026   SimSystemRegister& nzcv() { return nzcv_; }
   1027   SimSystemRegister& fpcr() { return fpcr_; }
   1028   FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); }
   1029   bool DN() { return fpcr_.DN() != 0; }
   1030 
   1031   // Debug helpers
   1032 
   1033   // Simulator breakpoints.
   1034   struct Breakpoint {
   1035     Instruction* location;
   1036     bool enabled;
   1037   };
   1038   std::vector<Breakpoint> breakpoints_;
   1039   void SetBreakpoint(Instruction* breakpoint);
   1040   void ListBreakpoints();
   1041   void CheckBreakpoints();
   1042 
   1043   // Helpers for the 'next' command.
   1044   // When this is set, the Simulator will insert a breakpoint after the next BL
   1045   // instruction it meets.
   1046   bool break_on_next_;
   1047   // Check if the Simulator should insert a break after the current instruction
   1048   // for the 'next' command.
   1049   void CheckBreakNext();
   1050 
   1051   // Disassemble instruction at the given address.
   1052   void PrintInstructionsAt(Instruction* pc, uint64_t count);
   1053 
   1054   // Print all registers of the specified types.
   1055   void PrintRegisters();
   1056   void PrintVRegisters();
   1057   void PrintSystemRegisters();
   1058 
   1059   // As above, but only print the registers that have been updated.
   1060   void PrintWrittenRegisters();
   1061   void PrintWrittenVRegisters();
   1062 
   1063   // As above, but respect LOG_REG and LOG_VREG.
   1064   void LogWrittenRegisters() {
   1065     if (log_parameters() & LOG_REGS) PrintWrittenRegisters();
   1066   }
   1067   void LogWrittenVRegisters() {
   1068     if (log_parameters() & LOG_VREGS) PrintWrittenVRegisters();
   1069   }
   1070   void LogAllWrittenRegisters() {
   1071     LogWrittenRegisters();
   1072     LogWrittenVRegisters();
   1073   }
   1074 
   1075   // Specify relevant register formats for Print(V)Register and related helpers.
   1076   enum PrintRegisterFormat {
   1077     // The lane size.
   1078     kPrintRegLaneSizeB = 0 << 0,
   1079     kPrintRegLaneSizeH = 1 << 0,
   1080     kPrintRegLaneSizeS = 2 << 0,
   1081     kPrintRegLaneSizeW = kPrintRegLaneSizeS,
   1082     kPrintRegLaneSizeD = 3 << 0,
   1083     kPrintRegLaneSizeX = kPrintRegLaneSizeD,
   1084     kPrintRegLaneSizeQ = 4 << 0,
   1085 
   1086     kPrintRegLaneSizeOffset = 0,
   1087     kPrintRegLaneSizeMask = 7 << 0,
   1088 
   1089     // The lane count.
   1090     kPrintRegAsScalar = 0,
   1091     kPrintRegAsDVector = 1 << 3,
   1092     kPrintRegAsQVector = 2 << 3,
   1093 
   1094     kPrintRegAsVectorMask = 3 << 3,
   1095 
   1096     // Indicate floating-point format lanes. (This flag is only supported for S-
   1097     // and D-sized lanes.)
   1098     kPrintRegAsFP = 1 << 5,
   1099 
   1100     // Supported combinations.
   1101 
   1102     kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
   1103     kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
   1104     kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
   1105     kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
   1106 
   1107     kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
   1108     kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
   1109     kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
   1110     kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
   1111     kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
   1112     kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
   1113     kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
   1114     kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
   1115     kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
   1116     kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
   1117     kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
   1118     kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
   1119     kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
   1120     kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
   1121     kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
   1122     kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
   1123     kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
   1124   };
   1125 
   1126   unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
   1127     return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
   1128   }
   1129 
   1130   unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
   1131     return 1 << GetPrintRegLaneSizeInBytesLog2(format);
   1132   }
   1133 
   1134   unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
   1135     if (format & kPrintRegAsDVector) return kDRegSizeLog2;
   1136     if (format & kPrintRegAsQVector) return kQRegSizeLog2;
   1137 
   1138     // Scalar types.
   1139     return GetPrintRegLaneSizeInBytesLog2(format);
   1140   }
   1141 
   1142   unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
   1143     return 1 << GetPrintRegSizeInBytesLog2(format);
   1144   }
   1145 
   1146   unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
   1147     unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
   1148     unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
   1149     DCHECK_GE(reg_size_log2, lane_size_log2);
   1150     return 1 << (reg_size_log2 - lane_size_log2);
   1151   }
   1152 
   1153   template <typename T>
   1154   PrintRegisterFormat GetPrintRegisterFormat(T value) {
   1155     return GetPrintRegisterFormatForSize(sizeof(value));
   1156   }
   1157 
   1158   PrintRegisterFormat GetPrintRegisterFormat(double value) {
   1159     static_assert(sizeof(value) == kDRegSize,
   1160                   "D register must be size of double.");
   1161     return GetPrintRegisterFormatForSizeFP(sizeof(value));
   1162   }
   1163 
   1164   PrintRegisterFormat GetPrintRegisterFormat(float value) {
   1165     static_assert(sizeof(value) == kSRegSize,
   1166                   "S register must be size of float.");
   1167     return GetPrintRegisterFormatForSizeFP(sizeof(value));
   1168   }
   1169 
   1170   PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
   1171   PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
   1172 
   1173   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t reg_size,
   1174                                                     size_t lane_size);
   1175 
   1176   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t size) {
   1177     return GetPrintRegisterFormatForSize(size, size);
   1178   }
   1179 
   1180   PrintRegisterFormat GetPrintRegisterFormatForSizeFP(size_t size) {
   1181     switch (size) {
   1182       default:
   1183         UNREACHABLE();
   1184       case kDRegSize:
   1185         return kPrintDReg;
   1186       case kSRegSize:
   1187         return kPrintSReg;
   1188     }
   1189   }
   1190 
   1191   PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
   1192     if ((GetPrintRegLaneSizeInBytes(format) == kSRegSize) ||
   1193         (GetPrintRegLaneSizeInBytes(format) == kDRegSize)) {
   1194       return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
   1195     }
   1196     return format;
   1197   }
   1198 
   1199   // Print individual register values (after update).
   1200   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
   1201   void PrintVRegister(unsigned code, PrintRegisterFormat sizes);
   1202   void PrintSystemRegister(SystemRegister id);
   1203 
   1204   // Like Print* (above), but respect log_parameters().
   1205   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
   1206     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
   1207   }
   1208   void LogVRegister(unsigned code, PrintRegisterFormat format) {
   1209     if (log_parameters() & LOG_VREGS) PrintVRegister(code, format);
   1210   }
   1211   void LogSystemRegister(SystemRegister id) {
   1212     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
   1213   }
   1214 
   1215   // Print memory accesses.
   1216   void PrintRead(uintptr_t address, unsigned reg_code,
   1217                  PrintRegisterFormat format);
   1218   void PrintWrite(uintptr_t address, unsigned reg_code,
   1219                   PrintRegisterFormat format);
   1220   void PrintVRead(uintptr_t address, unsigned reg_code,
   1221                   PrintRegisterFormat format, unsigned lane);
   1222   void PrintVWrite(uintptr_t address, unsigned reg_code,
   1223                    PrintRegisterFormat format, unsigned lane);
   1224 
   1225   // Like Print* (above), but respect log_parameters().
   1226   void LogRead(uintptr_t address, unsigned reg_code,
   1227                PrintRegisterFormat format) {
   1228     if (log_parameters() & LOG_REGS) PrintRead(address, reg_code, format);
   1229   }
   1230   void LogWrite(uintptr_t address, unsigned reg_code,
   1231                 PrintRegisterFormat format) {
   1232     if (log_parameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
   1233   }
   1234   void LogVRead(uintptr_t address, unsigned reg_code,
   1235                 PrintRegisterFormat format, unsigned lane = 0) {
   1236     if (log_parameters() & LOG_VREGS) {
   1237       PrintVRead(address, reg_code, format, lane);
   1238     }
   1239   }
   1240   void LogVWrite(uintptr_t address, unsigned reg_code,
   1241                  PrintRegisterFormat format, unsigned lane = 0) {
   1242     if (log_parameters() & LOG_WRITE) {
   1243       PrintVWrite(address, reg_code, format, lane);
   1244     }
   1245   }
   1246 
   1247   int log_parameters() { return log_parameters_; }
   1248   void set_log_parameters(int new_parameters) {
   1249     log_parameters_ = new_parameters;
   1250     if (!decoder_) {
   1251       if (new_parameters & LOG_DISASM) {
   1252         PrintF("Run --debug-sim to dynamically turn on disassembler\n");
   1253       }
   1254       return;
   1255     }
   1256     if (new_parameters & LOG_DISASM) {
   1257       decoder_->InsertVisitorBefore(print_disasm_, this);
   1258     } else {
   1259       decoder_->RemoveVisitor(print_disasm_);
   1260     }
   1261   }
   1262 
   1263   // Helper functions for register tracing.
   1264   void PrintRegisterRawHelper(unsigned code, Reg31Mode r31mode,
   1265                               int size_in_bytes = kXRegSize);
   1266   void PrintVRegisterRawHelper(unsigned code, int bytes = kQRegSize,
   1267                                int lsb = 0);
   1268   void PrintVRegisterFPHelper(unsigned code, unsigned lane_size_in_bytes,
   1269                               int lane_count = 1, int rightmost_lane = 0);
   1270 
   1271   static inline const char* WRegNameForCode(unsigned code,
   1272       Reg31Mode mode = Reg31IsZeroRegister);
   1273   static inline const char* XRegNameForCode(unsigned code,
   1274       Reg31Mode mode = Reg31IsZeroRegister);
   1275   static inline const char* SRegNameForCode(unsigned code);
   1276   static inline const char* DRegNameForCode(unsigned code);
   1277   static inline const char* VRegNameForCode(unsigned code);
   1278   static inline int CodeFromName(const char* name);
   1279 
   1280  protected:
   1281   // Simulation helpers ------------------------------------
   1282   bool ConditionPassed(Condition cond) {
   1283     SimSystemRegister& flags = nzcv();
   1284     switch (cond) {
   1285       case eq:
   1286         return flags.Z();
   1287       case ne:
   1288         return !flags.Z();
   1289       case hs:
   1290         return flags.C();
   1291       case lo:
   1292         return !flags.C();
   1293       case mi:
   1294         return flags.N();
   1295       case pl:
   1296         return !flags.N();
   1297       case vs:
   1298         return flags.V();
   1299       case vc:
   1300         return !flags.V();
   1301       case hi:
   1302         return flags.C() && !flags.Z();
   1303       case ls:
   1304         return !(flags.C() && !flags.Z());
   1305       case ge:
   1306         return flags.N() == flags.V();
   1307       case lt:
   1308         return flags.N() != flags.V();
   1309       case gt:
   1310         return !flags.Z() && (flags.N() == flags.V());
   1311       case le:
   1312         return !(!flags.Z() && (flags.N() == flags.V()));
   1313       case nv:  // Fall through.
   1314       case al:
   1315         return true;
   1316       default:
   1317         UNREACHABLE();
   1318     }
   1319   }
   1320 
   1321   bool ConditionFailed(Condition cond) {
   1322     return !ConditionPassed(cond);
   1323   }
   1324 
   1325   template<typename T>
   1326   void AddSubHelper(Instruction* instr, T op2);
   1327   template <typename T>
   1328   T AddWithCarry(bool set_flags, T left, T right, int carry_in = 0);
   1329   template<typename T>
   1330   void AddSubWithCarry(Instruction* instr);
   1331   template<typename T>
   1332   void LogicalHelper(Instruction* instr, T op2);
   1333   template<typename T>
   1334   void ConditionalCompareHelper(Instruction* instr, T op2);
   1335   void LoadStoreHelper(Instruction* instr,
   1336                        int64_t offset,
   1337                        AddrMode addrmode);
   1338   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
   1339   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
   1340                              AddrMode addrmode);
   1341   void LoadStoreWriteBack(unsigned addr_reg,
   1342                           int64_t offset,
   1343                           AddrMode addrmode);
   1344   void NEONLoadStoreMultiStructHelper(const Instruction* instr,
   1345                                       AddrMode addr_mode);
   1346   void NEONLoadStoreSingleStructHelper(const Instruction* instr,
   1347                                        AddrMode addr_mode);
   1348   void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
   1349 
   1350   // Memory read helpers.
   1351   template <typename T, typename A>
   1352   T MemoryRead(A address) {
   1353     T value;
   1354     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
   1355                   (sizeof(value) == 4) || (sizeof(value) == 8) ||
   1356                   (sizeof(value) == 16));
   1357     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
   1358     return value;
   1359   }
   1360 
   1361   // Memory write helpers.
   1362   template <typename T, typename A>
   1363   void MemoryWrite(A address, T value) {
   1364     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
   1365                   (sizeof(value) == 4) || (sizeof(value) == 8) ||
   1366                   (sizeof(value) == 16));
   1367     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
   1368   }
   1369 
   1370   template <typename T>
   1371   T ShiftOperand(T value,
   1372                  Shift shift_type,
   1373                  unsigned amount);
   1374   template <typename T>
   1375   T ExtendValue(T value,
   1376                 Extend extend_type,
   1377                 unsigned left_shift = 0);
   1378   template <typename T>
   1379   void Extract(Instruction* instr);
   1380   template <typename T>
   1381   void DataProcessing2Source(Instruction* instr);
   1382   template <typename T>
   1383   void BitfieldHelper(Instruction* instr);
   1384   uint16_t PolynomialMult(uint8_t op1, uint8_t op2);
   1385 
   1386   void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
   1387   void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
   1388   void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
   1389   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1390            uint64_t addr);
   1391   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1392            int index, uint64_t addr);
   1393   void ld2r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1394             uint64_t addr);
   1395   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1396            LogicVRegister dst3, uint64_t addr);
   1397   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1398            LogicVRegister dst3, int index, uint64_t addr);
   1399   void ld3r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1400             LogicVRegister dst3, uint64_t addr);
   1401   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1402            LogicVRegister dst3, LogicVRegister dst4, uint64_t addr);
   1403   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1404            LogicVRegister dst3, LogicVRegister dst4, int index, uint64_t addr);
   1405   void ld4r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
   1406             LogicVRegister dst3, LogicVRegister dst4, uint64_t addr);
   1407   void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
   1408   void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
   1409   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1410            uint64_t addr);
   1411   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1412            int index, uint64_t addr);
   1413   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1414            LogicVRegister src3, uint64_t addr);
   1415   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1416            LogicVRegister src3, int index, uint64_t addr);
   1417   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1418            LogicVRegister src3, LogicVRegister src4, uint64_t addr);
   1419   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
   1420            LogicVRegister src3, LogicVRegister src4, int index, uint64_t addr);
   1421   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst,
   1422                      const LogicVRegister& src1, const LogicVRegister& src2,
   1423                      Condition cond);
   1424   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst,
   1425                      const LogicVRegister& src1, int imm, Condition cond);
   1426   LogicVRegister cmptst(VectorFormat vform, LogicVRegister dst,
   1427                         const LogicVRegister& src1, const LogicVRegister& src2);
   1428   LogicVRegister add(VectorFormat vform, LogicVRegister dst,
   1429                      const LogicVRegister& src1, const LogicVRegister& src2);
   1430   LogicVRegister addp(VectorFormat vform, LogicVRegister dst,
   1431                       const LogicVRegister& src1, const LogicVRegister& src2);
   1432   LogicVRegister mla(VectorFormat vform, LogicVRegister dst,
   1433                      const LogicVRegister& src1, const LogicVRegister& src2);
   1434   LogicVRegister mls(VectorFormat vform, LogicVRegister dst,
   1435                      const LogicVRegister& src1, const LogicVRegister& src2);
   1436   LogicVRegister mul(VectorFormat vform, LogicVRegister dst,
   1437                      const LogicVRegister& src1, const LogicVRegister& src2);
   1438   LogicVRegister mul(VectorFormat vform, LogicVRegister dst,
   1439                      const LogicVRegister& src1, const LogicVRegister& src2,
   1440                      int index);
   1441   LogicVRegister mla(VectorFormat vform, LogicVRegister dst,
   1442                      const LogicVRegister& src1, const LogicVRegister& src2,
   1443                      int index);
   1444   LogicVRegister mls(VectorFormat vform, LogicVRegister dst,
   1445                      const LogicVRegister& src1, const LogicVRegister& src2,
   1446                      int index);
   1447   LogicVRegister pmul(VectorFormat vform, LogicVRegister dst,
   1448                       const LogicVRegister& src1, const LogicVRegister& src2);
   1449 
   1450   typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
   1451                                                    LogicVRegister dst,
   1452                                                    const LogicVRegister& src1,
   1453                                                    const LogicVRegister& src2,
   1454                                                    int index);
   1455   LogicVRegister fmul(VectorFormat vform, LogicVRegister dst,
   1456                       const LogicVRegister& src1, const LogicVRegister& src2,
   1457                       int index);
   1458   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
   1459                       const LogicVRegister& src1, const LogicVRegister& src2,
   1460                       int index);
   1461   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
   1462                       const LogicVRegister& src1, const LogicVRegister& src2,
   1463                       int index);
   1464   LogicVRegister fmulx(VectorFormat vform, LogicVRegister dst,
   1465                        const LogicVRegister& src1, const LogicVRegister& src2,
   1466                        int index);
   1467   LogicVRegister smull(VectorFormat vform, LogicVRegister dst,
   1468                        const LogicVRegister& src1, const LogicVRegister& src2,
   1469                        int index);
   1470   LogicVRegister smull2(VectorFormat vform, LogicVRegister dst,
   1471                         const LogicVRegister& src1, const LogicVRegister& src2,
   1472                         int index);
   1473   LogicVRegister umull(VectorFormat vform, LogicVRegister dst,
   1474                        const LogicVRegister& src1, const LogicVRegister& src2,
   1475                        int index);
   1476   LogicVRegister umull2(VectorFormat vform, LogicVRegister dst,
   1477                         const LogicVRegister& src1, const LogicVRegister& src2,
   1478                         int index);
   1479   LogicVRegister smlal(VectorFormat vform, LogicVRegister dst,
   1480                        const LogicVRegister& src1, const LogicVRegister& src2,
   1481                        int index);
   1482   LogicVRegister smlal2(VectorFormat vform, LogicVRegister dst,
   1483                         const LogicVRegister& src1, const LogicVRegister& src2,
   1484                         int index);
   1485   LogicVRegister umlal(VectorFormat vform, LogicVRegister dst,
   1486                        const LogicVRegister& src1, const LogicVRegister& src2,
   1487                        int index);
   1488   LogicVRegister umlal2(VectorFormat vform, LogicVRegister dst,
   1489                         const LogicVRegister& src1, const LogicVRegister& src2,
   1490                         int index);
   1491   LogicVRegister smlsl(VectorFormat vform, LogicVRegister dst,
   1492                        const LogicVRegister& src1, const LogicVRegister& src2,
   1493                        int index);
   1494   LogicVRegister smlsl2(VectorFormat vform, LogicVRegister dst,
   1495                         const LogicVRegister& src1, const LogicVRegister& src2,
   1496                         int index);
   1497   LogicVRegister umlsl(VectorFormat vform, LogicVRegister dst,
   1498                        const LogicVRegister& src1, const LogicVRegister& src2,
   1499                        int index);
   1500   LogicVRegister umlsl2(VectorFormat vform, LogicVRegister dst,
   1501                         const LogicVRegister& src1, const LogicVRegister& src2,
   1502                         int index);
   1503   LogicVRegister sqdmull(VectorFormat vform, LogicVRegister dst,
   1504                          const LogicVRegister& src1, const LogicVRegister& src2,
   1505                          int index);
   1506   LogicVRegister sqdmull2(VectorFormat vform, LogicVRegister dst,
   1507                           const LogicVRegister& src1,
   1508                           const LogicVRegister& src2, int index);
   1509   LogicVRegister sqdmlal(VectorFormat vform, LogicVRegister dst,
   1510                          const LogicVRegister& src1, const LogicVRegister& src2,
   1511                          int index);
   1512   LogicVRegister sqdmlal2(VectorFormat vform, LogicVRegister dst,
   1513                           const LogicVRegister& src1,
   1514                           const LogicVRegister& src2, int index);
   1515   LogicVRegister sqdmlsl(VectorFormat vform, LogicVRegister dst,
   1516                          const LogicVRegister& src1, const LogicVRegister& src2,
   1517                          int index);
   1518   LogicVRegister sqdmlsl2(VectorFormat vform, LogicVRegister dst,
   1519                           const LogicVRegister& src1,
   1520                           const LogicVRegister& src2, int index);
   1521   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst,
   1522                          const LogicVRegister& src1, const LogicVRegister& src2,
   1523                          int index);
   1524   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst,
   1525                           const LogicVRegister& src1,
   1526                           const LogicVRegister& src2, int index);
   1527   LogicVRegister sub(VectorFormat vform, LogicVRegister dst,
   1528                      const LogicVRegister& src1, const LogicVRegister& src2);
   1529   LogicVRegister and_(VectorFormat vform, LogicVRegister dst,
   1530                       const LogicVRegister& src1, const LogicVRegister& src2);
   1531   LogicVRegister orr(VectorFormat vform, LogicVRegister dst,
   1532                      const LogicVRegister& src1, const LogicVRegister& src2);
   1533   LogicVRegister orn(VectorFormat vform, LogicVRegister dst,
   1534                      const LogicVRegister& src1, const LogicVRegister& src2);
   1535   LogicVRegister eor(VectorFormat vform, LogicVRegister dst,
   1536                      const LogicVRegister& src1, const LogicVRegister& src2);
   1537   LogicVRegister bic(VectorFormat vform, LogicVRegister dst,
   1538                      const LogicVRegister& src1, const LogicVRegister& src2);
   1539   LogicVRegister bic(VectorFormat vform, LogicVRegister dst,
   1540                      const LogicVRegister& src, uint64_t imm);
   1541   LogicVRegister bif(VectorFormat vform, LogicVRegister dst,
   1542                      const LogicVRegister& src1, const LogicVRegister& src2);
   1543   LogicVRegister bit(VectorFormat vform, LogicVRegister dst,
   1544                      const LogicVRegister& src1, const LogicVRegister& src2);
   1545   LogicVRegister bsl(VectorFormat vform, LogicVRegister dst,
   1546                      const LogicVRegister& src1, const LogicVRegister& src2);
   1547   LogicVRegister cls(VectorFormat vform, LogicVRegister dst,
   1548                      const LogicVRegister& src);
   1549   LogicVRegister clz(VectorFormat vform, LogicVRegister dst,
   1550                      const LogicVRegister& src);
   1551   LogicVRegister cnt(VectorFormat vform, LogicVRegister dst,
   1552                      const LogicVRegister& src);
   1553   LogicVRegister not_(VectorFormat vform, LogicVRegister dst,
   1554                       const LogicVRegister& src);
   1555   LogicVRegister rbit(VectorFormat vform, LogicVRegister dst,
   1556                       const LogicVRegister& src);
   1557   LogicVRegister rev(VectorFormat vform, LogicVRegister dst,
   1558                      const LogicVRegister& src, int revSize);
   1559   LogicVRegister rev16(VectorFormat vform, LogicVRegister dst,
   1560                        const LogicVRegister& src);
   1561   LogicVRegister rev32(VectorFormat vform, LogicVRegister dst,
   1562                        const LogicVRegister& src);
   1563   LogicVRegister rev64(VectorFormat vform, LogicVRegister dst,
   1564                        const LogicVRegister& src);
   1565   LogicVRegister addlp(VectorFormat vform, LogicVRegister dst,
   1566                        const LogicVRegister& src, bool is_signed,
   1567                        bool do_accumulate);
   1568   LogicVRegister saddlp(VectorFormat vform, LogicVRegister dst,
   1569                         const LogicVRegister& src);
   1570   LogicVRegister uaddlp(VectorFormat vform, LogicVRegister dst,
   1571                         const LogicVRegister& src);
   1572   LogicVRegister sadalp(VectorFormat vform, LogicVRegister dst,
   1573                         const LogicVRegister& src);
   1574   LogicVRegister uadalp(VectorFormat vform, LogicVRegister dst,
   1575                         const LogicVRegister& src);
   1576   LogicVRegister ext(VectorFormat vform, LogicVRegister dst,
   1577                      const LogicVRegister& src1, const LogicVRegister& src2,
   1578                      int index);
   1579   LogicVRegister ins_element(VectorFormat vform, LogicVRegister dst,
   1580                              int dst_index, const LogicVRegister& src,
   1581                              int src_index);
   1582   LogicVRegister ins_immediate(VectorFormat vform, LogicVRegister dst,
   1583                                int dst_index, uint64_t imm);
   1584   LogicVRegister dup_element(VectorFormat vform, LogicVRegister dst,
   1585                              const LogicVRegister& src, int src_index);
   1586   LogicVRegister dup_immediate(VectorFormat vform, LogicVRegister dst,
   1587                                uint64_t imm);
   1588   LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
   1589   LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
   1590   LogicVRegister orr(VectorFormat vform, LogicVRegister dst,
   1591                      const LogicVRegister& src, uint64_t imm);
   1592   LogicVRegister sshl(VectorFormat vform, LogicVRegister dst,
   1593                       const LogicVRegister& src1, const LogicVRegister& src2);
   1594   LogicVRegister ushl(VectorFormat vform, LogicVRegister dst,
   1595                       const LogicVRegister& src1, const LogicVRegister& src2);
   1596   LogicVRegister SMinMax(VectorFormat vform, LogicVRegister dst,
   1597                          const LogicVRegister& src1, const LogicVRegister& src2,
   1598                          bool max);
   1599   LogicVRegister smax(VectorFormat vform, LogicVRegister dst,
   1600                       const LogicVRegister& src1, const LogicVRegister& src2);
   1601   LogicVRegister smin(VectorFormat vform, LogicVRegister dst,
   1602                       const LogicVRegister& src1, const LogicVRegister& src2);
   1603   LogicVRegister SMinMaxP(VectorFormat vform, LogicVRegister dst,
   1604                           const LogicVRegister& src1,
   1605                           const LogicVRegister& src2, bool max);
   1606   LogicVRegister smaxp(VectorFormat vform, LogicVRegister dst,
   1607                        const LogicVRegister& src1, const LogicVRegister& src2);
   1608   LogicVRegister sminp(VectorFormat vform, LogicVRegister dst,
   1609                        const LogicVRegister& src1, const LogicVRegister& src2);
   1610   LogicVRegister addp(VectorFormat vform, LogicVRegister dst,
   1611                       const LogicVRegister& src);
   1612   LogicVRegister addv(VectorFormat vform, LogicVRegister dst,
   1613                       const LogicVRegister& src);
   1614   LogicVRegister uaddlv(VectorFormat vform, LogicVRegister dst,
   1615                         const LogicVRegister& src);
   1616   LogicVRegister saddlv(VectorFormat vform, LogicVRegister dst,
   1617                         const LogicVRegister& src);
   1618   LogicVRegister SMinMaxV(VectorFormat vform, LogicVRegister dst,
   1619                           const LogicVRegister& src, bool max);
   1620   LogicVRegister smaxv(VectorFormat vform, LogicVRegister dst,
   1621                        const LogicVRegister& src);
   1622   LogicVRegister sminv(VectorFormat vform, LogicVRegister dst,
   1623                        const LogicVRegister& src);
   1624   LogicVRegister uxtl(VectorFormat vform, LogicVRegister dst,
   1625                       const LogicVRegister& src);
   1626   LogicVRegister uxtl2(VectorFormat vform, LogicVRegister dst,
   1627                        const LogicVRegister& src);
   1628   LogicVRegister sxtl(VectorFormat vform, LogicVRegister dst,
   1629                       const LogicVRegister& src);
   1630   LogicVRegister sxtl2(VectorFormat vform, LogicVRegister dst,
   1631                        const LogicVRegister& src);
   1632   LogicVRegister Table(VectorFormat vform, LogicVRegister dst,
   1633                        const LogicVRegister& ind, bool zero_out_of_bounds,
   1634                        const LogicVRegister* tab1,
   1635                        const LogicVRegister* tab2 = nullptr,
   1636                        const LogicVRegister* tab3 = nullptr,
   1637                        const LogicVRegister* tab4 = nullptr);
   1638   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
   1639                      const LogicVRegister& tab, const LogicVRegister& ind);
   1640   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
   1641                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1642                      const LogicVRegister& ind);
   1643   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
   1644                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1645                      const LogicVRegister& tab3, const LogicVRegister& ind);
   1646   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
   1647                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1648                      const LogicVRegister& tab3, const LogicVRegister& tab4,
   1649                      const LogicVRegister& ind);
   1650   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
   1651                      const LogicVRegister& tab, const LogicVRegister& ind);
   1652   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
   1653                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1654                      const LogicVRegister& ind);
   1655   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
   1656                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1657                      const LogicVRegister& tab3, const LogicVRegister& ind);
   1658   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
   1659                      const LogicVRegister& tab, const LogicVRegister& tab2,
   1660                      const LogicVRegister& tab3, const LogicVRegister& tab4,
   1661                      const LogicVRegister& ind);
   1662   LogicVRegister uaddl(VectorFormat vform, LogicVRegister dst,
   1663                        const LogicVRegister& src1, const LogicVRegister& src2);
   1664   LogicVRegister uaddl2(VectorFormat vform, LogicVRegister dst,
   1665                         const LogicVRegister& src1, const LogicVRegister& src2);
   1666   LogicVRegister uaddw(VectorFormat vform, LogicVRegister dst,
   1667                        const LogicVRegister& src1, const LogicVRegister& src2);
   1668   LogicVRegister uaddw2(VectorFormat vform, LogicVRegister dst,
   1669                         const LogicVRegister& src1, const LogicVRegister& src2);
   1670   LogicVRegister saddl(VectorFormat vform, LogicVRegister dst,
   1671                        const LogicVRegister& src1, const LogicVRegister& src2);
   1672   LogicVRegister saddl2(VectorFormat vform, LogicVRegister dst,
   1673                         const LogicVRegister& src1, const LogicVRegister& src2);
   1674   LogicVRegister saddw(VectorFormat vform, LogicVRegister dst,
   1675                        const LogicVRegister& src1, const LogicVRegister& src2);
   1676   LogicVRegister saddw2(VectorFormat vform, LogicVRegister dst,
   1677                         const LogicVRegister& src1, const LogicVRegister& src2);
   1678   LogicVRegister usubl(VectorFormat vform, LogicVRegister dst,
   1679                        const LogicVRegister& src1, const LogicVRegister& src2);
   1680   LogicVRegister usubl2(VectorFormat vform, LogicVRegister dst,
   1681                         const LogicVRegister& src1, const LogicVRegister& src2);
   1682   LogicVRegister usubw(VectorFormat vform, LogicVRegister dst,
   1683                        const LogicVRegister& src1, const LogicVRegister& src2);
   1684   LogicVRegister usubw2(VectorFormat vform, LogicVRegister dst,
   1685                         const LogicVRegister& src1, const LogicVRegister& src2);
   1686   LogicVRegister ssubl(VectorFormat vform, LogicVRegister dst,
   1687                        const LogicVRegister& src1, const LogicVRegister& src2);
   1688   LogicVRegister ssubl2(VectorFormat vform, LogicVRegister dst,
   1689                         const LogicVRegister& src1, const LogicVRegister& src2);
   1690   LogicVRegister ssubw(VectorFormat vform, LogicVRegister dst,
   1691                        const LogicVRegister& src1, const LogicVRegister& src2);
   1692   LogicVRegister ssubw2(VectorFormat vform, LogicVRegister dst,
   1693                         const LogicVRegister& src1, const LogicVRegister& src2);
   1694   LogicVRegister UMinMax(VectorFormat vform, LogicVRegister dst,
   1695                          const LogicVRegister& src1, const LogicVRegister& src2,
   1696                          bool max);
   1697   LogicVRegister umax(VectorFormat vform, LogicVRegister dst,
   1698                       const LogicVRegister& src1, const LogicVRegister& src2);
   1699   LogicVRegister umin(VectorFormat vform, LogicVRegister dst,
   1700                       const LogicVRegister& src1, const LogicVRegister& src2);
   1701   LogicVRegister UMinMaxP(VectorFormat vform, LogicVRegister dst,
   1702                           const LogicVRegister& src1,
   1703                           const LogicVRegister& src2, bool max);
   1704   LogicVRegister umaxp(VectorFormat vform, LogicVRegister dst,
   1705                        const LogicVRegister& src1, const LogicVRegister& src2);
   1706   LogicVRegister uminp(VectorFormat vform, LogicVRegister dst,
   1707                        const LogicVRegister& src1, const LogicVRegister& src2);
   1708   LogicVRegister UMinMaxV(VectorFormat vform, LogicVRegister dst,
   1709                           const LogicVRegister& src, bool max);
   1710   LogicVRegister umaxv(VectorFormat vform, LogicVRegister dst,
   1711                        const LogicVRegister& src);
   1712   LogicVRegister uminv(VectorFormat vform, LogicVRegister dst,
   1713                        const LogicVRegister& src);
   1714   LogicVRegister trn1(VectorFormat vform, LogicVRegister dst,
   1715                       const LogicVRegister& src1, const LogicVRegister& src2);
   1716   LogicVRegister trn2(VectorFormat vform, LogicVRegister dst,
   1717                       const LogicVRegister& src1, const LogicVRegister& src2);
   1718   LogicVRegister zip1(VectorFormat vform, LogicVRegister dst,
   1719                       const LogicVRegister& src1, const LogicVRegister& src2);
   1720   LogicVRegister zip2(VectorFormat vform, LogicVRegister dst,
   1721                       const LogicVRegister& src1, const LogicVRegister& src2);
   1722   LogicVRegister uzp1(VectorFormat vform, LogicVRegister dst,
   1723                       const LogicVRegister& src1, const LogicVRegister& src2);
   1724   LogicVRegister uzp2(VectorFormat vform, LogicVRegister dst,
   1725                       const LogicVRegister& src1, const LogicVRegister& src2);
   1726   LogicVRegister shl(VectorFormat vform, LogicVRegister dst,
   1727                      const LogicVRegister& src, int shift);
   1728   LogicVRegister scvtf(VectorFormat vform, LogicVRegister dst,
   1729                        const LogicVRegister& src, int fbits,
   1730                        FPRounding rounding_mode);
   1731   LogicVRegister ucvtf(VectorFormat vform, LogicVRegister dst,
   1732                        const LogicVRegister& src, int fbits,
   1733                        FPRounding rounding_mode);
   1734   LogicVRegister sshll(VectorFormat vform, LogicVRegister dst,
   1735                        const LogicVRegister& src, int shift);
   1736   LogicVRegister sshll2(VectorFormat vform, LogicVRegister dst,
   1737                         const LogicVRegister& src, int shift);
   1738   LogicVRegister shll(VectorFormat vform, LogicVRegister dst,
   1739                       const LogicVRegister& src);
   1740   LogicVRegister shll2(VectorFormat vform, LogicVRegister dst,
   1741                        const LogicVRegister& src);
   1742   LogicVRegister ushll(VectorFormat vform, LogicVRegister dst,
   1743                        const LogicVRegister& src, int shift);
   1744   LogicVRegister ushll2(VectorFormat vform, LogicVRegister dst,
   1745                         const LogicVRegister& src, int shift);
   1746   LogicVRegister sli(VectorFormat vform, LogicVRegister dst,
   1747                      const LogicVRegister& src, int shift);
   1748   LogicVRegister sri(VectorFormat vform, LogicVRegister dst,
   1749                      const LogicVRegister& src, int shift);
   1750   LogicVRegister sshr(VectorFormat vform, LogicVRegister dst,
   1751                       const LogicVRegister& src, int shift);
   1752   LogicVRegister ushr(VectorFormat vform, LogicVRegister dst,
   1753                       const LogicVRegister& src, int shift);
   1754   LogicVRegister ssra(VectorFormat vform, LogicVRegister dst,
   1755                       const LogicVRegister& src, int shift);
   1756   LogicVRegister usra(VectorFormat vform, LogicVRegister dst,
   1757                       const LogicVRegister& src, int shift);
   1758   LogicVRegister srsra(VectorFormat vform, LogicVRegister dst,
   1759                        const LogicVRegister& src, int shift);
   1760   LogicVRegister ursra(VectorFormat vform, LogicVRegister dst,
   1761                        const LogicVRegister& src, int shift);
   1762   LogicVRegister suqadd(VectorFormat vform, LogicVRegister dst,
   1763                         const LogicVRegister& src);
   1764   LogicVRegister usqadd(VectorFormat vform, LogicVRegister dst,
   1765                         const LogicVRegister& src);
   1766   LogicVRegister sqshl(VectorFormat vform, LogicVRegister dst,
   1767                        const LogicVRegister& src, int shift);
   1768   LogicVRegister uqshl(VectorFormat vform, LogicVRegister dst,
   1769                        const LogicVRegister& src, int shift);
   1770   LogicVRegister sqshlu(VectorFormat vform, LogicVRegister dst,
   1771                         const LogicVRegister& src, int shift);
   1772   LogicVRegister abs(VectorFormat vform, LogicVRegister dst,
   1773                      const LogicVRegister& src);
   1774   LogicVRegister neg(VectorFormat vform, LogicVRegister dst,
   1775                      const LogicVRegister& src);
   1776   LogicVRegister ExtractNarrow(VectorFormat vform, LogicVRegister dst,
   1777                                bool dstIsSigned, const LogicVRegister& src,
   1778                                bool srcIsSigned);
   1779   LogicVRegister xtn(VectorFormat vform, LogicVRegister dst,
   1780                      const LogicVRegister& src);
   1781   LogicVRegister sqxtn(VectorFormat vform, LogicVRegister dst,
   1782                        const LogicVRegister& src);
   1783   LogicVRegister uqxtn(VectorFormat vform, LogicVRegister dst,
   1784                        const LogicVRegister& src);
   1785   LogicVRegister sqxtun(VectorFormat vform, LogicVRegister dst,
   1786                         const LogicVRegister& src);
   1787   LogicVRegister AbsDiff(VectorFormat vform, LogicVRegister dst,
   1788                          const LogicVRegister& src1, const LogicVRegister& src2,
   1789                          bool issigned);
   1790   LogicVRegister saba(VectorFormat vform, LogicVRegister dst,
   1791                       const LogicVRegister& src1, const LogicVRegister& src2);
   1792   LogicVRegister uaba(VectorFormat vform, LogicVRegister dst,
   1793                       const LogicVRegister& src1, const LogicVRegister& src2);
   1794   LogicVRegister shrn(VectorFormat vform, LogicVRegister dst,
   1795                       const LogicVRegister& src, int shift);
   1796   LogicVRegister shrn2(VectorFormat vform, LogicVRegister dst,
   1797                        const LogicVRegister& src, int shift);
   1798   LogicVRegister rshrn(VectorFormat vform, LogicVRegister dst,
   1799                        const LogicVRegister& src, int shift);
   1800   LogicVRegister rshrn2(VectorFormat vform, LogicVRegister dst,
   1801                         const LogicVRegister& src, int shift);
   1802   LogicVRegister uqshrn(VectorFormat vform, LogicVRegister dst,
   1803                         const LogicVRegister& src, int shift);
   1804   LogicVRegister uqshrn2(VectorFormat vform, LogicVRegister dst,
   1805                          const LogicVRegister& src, int shift);
   1806   LogicVRegister uqrshrn(VectorFormat vform, LogicVRegister dst,
   1807                          const LogicVRegister& src, int shift);
   1808   LogicVRegister uqrshrn2(VectorFormat vform, LogicVRegister dst,
   1809                           const LogicVRegister& src, int shift);
   1810   LogicVRegister sqshrn(VectorFormat vform, LogicVRegister dst,
   1811                         const LogicVRegister& src, int shift);
   1812   LogicVRegister sqshrn2(VectorFormat vform, LogicVRegister dst,
   1813                          const LogicVRegister& src, int shift);
   1814   LogicVRegister sqrshrn(VectorFormat vform, LogicVRegister dst,
   1815                          const LogicVRegister& src, int shift);
   1816   LogicVRegister sqrshrn2(VectorFormat vform, LogicVRegister dst,
   1817                           const LogicVRegister& src, int shift);
   1818   LogicVRegister sqshrun(VectorFormat vform, LogicVRegister dst,
   1819                          const LogicVRegister& src, int shift);
   1820   LogicVRegister sqshrun2(VectorFormat vform, LogicVRegister dst,
   1821                           const LogicVRegister& src, int shift);
   1822   LogicVRegister sqrshrun(VectorFormat vform, LogicVRegister dst,
   1823                           const LogicVRegister& src, int shift);
   1824   LogicVRegister sqrshrun2(VectorFormat vform, LogicVRegister dst,
   1825                            const LogicVRegister& src, int shift);
   1826   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst,
   1827                           const LogicVRegister& src1,
   1828                           const LogicVRegister& src2, bool round = true);
   1829   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst,
   1830                          const LogicVRegister& src1,
   1831                          const LogicVRegister& src2);
   1832 #define NEON_3VREG_LOGIC_LIST(V) \
   1833   V(addhn)                       \
   1834   V(addhn2)                      \
   1835   V(raddhn)                      \
   1836   V(raddhn2)                     \
   1837   V(subhn)                       \
   1838   V(subhn2)                      \
   1839   V(rsubhn)                      \
   1840   V(rsubhn2)                     \
   1841   V(pmull)                       \
   1842   V(pmull2)                      \
   1843   V(sabal)                       \
   1844   V(sabal2)                      \
   1845   V(uabal)                       \
   1846   V(uabal2)                      \
   1847   V(sabdl)                       \
   1848   V(sabdl2)                      \
   1849   V(uabdl)                       \
   1850   V(uabdl2)                      \
   1851   V(smull)                       \
   1852   V(smull2)                      \
   1853   V(umull)                       \
   1854   V(umull2)                      \
   1855   V(smlal)                       \
   1856   V(smlal2)                      \
   1857   V(umlal)                       \
   1858   V(umlal2)                      \
   1859   V(smlsl)                       \
   1860   V(smlsl2)                      \
   1861   V(umlsl)                       \
   1862   V(umlsl2)                      \
   1863   V(sqdmlal)                     \
   1864   V(sqdmlal2)                    \
   1865   V(sqdmlsl)                     \
   1866   V(sqdmlsl2)                    \
   1867   V(sqdmull)                     \
   1868   V(sqdmull2)
   1869 
   1870 #define DEFINE_LOGIC_FUNC(FXN)                               \
   1871   LogicVRegister FXN(VectorFormat vform, LogicVRegister dst, \
   1872                      const LogicVRegister& src1, const LogicVRegister& src2);
   1873   NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
   1874 #undef DEFINE_LOGIC_FUNC
   1875 
   1876 #define NEON_FP3SAME_LIST(V) \
   1877   V(fadd, FPAdd, false)      \
   1878   V(fsub, FPSub, true)       \
   1879   V(fmul, FPMul, true)       \
   1880   V(fmulx, FPMulx, true)     \
   1881   V(fdiv, FPDiv, true)       \
   1882   V(fmax, FPMax, false)      \
   1883   V(fmin, FPMin, false)      \
   1884   V(fmaxnm, FPMaxNM, false)  \
   1885   V(fminnm, FPMinNM, false)
   1886 
   1887 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                           \
   1888   template <typename T>                                                      \
   1889   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \
   1890                     const LogicVRegister& src1, const LogicVRegister& src2); \
   1891   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \
   1892                     const LogicVRegister& src1, const LogicVRegister& src2);
   1893   NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
   1894 #undef DECLARE_NEON_FP_VECTOR_OP
   1895 
   1896 #define NEON_FPPAIRWISE_LIST(V) \
   1897   V(faddp, fadd, FPAdd)         \
   1898   V(fmaxp, fmax, FPMax)         \
   1899   V(fmaxnmp, fmaxnm, FPMaxNM)   \
   1900   V(fminp, fmin, FPMin)         \
   1901   V(fminnmp, fminnm, FPMinNM)
   1902 
   1903 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)                                  \
   1904   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \
   1905                      const LogicVRegister& src1, const LogicVRegister& src2); \
   1906   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \
   1907                      const LogicVRegister& src);
   1908   NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
   1909 #undef DECLARE_NEON_FP_PAIR_OP
   1910 
   1911   template <typename T>
   1912   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst,
   1913                         const LogicVRegister& src1, const LogicVRegister& src2);
   1914   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst,
   1915                         const LogicVRegister& src1, const LogicVRegister& src2);
   1916   template <typename T>
   1917   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst,
   1918                          const LogicVRegister& src1,
   1919                          const LogicVRegister& src2);
   1920   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst,
   1921                          const LogicVRegister& src1,
   1922                          const LogicVRegister& src2);
   1923   template <typename T>
   1924   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
   1925                       const LogicVRegister& src1, const LogicVRegister& src2);
   1926   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
   1927                       const LogicVRegister& src1, const LogicVRegister& src2);
   1928   template <typename T>
   1929   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
   1930                       const LogicVRegister& src1, const LogicVRegister& src2);
   1931   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
   1932                       const LogicVRegister& src1, const LogicVRegister& src2);
   1933   LogicVRegister fnmul(VectorFormat vform, LogicVRegister dst,
   1934                        const LogicVRegister& src1, const LogicVRegister& src2);
   1935 
   1936   template <typename T>
   1937   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst,
   1938                       const LogicVRegister& src1, const LogicVRegister& src2,
   1939                       Condition cond);
   1940   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst,
   1941                       const LogicVRegister& src1, const LogicVRegister& src2,
   1942                       Condition cond);
   1943   LogicVRegister fabscmp(VectorFormat vform, LogicVRegister dst,
   1944                          const LogicVRegister& src1, const LogicVRegister& src2,
   1945                          Condition cond);
   1946   LogicVRegister fcmp_zero(VectorFormat vform, LogicVRegister dst,
   1947                            const LogicVRegister& src, Condition cond);
   1948 
   1949   template <typename T>
   1950   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst,
   1951                       const LogicVRegister& src);
   1952   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst,
   1953                       const LogicVRegister& src);
   1954   template <typename T>
   1955   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst,
   1956                         const LogicVRegister& src);
   1957   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst,
   1958                         const LogicVRegister& src);
   1959   template <typename T>
   1960   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst,
   1961                        const LogicVRegister& src);
   1962   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst,
   1963                        const LogicVRegister& src);
   1964   LogicVRegister fabd(VectorFormat vform, LogicVRegister dst,
   1965                       const LogicVRegister& src1, const LogicVRegister& src2);
   1966   LogicVRegister frint(VectorFormat vform, LogicVRegister dst,
   1967                        const LogicVRegister& src, FPRounding rounding_mode,
   1968                        bool inexact_exception = false);
   1969   LogicVRegister fcvts(VectorFormat vform, LogicVRegister dst,
   1970                        const LogicVRegister& src, FPRounding rounding_mode,
   1971                        int fbits = 0);
   1972   LogicVRegister fcvtu(VectorFormat vform, LogicVRegister dst,
   1973                        const LogicVRegister& src, FPRounding rounding_mode,
   1974                        int fbits = 0);
   1975   LogicVRegister fcvtl(VectorFormat vform, LogicVRegister dst,
   1976                        const LogicVRegister& src);
   1977   LogicVRegister fcvtl2(VectorFormat vform, LogicVRegister dst,
   1978                         const LogicVRegister& src);
   1979   LogicVRegister fcvtn(VectorFormat vform, LogicVRegister dst,
   1980                        const LogicVRegister& src);
   1981   LogicVRegister fcvtn2(VectorFormat vform, LogicVRegister dst,
   1982                         const LogicVRegister& src);
   1983   LogicVRegister fcvtxn(VectorFormat vform, LogicVRegister dst,
   1984                         const LogicVRegister& src);
   1985   LogicVRegister fcvtxn2(VectorFormat vform, LogicVRegister dst,
   1986                          const LogicVRegister& src);
   1987   LogicVRegister fsqrt(VectorFormat vform, LogicVRegister dst,
   1988                        const LogicVRegister& src);
   1989   LogicVRegister frsqrte(VectorFormat vform, LogicVRegister dst,
   1990                          const LogicVRegister& src);
   1991   LogicVRegister frecpe(VectorFormat vform, LogicVRegister dst,
   1992                         const LogicVRegister& src, FPRounding rounding);
   1993   LogicVRegister ursqrte(VectorFormat vform, LogicVRegister dst,
   1994                          const LogicVRegister& src);
   1995   LogicVRegister urecpe(VectorFormat vform, LogicVRegister dst,
   1996                         const LogicVRegister& src);
   1997 
   1998   typedef float (Simulator::*FPMinMaxOp)(float a, float b);
   1999 
   2000   LogicVRegister FMinMaxV(VectorFormat vform, LogicVRegister dst,
   2001                           const LogicVRegister& src, FPMinMaxOp Op);
   2002 
   2003   LogicVRegister fminv(VectorFormat vform, LogicVRegister dst,
   2004                        const LogicVRegister& src);
   2005   LogicVRegister fmaxv(VectorFormat vform, LogicVRegister dst,
   2006                        const LogicVRegister& src);
   2007   LogicVRegister fminnmv(VectorFormat vform, LogicVRegister dst,
   2008                          const LogicVRegister& src);
   2009   LogicVRegister fmaxnmv(VectorFormat vform, LogicVRegister dst,
   2010                          const LogicVRegister& src);
   2011 
   2012   template <typename T>
   2013   T FPRecipSqrtEstimate(T op);
   2014   template <typename T>
   2015   T FPRecipEstimate(T op, FPRounding rounding);
   2016   template <typename T, typename R>
   2017   R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
   2018 
   2019   void FPCompare(double val0, double val1);
   2020   double FPRoundInt(double value, FPRounding round_mode);
   2021   double FPToDouble(float value);
   2022   float FPToFloat(double value, FPRounding round_mode);
   2023   float FPToFloat(float16 value);
   2024   float16 FPToFloat16(float value, FPRounding round_mode);
   2025   float16 FPToFloat16(double value, FPRounding round_mode);
   2026   double recip_sqrt_estimate(double a);
   2027   double recip_estimate(double a);
   2028   double FPRecipSqrtEstimate(double a);
   2029   double FPRecipEstimate(double a);
   2030   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
   2031   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
   2032   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
   2033   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
   2034   int32_t FPToInt32(double value, FPRounding rmode);
   2035   int64_t FPToInt64(double value, FPRounding rmode);
   2036   uint32_t FPToUInt32(double value, FPRounding rmode);
   2037   uint64_t FPToUInt64(double value, FPRounding rmode);
   2038 
   2039   template <typename T>
   2040   T FPAdd(T op1, T op2);
   2041 
   2042   template <typename T>
   2043   T FPDiv(T op1, T op2);
   2044 
   2045   template <typename T>
   2046   T FPMax(T a, T b);
   2047 
   2048   template <typename T>
   2049   T FPMaxNM(T a, T b);
   2050 
   2051   template <typename T>
   2052   T FPMin(T a, T b);
   2053 
   2054   template <typename T>
   2055   T FPMinNM(T a, T b);
   2056 
   2057   template <typename T>
   2058   T FPMul(T op1, T op2);
   2059 
   2060   template <typename T>
   2061   T FPMulx(T op1, T op2);
   2062 
   2063   template <typename T>
   2064   T FPMulAdd(T a, T op1, T op2);
   2065 
   2066   template <typename T>
   2067   T FPSqrt(T op);
   2068 
   2069   template <typename T>
   2070   T FPSub(T op1, T op2);
   2071 
   2072   template <typename T>
   2073   T FPRecipStepFused(T op1, T op2);
   2074 
   2075   template <typename T>
   2076   T FPRSqrtStepFused(T op1, T op2);
   2077 
   2078   // This doesn't do anything at the moment. We'll need it if we want support
   2079   // for cumulative exception bits or floating-point exceptions.
   2080   void FPProcessException() {}
   2081 
   2082   // Standard NaN processing.
   2083   bool FPProcessNaNs(Instruction* instr);
   2084 
   2085   void CheckStackAlignment();
   2086 
   2087   inline void CheckPCSComplianceAndRun();
   2088 
   2089 #ifdef DEBUG
   2090   // Corruption values should have their least significant byte cleared to
   2091   // allow the code of the register being corrupted to be inserted.
   2092   static const uint64_t kCallerSavedRegisterCorruptionValue =
   2093       0xca11edc0de000000UL;
   2094   // This value is a NaN in both 32-bit and 64-bit FP.
   2095   static const uint64_t kCallerSavedVRegisterCorruptionValue =
   2096       0x7ff000007f801000UL;
   2097   // This value is a mix of 32/64-bits NaN and "verbose" immediate.
   2098   static const uint64_t kDefaultCPURegisterCorruptionValue =
   2099       0x7ffbad007f8bad00UL;
   2100 
   2101   void CorruptRegisters(CPURegList* list,
   2102                         uint64_t value = kDefaultCPURegisterCorruptionValue);
   2103   void CorruptAllCallerSavedCPURegisters();
   2104 #endif
   2105 
   2106   // Pseudo Printf instruction
   2107   void DoPrintf(Instruction* instr);
   2108 
   2109   // Processor state ---------------------------------------
   2110 
   2111   // Output stream.
   2112   FILE* stream_;
   2113   PrintDisassembler* print_disasm_;
   2114   void PRINTF_FORMAT(2, 3) TraceSim(const char* format, ...);
   2115 
   2116   // Instrumentation.
   2117   Instrument* instrument_;
   2118 
   2119   // General purpose registers. Register 31 is the stack pointer.
   2120   SimRegister registers_[kNumberOfRegisters];
   2121 
   2122   // Floating point registers
   2123   SimVRegister vregisters_[kNumberOfVRegisters];
   2124 
   2125   // Processor state
   2126   // bits[31, 27]: Condition flags N, Z, C, and V.
   2127   //               (Negative, Zero, Carry, Overflow)
   2128   SimSystemRegister nzcv_;
   2129 
   2130   // Floating-Point Control Register
   2131   SimSystemRegister fpcr_;
   2132 
   2133   // Only a subset of FPCR features are supported by the simulator. This helper
   2134   // checks that the FPCR settings are supported.
   2135   //
   2136   // This is checked when floating-point instructions are executed, not when
   2137   // FPCR is set. This allows generated code to modify FPCR for external
   2138   // functions, or to save and restore it when entering and leaving generated
   2139   // code.
   2140   void AssertSupportedFPCR() {
   2141     DCHECK_EQ(fpcr().FZ(), 0);            // No flush-to-zero support.
   2142     DCHECK(fpcr().RMode() == FPTieEven);  // Ties-to-even rounding only.
   2143 
   2144     // The simulator does not support half-precision operations so fpcr().AHP()
   2145     // is irrelevant, and is not checked here.
   2146   }
   2147 
   2148   template <typename T>
   2149   static int CalcNFlag(T result) {
   2150     return (result >> (sizeof(T) * 8 - 1)) & 1;
   2151   }
   2152 
   2153   static int CalcZFlag(uint64_t result) {
   2154     return result == 0;
   2155   }
   2156 
   2157   static const uint32_t kConditionFlagsMask = 0xf0000000;
   2158 
   2159   // Stack
   2160   uintptr_t stack_;
   2161   static const size_t stack_protection_size_ = KB;
   2162   size_t stack_size_;
   2163   uintptr_t stack_limit_;
   2164 
   2165   Decoder<DispatchingDecoderVisitor>* decoder_;
   2166   Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
   2167 
   2168   // Indicates if the pc has been modified by the instruction and should not be
   2169   // automatically incremented.
   2170   bool pc_modified_;
   2171   Instruction* pc_;
   2172 
   2173   static const char* xreg_names[];
   2174   static const char* wreg_names[];
   2175   static const char* sreg_names[];
   2176   static const char* dreg_names[];
   2177   static const char* vreg_names[];
   2178 
   2179   // Debugger input.
   2180   void set_last_debugger_input(char* input) {
   2181     DeleteArray(last_debugger_input_);
   2182     last_debugger_input_ = input;
   2183   }
   2184   char* last_debugger_input() { return last_debugger_input_; }
   2185   char* last_debugger_input_;
   2186 
   2187   // Synchronization primitives. See ARM DDI 0487A.a, B2.10. Pair types not
   2188   // implemented.
   2189   enum class MonitorAccess {
   2190     Open,
   2191     Exclusive,
   2192   };
   2193 
   2194   enum class TransactionSize {
   2195     None = 0,
   2196     Byte = 1,
   2197     HalfWord = 2,
   2198     Word = 4,
   2199     DoubleWord = 8,
   2200   };
   2201 
   2202   TransactionSize get_transaction_size(unsigned size);
   2203 
   2204   // The least-significant bits of the address are ignored. The number of bits
   2205   // is implementation-defined, between 3 and 11. See ARM DDI 0487A.a, B2.10.3.
   2206   static const uintptr_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1);
   2207 
   2208   class LocalMonitor {
   2209    public:
   2210     LocalMonitor();
   2211 
   2212     // These functions manage the state machine for the local monitor, but do
   2213     // not actually perform loads and stores. NotifyStoreExcl only returns
   2214     // true if the exclusive store is allowed; the global monitor will still
   2215     // have to be checked to see whether the memory should be updated.
   2216     void NotifyLoad();
   2217     void NotifyLoadExcl(uintptr_t addr, TransactionSize size);
   2218     void NotifyStore();
   2219     bool NotifyStoreExcl(uintptr_t addr, TransactionSize size);
   2220 
   2221    private:
   2222     void Clear();
   2223 
   2224     MonitorAccess access_state_;
   2225     uintptr_t tagged_addr_;
   2226     TransactionSize size_;
   2227   };
   2228 
   2229   class GlobalMonitor {
   2230    public:
   2231     GlobalMonitor();
   2232 
   2233     class Processor {
   2234      public:
   2235       Processor();
   2236 
   2237      private:
   2238       friend class GlobalMonitor;
   2239       // These functions manage the state machine for the global monitor, but do
   2240       // not actually perform loads and stores.
   2241       void Clear_Locked();
   2242       void NotifyLoadExcl_Locked(uintptr_t addr);
   2243       void NotifyStore_Locked(bool is_requesting_processor);
   2244       bool NotifyStoreExcl_Locked(uintptr_t addr, bool is_requesting_processor);
   2245 
   2246       MonitorAccess access_state_;
   2247       uintptr_t tagged_addr_;
   2248       Processor* next_;
   2249       Processor* prev_;
   2250       // A stxr can fail due to background cache evictions. Rather than
   2251       // simulating this, we'll just occasionally introduce cases where an
   2252       // exclusive store fails. This will happen once after every
   2253       // kMaxFailureCounter exclusive stores.
   2254       static const int kMaxFailureCounter = 5;
   2255       int failure_counter_;
   2256     };
   2257 
   2258     // Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
   2259     base::Mutex mutex;
   2260 
   2261     void NotifyLoadExcl_Locked(uintptr_t addr, Processor* processor);
   2262     void NotifyStore_Locked(Processor* processor);
   2263     bool NotifyStoreExcl_Locked(uintptr_t addr, Processor* processor);
   2264 
   2265     // Called when the simulator is destroyed.
   2266     void RemoveProcessor(Processor* processor);
   2267 
   2268    private:
   2269     bool IsProcessorInLinkedList_Locked(Processor* processor) const;
   2270     void PrependProcessor_Locked(Processor* processor);
   2271 
   2272     Processor* head_;
   2273   };
   2274 
   2275   LocalMonitor local_monitor_;
   2276   GlobalMonitor::Processor global_monitor_processor_;
   2277   static base::LazyInstance<GlobalMonitor>::type global_monitor_;
   2278 
   2279  private:
   2280   void Init(FILE* stream);
   2281 
   2282   V8_EXPORT_PRIVATE void CallImpl(Address entry, CallArgument* args);
   2283 
   2284   // Read floating point return values.
   2285   template <typename T>
   2286   typename std::enable_if<std::is_floating_point<T>::value, T>::type
   2287   ReadReturn() {
   2288     return static_cast<T>(dreg(0));
   2289   }
   2290   // Read non-float return values.
   2291   template <typename T>
   2292   typename std::enable_if<!std::is_floating_point<T>::value, T>::type
   2293   ReadReturn() {
   2294     return ConvertReturn<T>(xreg(0));
   2295   }
   2296 
   2297   template <typename T>
   2298   static T FPDefaultNaN();
   2299 
   2300   template <typename T>
   2301   T FPProcessNaN(T op) {
   2302     DCHECK(std::isnan(op));
   2303     return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
   2304   }
   2305 
   2306   template <typename T>
   2307   T FPProcessNaNs(T op1, T op2) {
   2308     if (IsSignallingNaN(op1)) {
   2309       return FPProcessNaN(op1);
   2310     } else if (IsSignallingNaN(op2)) {
   2311       return FPProcessNaN(op2);
   2312     } else if (std::isnan(op1)) {
   2313       DCHECK(IsQuietNaN(op1));
   2314       return FPProcessNaN(op1);
   2315     } else if (std::isnan(op2)) {
   2316       DCHECK(IsQuietNaN(op2));
   2317       return FPProcessNaN(op2);
   2318     } else {
   2319       return 0.0;
   2320     }
   2321   }
   2322 
   2323   template <typename T>
   2324   T FPProcessNaNs3(T op1, T op2, T op3) {
   2325     if (IsSignallingNaN(op1)) {
   2326       return FPProcessNaN(op1);
   2327     } else if (IsSignallingNaN(op2)) {
   2328       return FPProcessNaN(op2);
   2329     } else if (IsSignallingNaN(op3)) {
   2330       return FPProcessNaN(op3);
   2331     } else if (std::isnan(op1)) {
   2332       DCHECK(IsQuietNaN(op1));
   2333       return FPProcessNaN(op1);
   2334     } else if (std::isnan(op2)) {
   2335       DCHECK(IsQuietNaN(op2));
   2336       return FPProcessNaN(op2);
   2337     } else if (std::isnan(op3)) {
   2338       DCHECK(IsQuietNaN(op3));
   2339       return FPProcessNaN(op3);
   2340     } else {
   2341       return 0.0;
   2342     }
   2343   }
   2344 
   2345   int  log_parameters_;
   2346   Isolate* isolate_;
   2347 };
   2348 
   2349 template <>
   2350 inline double Simulator::FPDefaultNaN<double>() {
   2351   return kFP64DefaultNaN;
   2352 }
   2353 
   2354 template <>
   2355 inline float Simulator::FPDefaultNaN<float>() {
   2356   return kFP32DefaultNaN;
   2357 }
   2358 
   2359 #endif  // defined(USE_SIMULATOR)
   2360 
   2361 }  // namespace internal
   2362 }  // namespace v8
   2363 
   2364 #endif  // V8_ARM64_SIMULATOR_ARM64_H_
   2365