tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Simulator-vixl.h (96976B)


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