1// Copyright 2015, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#ifndef VIXL_AARCH64_SIMULATOR_AARCH64_H_
28#define VIXL_AARCH64_SIMULATOR_AARCH64_H_
29
30#include <memory>
31#include <unordered_map>
32#include <vector>
33
34#include "../globals-vixl.h"
35#include "../utils-vixl.h"
36#include "cpu-features.h"
37
38#include "abi-aarch64.h"
39#include "cpu-features-auditor-aarch64.h"
40#include "debugger-aarch64.h"
41#include "disasm-aarch64.h"
42#include "instructions-aarch64.h"
43#include "simulator-constants-aarch64.h"
44
45#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
46
47// These are only used for the ABI feature, and depend on checks performed for
48// it.
49#ifdef VIXL_HAS_ABI_SUPPORT
50#include <tuple>
51#if __cplusplus >= 201402L
52// Required for `std::index_sequence`
53#include <utility>
54#endif
55#endif
56
57// The hosts that Simulator running on may not have these flags defined.
58#ifndef PROT_BTI
59#define PROT_BTI 0x10
60#endif
61#ifndef PROT_MTE
62#define PROT_MTE 0x20
63#endif
64
65namespace vixl {
66namespace aarch64 {
67
68class Simulator;
69struct RuntimeCallStructHelper;
70
71class SimStack {
72 public:
73  SimStack() {}
74  explicit SimStack(size_t size) : usable_size_(size) {}
75
76  // Guard against accesses above the stack base. This could occur, for example,
77  // if the first simulated function tries to read stack arguments that haven't
78  // been properly initialised in the Simulator's stack.
79  void SetBaseGuardSize(size_t size) { base_guard_size_ = size; }
80
81  // Guard against stack overflows. The size should be large enough to detect
82  // the largest stride made (by `MacroAssembler::Claim()` or equivalent) whilst
83  // initialising stack objects.
84  void SetLimitGuardSize(size_t size) { limit_guard_size_ = size; }
85
86  // The minimum usable size of the stack.
87  // Equal to "stack base" - "stack limit", in AAPCS64 terminology.
88  void SetUsableSize(size_t size) { usable_size_ = size; }
89
90  // Set the minimum alignment for the stack parameters.
91  void AlignToBytesLog2(int align_log2) { align_log2_ = align_log2; }
92
93  class Allocated {
94   public:
95    // Using AAPCS64 terminology, highest addresses at the top:
96    //
97    //  data_.get() + alloc_size ->
98    //                              |
99    //                              | Base guard
100    //                 GetBase() -> |                  |
101    //                                |                |
102    //                                |                | AAPCS64-legal
103    //                                | Usable stack   | values of 'sp'.
104    //                                |                |
105    //                                |                |
106    //                GetLimit() -> |
107    //                              | Limit guard
108    //               data_.get() -> |
109    //
110    // The Simulator detects (and forbids) accesses to either guard region.
111
112    char* GetBase() const { return base_; }
113    char* GetLimit() const { return limit_; }
114
115    template <typename T>
116    bool IsAccessInGuardRegion(const T* base, size_t size) const {
117      VIXL_ASSERT(size > 0);
118      // Inclusive bounds.
119      const char* start = reinterpret_cast<const char*>(base);
120      const char* end = start + size - 1;
121      const char* data_start = data_.get();
122      const char* data_end = data_start + alloc_size_ - 1;
123      bool in_base_guard = (start <= data_end) && (end >= base_);
124      bool in_limit_guard = (start <= limit_) && (end >= data_start);
125      return in_base_guard || in_limit_guard;
126    }
127
128   private:
129    std::unique_ptr<char[]> data_;
130    char* limit_;
131    char* base_;
132    size_t alloc_size_;
133
134    friend class SimStack;
135  };
136
137  // Allocate the stack, locking the parameters.
138  Allocated Allocate() {
139    size_t align_to = 1 << align_log2_;
140    size_t l = AlignUp(limit_guard_size_, align_to);
141    size_t u = AlignUp(usable_size_, align_to);
142    size_t b = AlignUp(base_guard_size_, align_to);
143    size_t size = l + u + b;
144
145    Allocated a;
146    size_t alloc_size = (align_to - 1) + size;
147    a.data_ = std::make_unique<char[]>(alloc_size);
148    void* data = a.data_.get();
149    auto data_aligned =
150        reinterpret_cast<char*>(std::align(align_to, size, data, alloc_size));
151    a.limit_ = data_aligned + l - 1;
152    a.base_ = data_aligned + l + u;
153    a.alloc_size_ = alloc_size;
154    return a;
155  }
156
157 private:
158  size_t base_guard_size_ = 256;
159  size_t limit_guard_size_ = 4 * 1024;
160  size_t usable_size_ = 8 * 1024;
161  size_t align_log2_ = 4;
162
163  static const size_t kDefaultBaseGuardSize = 256;
164  static const size_t kDefaultLimitGuardSize = 4 * 1024;
165  static const size_t kDefaultUsableSize = 8 * 1024;
166};
167
168// Armv8.5 MTE helpers.
169inline int GetAllocationTagFromAddress(uint64_t address) {
170  return static_cast<int>(ExtractUnsignedBitfield64(59, 56, address));
171}
172
173template <typename T>
174T AddressUntag(T address) {
175  // Cast the address using a C-style cast. A reinterpret_cast would be
176  // appropriate, but it can't cast one integral type to another.
177  uint64_t bits = (uint64_t)address;
178  return (T)(bits & ~kAddressTagMask);
179}
180
181// A callback function, called when a function has been intercepted if a
182// BranchInterception entry exists in branch_interceptions. The address of
183// the intercepted function is passed to the callback. For usage see
184// BranchInterception.
185using InterceptionCallback = std::function<void(uint64_t)>;
186
187class MetaDataDepot {
188 public:
189  class MetaDataMTE {
190   public:
191    explicit MetaDataMTE(int tag) : tag_(tag) {}
192
193    int GetTag() const { return tag_; }
194    void SetTag(int tag) {
195      VIXL_ASSERT(IsUint4(tag));
196      tag_ = tag;
197    }
198
199    static bool IsActive() { return is_active; }
200    static void SetActive(bool value) { is_active = value; }
201
202   private:
203    static bool is_active;
204    int16_t tag_;
205
206    friend class MetaDataDepot;
207  };
208
209  // Generate a key for metadata recording from a untagged address.
210  template <typename T>
211  uint64_t GenerateMTEkey(T address) const {
212    // Cast the address using a C-style cast. A reinterpret_cast would be
213    // appropriate, but it can't cast one integral type to another.
214    return (uint64_t)(AddressUntag(address)) >> kMTETagGranuleInBytesLog2;
215  }
216
217  template <typename R, typename T>
218  R GetAttribute(T map, uint64_t key) {
219    auto pair = map->find(key);
220    R value = (pair == map->end()) ? nullptr : &pair->second;
221    return value;
222  }
223
224  template <typename T>
225  int GetMTETag(T address, Instruction const* pc = nullptr) {
226    uint64_t key = GenerateMTEkey(address);
227    MetaDataMTE* m = GetAttribute<MetaDataMTE*>(&metadata_mte_, key);
228
229    if (!m) {
230      std::stringstream sstream;
231      sstream << std::hex << "MTE ERROR : instruction at 0x"
232              << reinterpret_cast<uint64_t>(pc)
233              << " touched a unallocated memory location 0x"
234              << (uint64_t)(address) << ".\n";
235      VIXL_ABORT_WITH_MSG(sstream.str().c_str());
236    }
237
238    return m->GetTag();
239  }
240
241  template <typename T>
242  void SetMTETag(T address, int tag, Instruction const* pc = nullptr) {
243    VIXL_ASSERT(IsAligned((uintptr_t)address, kMTETagGranuleInBytes));
244    uint64_t key = GenerateMTEkey(address);
245    MetaDataMTE* m = GetAttribute<MetaDataMTE*>(&metadata_mte_, key);
246
247    if (!m) {
248      metadata_mte_.insert({key, MetaDataMTE(tag)});
249    } else {
250      // Overwrite
251      if (m->GetTag() == tag) {
252        std::stringstream sstream;
253        sstream << std::hex << "MTE WARNING : instruction at 0x"
254                << reinterpret_cast<uint64_t>(pc)
255                << ", the same tag is assigned to the address 0x"
256                << (uint64_t)(address) << ".\n";
257        VIXL_WARNING(sstream.str().c_str());
258      }
259      m->SetTag(tag);
260    }
261  }
262
263  template <typename T>
264  size_t CleanMTETag(T address) {
265    VIXL_ASSERT(
266        IsAligned(reinterpret_cast<uintptr_t>(address), kMTETagGranuleInBytes));
267    uint64_t key = GenerateMTEkey(address);
268    return metadata_mte_.erase(key);
269  }
270
271  size_t GetTotalCountMTE() { return metadata_mte_.size(); }
272
273  // A pure virtual struct that allows the templated BranchInterception struct
274  // to be stored. For more information see BranchInterception.
275  struct BranchInterceptionAbstract {
276    virtual ~BranchInterceptionAbstract() {}
277    // Call the callback_ if one exists, otherwise do a RuntimeCall.
278    virtual void operator()(Simulator* simulator) const = 0;
279  };
280
281  // An entry denoting a function to intercept when branched to during
282  // simulator execution. When a function is intercepted the callback will be
283  // called if one exists otherwise the function will be passed to
284  // RuntimeCall.
285  template <typename R, typename... P>
286  struct BranchInterception : public BranchInterceptionAbstract {
287    BranchInterception(R (*function)(P...),
288                       InterceptionCallback callback = nullptr)
289        : function_(function), callback_(callback) {}
290
291    void operator()(Simulator* simulator) const VIXL_OVERRIDE;
292
293   private:
294    // Pointer to the function that will be intercepted.
295    R (*function_)(P...);
296
297    // Function to be called instead of function_
298    InterceptionCallback callback_;
299  };
300
301  // Register a new BranchInterception object. If 'function' is branched to
302  // (e.g: "blr function") in the future; instead, if provided, 'callback' will
303  // be called otherwise a runtime call will be performed on 'function'.
304  //
305  // For example: this can be used to always perform runtime calls on
306  // non-AArch64 functions without using the macroassembler.
307  //
308  // Note: only unconditional branches to registers are currently supported to
309  // be intercepted, e.g: "br"/"blr".
310  //
311  // TODO: support intercepting other branch types.
312  template <typename R, typename... P>
313  void RegisterBranchInterception(R (*function)(P...),
314                                  InterceptionCallback callback = nullptr) {
315    uintptr_t addr = reinterpret_cast<uintptr_t>(function);
316    std::unique_ptr<BranchInterceptionAbstract> intercept =
317        std::make_unique<BranchInterception<R, P...>>(function, callback);
318    branch_interceptions_.insert(std::make_pair(addr, std::move(intercept)));
319  }
320
321  // Search for branch interceptions to the branch_target address; If one is
322  // found return it otherwise return nullptr.
323  BranchInterceptionAbstract* FindBranchInterception(uint64_t branch_target) {
324    // Check for interceptions to the target address, if one is found, call it.
325    auto search = branch_interceptions_.find(branch_target);
326    if (search != branch_interceptions_.end()) {
327      return search->second.get();
328    } else {
329      return nullptr;
330    }
331  }
332
333  void ResetState() { branch_interceptions_.clear(); }
334
335 private:
336  // Tag recording of each allocated memory in the tag-granule.
337  std::unordered_map<uint64_t, class MetaDataMTE> metadata_mte_;
338
339  // Store a map of addresses to be intercepted and their corresponding branch
340  // interception object, see 'BranchInterception'.
341  std::unordered_map<uintptr_t, std::unique_ptr<BranchInterceptionAbstract>>
342      branch_interceptions_;
343};
344
345
346// Representation of memory, with typed getters and setters for access.
347class Memory {
348 public:
349  explicit Memory(SimStack::Allocated stack) : stack_(std::move(stack)) {
350    metadata_depot_ = nullptr;
351  }
352
353  const SimStack::Allocated& GetStack() { return stack_; }
354
355  template <typename A>
356  bool IsMTETagsMatched(A address, Instruction const* pc = nullptr) const {
357    if (MetaDataDepot::MetaDataMTE::IsActive()) {
358      // Cast the address using a C-style cast. A reinterpret_cast would be
359      // appropriate, but it can't cast one integral type to another.
360      uint64_t addr = (uint64_t)address;
361      int pointer_tag = GetAllocationTagFromAddress(addr);
362      int memory_tag = metadata_depot_->GetMTETag(AddressUntag(addr), pc);
363      return pointer_tag == memory_tag;
364    }
365    return true;
366  }
367
368  template <typename T, typename A>
369  T Read(A address, Instruction const* pc = nullptr) const {
370    T value;
371    VIXL_STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
372                       (sizeof(value) == 4) || (sizeof(value) == 8) ||
373                       (sizeof(value) == 16));
374    auto base = reinterpret_cast<const char*>(AddressUntag(address));
375    if (stack_.IsAccessInGuardRegion(base, sizeof(value))) {
376      VIXL_ABORT_WITH_MSG("Attempt to read from stack guard region");
377    }
378    if (!IsMTETagsMatched(address, pc)) {
379      VIXL_ABORT_WITH_MSG("Tag mismatch.");
380    }
381    memcpy(&value, base, sizeof(value));
382    return value;
383  }
384
385  template <typename T, typename A>
386  void Write(A address, T value, Instruction const* pc = nullptr) const {
387    VIXL_STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
388                       (sizeof(value) == 4) || (sizeof(value) == 8) ||
389                       (sizeof(value) == 16));
390    auto base = reinterpret_cast<char*>(AddressUntag(address));
391    if (stack_.IsAccessInGuardRegion(base, sizeof(value))) {
392      VIXL_ABORT_WITH_MSG("Attempt to write to stack guard region");
393    }
394    if (!IsMTETagsMatched(address, pc)) {
395      VIXL_ABORT_WITH_MSG("Tag mismatch.");
396    }
397    memcpy(base, &value, sizeof(value));
398  }
399
400  template <typename A>
401  uint64_t ReadUint(int size_in_bytes, A address) const {
402    switch (size_in_bytes) {
403      case 1:
404        return Read<uint8_t>(address);
405      case 2:
406        return Read<uint16_t>(address);
407      case 4:
408        return Read<uint32_t>(address);
409      case 8:
410        return Read<uint64_t>(address);
411    }
412    VIXL_UNREACHABLE();
413    return 0;
414  }
415
416  template <typename A>
417  int64_t ReadInt(int size_in_bytes, A address) const {
418    switch (size_in_bytes) {
419      case 1:
420        return Read<int8_t>(address);
421      case 2:
422        return Read<int16_t>(address);
423      case 4:
424        return Read<int32_t>(address);
425      case 8:
426        return Read<int64_t>(address);
427    }
428    VIXL_UNREACHABLE();
429    return 0;
430  }
431
432  template <typename A>
433  void Write(int size_in_bytes, A address, uint64_t value) const {
434    switch (size_in_bytes) {
435      case 1:
436        return Write(address, static_cast<uint8_t>(value));
437      case 2:
438        return Write(address, static_cast<uint16_t>(value));
439      case 4:
440        return Write(address, static_cast<uint32_t>(value));
441      case 8:
442        return Write(address, value);
443    }
444    VIXL_UNREACHABLE();
445  }
446
447  void AppendMetaData(MetaDataDepot* metadata_depot) {
448    VIXL_ASSERT(metadata_depot != nullptr);
449    VIXL_ASSERT(metadata_depot_ == nullptr);
450    metadata_depot_ = metadata_depot;
451  }
452
453 private:
454  SimStack::Allocated stack_;
455  MetaDataDepot* metadata_depot_;
456};
457
458// Represent a register (r0-r31, v0-v31, z0-z31, p0-p15).
459template <unsigned kMaxSizeInBits>
460class SimRegisterBase {
461 public:
462  static const unsigned kMaxSizeInBytes = kMaxSizeInBits / kBitsPerByte;
463  VIXL_STATIC_ASSERT((kMaxSizeInBytes * kBitsPerByte) == kMaxSizeInBits);
464
465  SimRegisterBase() : size_in_bytes_(kMaxSizeInBytes) { Clear(); }
466
467  unsigned GetSizeInBits() const { return size_in_bytes_ * kBitsPerByte; }
468  unsigned GetSizeInBytes() const { return size_in_bytes_; }
469
470  void SetSizeInBytes(unsigned size_in_bytes) {
471    VIXL_ASSERT(size_in_bytes <= kMaxSizeInBytes);
472    size_in_bytes_ = size_in_bytes;
473  }
474  void SetSizeInBits(unsigned size_in_bits) {
475    VIXL_ASSERT(size_in_bits <= kMaxSizeInBits);
476    VIXL_ASSERT((size_in_bits % kBitsPerByte) == 0);
477    SetSizeInBytes(size_in_bits / kBitsPerByte);
478  }
479
480  // Write the specified value. The value is zero-extended if necessary.
481  template <typename T>
482  void Write(T new_value) {
483    // All AArch64 registers are zero-extending.
484    if (sizeof(new_value) < GetSizeInBytes()) Clear();
485    WriteLane(new_value, 0);
486    NotifyRegisterWrite();
487  }
488  template <typename T>
489  VIXL_DEPRECATED("Write", void Set(T new_value)) {
490    Write(new_value);
491  }
492
493  void Clear() {
494    memset(value_, 0, kMaxSizeInBytes);
495    NotifyRegisterWrite();
496  }
497
498  // Insert a typed value into a register, leaving the rest of the register
499  // unchanged. The lane parameter indicates where in the register the value
500  // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
501  // 0 represents the least significant bits.
502  template <typename T>
503  void Insert(int lane, T new_value) {
504    WriteLane(new_value, lane);
505    NotifyRegisterWrite();
506  }
507
508  // Get the value as the specified type. The value is truncated if necessary.
509  template <typename T>
510  T Get() const {
511    return GetLane<T>(0);
512  }
513
514  // Get the lane value as the specified type. The value is truncated if
515  // necessary.
516  template <typename T>
517  T GetLane(int lane) const {
518    T result;
519    ReadLane(&result, lane);
520    return result;
521  }
522  template <typename T>
523  VIXL_DEPRECATED("GetLane", T Get(int lane) const) {
524    return GetLane(lane);
525  }
526
527  // Get the value of a specific bit, indexed from the least-significant bit of
528  // lane 0.
529  bool GetBit(int bit) const {
530    int bit_in_byte = bit % (sizeof(value_[0]) * kBitsPerByte);
531    int byte = bit / (sizeof(value_[0]) * kBitsPerByte);
532    return ((value_[byte] >> bit_in_byte) & 1) != 0;
533  }
534
535  // Return a pointer to the raw, underlying byte array.
536  const uint8_t* GetBytes() const { return value_; }
537
538  // TODO: Make this return a map of updated bytes, so that we can highlight
539  // updated lanes for load-and-insert. (That never happens for scalar code, but
540  // NEON has some instructions that can update individual lanes.)
541  bool WrittenSinceLastLog() const { return written_since_last_log_; }
542
543  void NotifyRegisterLogged() { written_since_last_log_ = false; }
544
545 protected:
546  uint8_t value_[kMaxSizeInBytes];
547
548  unsigned size_in_bytes_;
549
550  // Helpers to aid with register tracing.
551  bool written_since_last_log_;
552
553  void NotifyRegisterWrite() { written_since_last_log_ = true; }
554
555 private:
556  template <typename T>
557  void ReadLane(T* dst, int lane) const {
558    VIXL_ASSERT(lane >= 0);
559    VIXL_ASSERT((sizeof(*dst) + (lane * sizeof(*dst))) <= GetSizeInBytes());
560    memcpy(dst, &value_[lane * sizeof(*dst)], sizeof(*dst));
561  }
562
563  template <typename T>
564  void WriteLane(T src, int lane) {
565    VIXL_ASSERT(lane >= 0);
566    VIXL_ASSERT((sizeof(src) + (lane * sizeof(src))) <= GetSizeInBytes());
567    memcpy(&value_[lane * sizeof(src)], &src, sizeof(src));
568  }
569
570  // The default ReadLane and WriteLane methods assume what we are copying is
571  // "trivially copyable" by using memcpy. We have to provide alternative
572  // implementations for SimFloat16 which cannot be copied this way.
573
574  void ReadLane(vixl::internal::SimFloat16* dst, int lane) const {
575    uint16_t rawbits;
576    ReadLane(&rawbits, lane);
577    *dst = RawbitsToFloat16(rawbits);
578  }
579
580  void WriteLane(vixl::internal::SimFloat16 src, int lane) {
581    WriteLane(Float16ToRawbits(src), lane);
582  }
583};
584
585typedef SimRegisterBase<kXRegSize> SimRegister;      // r0-r31
586typedef SimRegisterBase<kPRegMaxSize> SimPRegister;  // p0-p15
587// FFR has the same format as a predicate register.
588typedef SimPRegister SimFFRRegister;
589
590// v0-v31 and z0-z31
591class SimVRegister : public SimRegisterBase<kZRegMaxSize> {
592 public:
593  SimVRegister() : SimRegisterBase<kZRegMaxSize>(), accessed_as_z_(false) {}
594
595  void NotifyAccessAsZ() { accessed_as_z_ = true; }
596
597  void NotifyRegisterLogged() {
598    SimRegisterBase<kZRegMaxSize>::NotifyRegisterLogged();
599    accessed_as_z_ = false;
600  }
601
602  bool AccessedAsZSinceLastLog() const { return accessed_as_z_; }
603
604 private:
605  bool accessed_as_z_;
606};
607
608// Representation of a SVE predicate register.
609class LogicPRegister {
610 public:
611  inline LogicPRegister(
612      SimPRegister& other)  // NOLINT(runtime/references)(runtime/explicit)
613      : register_(other) {}
614
615  // Set a conveniently-sized block to 16 bits as the minimum predicate length
616  // is 16 bits and allow to be increased to multiples of 16 bits.
617  typedef uint16_t ChunkType;
618
619  // Assign a bit into the end positon of the specified lane.
620  // The bit is zero-extended if necessary.
621  void SetActive(VectorFormat vform, int lane_index, bool value) {
622    int psize = LaneSizeInBytesFromFormat(vform);
623    int bit_index = lane_index * psize;
624    int byte_index = bit_index / kBitsPerByte;
625    int bit_offset = bit_index % kBitsPerByte;
626    uint8_t byte = register_.GetLane<uint8_t>(byte_index);
627    register_.Insert(byte_index, ZeroExtend(byte, bit_offset, psize, value));
628  }
629
630  bool IsActive(VectorFormat vform, int lane_index) const {
631    int psize = LaneSizeInBytesFromFormat(vform);
632    int bit_index = lane_index * psize;
633    int byte_index = bit_index / kBitsPerByte;
634    int bit_offset = bit_index % kBitsPerByte;
635    uint8_t byte = register_.GetLane<uint8_t>(byte_index);
636    return ExtractBit(byte, bit_offset);
637  }
638
639  // The accessors for bulk processing.
640  int GetChunkCount() const {
641    VIXL_ASSERT((register_.GetSizeInBytes() % sizeof(ChunkType)) == 0);
642    return register_.GetSizeInBytes() / sizeof(ChunkType);
643  }
644
645  ChunkType GetChunk(int lane) const { return GetActiveMask<ChunkType>(lane); }
646
647  void SetChunk(int lane, ChunkType new_value) {
648    SetActiveMask(lane, new_value);
649  }
650
651  void SetAllBits() {
652    int chunk_size = sizeof(ChunkType) * kBitsPerByte;
653    ChunkType bits = GetUintMask(chunk_size);
654    for (int lane = 0;
655         lane < (static_cast<int>(register_.GetSizeInBits() / chunk_size));
656         lane++) {
657      SetChunk(lane, bits);
658    }
659  }
660
661  template <typename T>
662  T GetActiveMask(int lane) const {
663    return register_.GetLane<T>(lane);
664  }
665
666  template <typename T>
667  void SetActiveMask(int lane, T new_value) {
668    register_.Insert<T>(lane, new_value);
669  }
670
671  void Clear() { register_.Clear(); }
672
673  bool Aliases(const LogicPRegister& other) const {
674    return &register_ == &other.register_;
675  }
676
677 private:
678  // The bit assignment is zero-extended to fill the size of predicate element.
679  uint8_t ZeroExtend(uint8_t byte, int index, int psize, bool value) {
680    VIXL_ASSERT(index >= 0);
681    VIXL_ASSERT(index + psize <= kBitsPerByte);
682    int bits = value ? 1 : 0;
683    switch (psize) {
684      case 1:
685        AssignBit(byte, index, bits);
686        break;
687      case 2:
688        AssignBits(byte, index, 0x03, bits);
689        break;
690      case 4:
691        AssignBits(byte, index, 0x0f, bits);
692        break;
693      case 8:
694        AssignBits(byte, index, 0xff, bits);
695        break;
696      default:
697        VIXL_UNREACHABLE();
698        return 0;
699    }
700    return byte;
701  }
702
703  SimPRegister& register_;
704};
705
706// Representation of a vector register, with typed getters and setters for lanes
707// and additional information to represent lane state.
708class LogicVRegister {
709 public:
710  inline LogicVRegister(
711      SimVRegister& other)  // NOLINT(runtime/references)(runtime/explicit)
712      : register_(other) {
713    for (size_t i = 0; i < ArrayLength(saturated_); i++) {
714      saturated_[i] = kNotSaturated;
715    }
716    for (size_t i = 0; i < ArrayLength(round_); i++) {
717      round_[i] = 0;
718    }
719  }
720
721  int64_t Int(VectorFormat vform, int index) const {
722    if (IsSVEFormat(vform)) register_.NotifyAccessAsZ();
723    int64_t element;
724    switch (LaneSizeInBitsFromFormat(vform)) {
725      case 8:
726        element = register_.GetLane<int8_t>(index);
727        break;
728      case 16:
729        element = register_.GetLane<int16_t>(index);
730        break;
731      case 32:
732        element = register_.GetLane<int32_t>(index);
733        break;
734      case 64:
735        element = register_.GetLane<int64_t>(index);
736        break;
737      default:
738        VIXL_UNREACHABLE();
739        return 0;
740    }
741    return element;
742  }
743
744  uint64_t Uint(VectorFormat vform, int index) const {
745    if (IsSVEFormat(vform)) register_.NotifyAccessAsZ();
746    uint64_t element;
747    switch (LaneSizeInBitsFromFormat(vform)) {
748      case 8:
749        element = register_.GetLane<uint8_t>(index);
750        break;
751      case 16:
752        element = register_.GetLane<uint16_t>(index);
753        break;
754      case 32:
755        element = register_.GetLane<uint32_t>(index);
756        break;
757      case 64:
758        element = register_.GetLane<uint64_t>(index);
759        break;
760      default:
761        VIXL_UNREACHABLE();
762        return 0;
763    }
764    return element;
765  }
766
767  int UintArray(VectorFormat vform, uint64_t* dst) const {
768    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
769      dst[i] = Uint(vform, i);
770    }
771    return LaneCountFromFormat(vform);
772  }
773
774  uint64_t UintLeftJustified(VectorFormat vform, int index) const {
775    return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
776  }
777
778  int64_t IntLeftJustified(VectorFormat vform, int index) const {
779    uint64_t value = UintLeftJustified(vform, index);
780    int64_t result;
781    memcpy(&result, &value, sizeof(result));
782    return result;
783  }
784
785  void SetInt(VectorFormat vform, int index, int64_t value) const {
786    if (IsSVEFormat(vform)) register_.NotifyAccessAsZ();
787    switch (LaneSizeInBitsFromFormat(vform)) {
788      case 8:
789        register_.Insert(index, static_cast<int8_t>(value));
790        break;
791      case 16:
792        register_.Insert(index, static_cast<int16_t>(value));
793        break;
794      case 32:
795        register_.Insert(index, static_cast<int32_t>(value));
796        break;
797      case 64:
798        register_.Insert(index, static_cast<int64_t>(value));
799        break;
800      default:
801        VIXL_UNREACHABLE();
802        return;
803    }
804  }
805
806  void SetIntArray(VectorFormat vform, const int64_t* src) const {
807    ClearForWrite(vform);
808    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
809      SetInt(vform, i, src[i]);
810    }
811  }
812
813  void SetUint(VectorFormat vform, int index, uint64_t value) const {
814    if (IsSVEFormat(vform)) register_.NotifyAccessAsZ();
815    switch (LaneSizeInBitsFromFormat(vform)) {
816      case 8:
817        register_.Insert(index, static_cast<uint8_t>(value));
818        break;
819      case 16:
820        register_.Insert(index, static_cast<uint16_t>(value));
821        break;
822      case 32:
823        register_.Insert(index, static_cast<uint32_t>(value));
824        break;
825      case 64:
826        register_.Insert(index, static_cast<uint64_t>(value));
827        break;
828      default:
829        VIXL_UNREACHABLE();
830        return;
831    }
832  }
833
834  void SetUintArray(VectorFormat vform, const uint64_t* src) const {
835    ClearForWrite(vform);
836    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
837      SetUint(vform, i, src[i]);
838    }
839  }
840
841  template <typename T>
842  T Float(int index) const {
843    return register_.GetLane<T>(index);
844  }
845
846  template <typename T>
847  void SetFloat(int index, T value) const {
848    register_.Insert(index, value);
849  }
850
851  template <typename T>
852  void SetFloat(VectorFormat vform, int index, T value) const {
853    if (IsSVEFormat(vform)) register_.NotifyAccessAsZ();
854    register_.Insert(index, value);
855  }
856
857  void Clear() { register_.Clear(); }
858
859  // When setting a result in a register larger than the result itself, the top
860  // bits of the register must be cleared.
861  void ClearForWrite(VectorFormat vform) const {
862    // SVE destinations write whole registers, so we have nothing to clear.
863    if (IsSVEFormat(vform)) return;
864
865    unsigned size = RegisterSizeInBytesFromFormat(vform);
866    for (unsigned i = size; i < register_.GetSizeInBytes(); i++) {
867      SetUint(kFormat16B, i, 0);
868    }
869  }
870
871  // Saturation state for each lane of a vector.
872  enum Saturation {
873    kNotSaturated = 0,
874    kSignedSatPositive = 1 << 0,
875    kSignedSatNegative = 1 << 1,
876    kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
877    kSignedSatUndefined = kSignedSatMask,
878    kUnsignedSatPositive = 1 << 2,
879    kUnsignedSatNegative = 1 << 3,
880    kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
881    kUnsignedSatUndefined = kUnsignedSatMask
882  };
883
884  // Getters for saturation state.
885  Saturation GetSignedSaturation(int index) {
886    return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
887  }
888
889  Saturation GetUnsignedSaturation(int index) {
890    return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
891  }
892
893  // Setters for saturation state.
894  void ClearSat(int index) { saturated_[index] = kNotSaturated; }
895
896  void SetSignedSat(int index, bool positive) {
897    SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
898  }
899
900  void SetUnsignedSat(int index, bool positive) {
901    SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
902  }
903
904  void SetSatFlag(int index, Saturation sat) {
905    saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
906    VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined);
907    VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined);
908  }
909
910  // Saturate lanes of a vector based on saturation state.
911  LogicVRegister& SignedSaturate(VectorFormat vform) {
912    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
913      Saturation sat = GetSignedSaturation(i);
914      if (sat == kSignedSatPositive) {
915        SetInt(vform, i, MaxIntFromFormat(vform));
916      } else if (sat == kSignedSatNegative) {
917        SetInt(vform, i, MinIntFromFormat(vform));
918      }
919    }
920    return *this;
921  }
922
923  LogicVRegister& UnsignedSaturate(VectorFormat vform) {
924    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
925      Saturation sat = GetUnsignedSaturation(i);
926      if (sat == kUnsignedSatPositive) {
927        SetUint(vform, i, MaxUintFromFormat(vform));
928      } else if (sat == kUnsignedSatNegative) {
929        SetUint(vform, i, 0);
930      }
931    }
932    return *this;
933  }
934
935  // Getter for rounding state.
936  bool GetRounding(int index) { return round_[index]; }
937
938  // Setter for rounding state.
939  void SetRounding(int index, bool round) { round_[index] = round; }
940
941  // Round lanes of a vector based on rounding state.
942  LogicVRegister& Round(VectorFormat vform) {
943    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
944      SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0));
945    }
946    return *this;
947  }
948
949  // Unsigned halve lanes of a vector, and use the saturation state to set the
950  // top bit.
951  LogicVRegister& Uhalve(VectorFormat vform) {
952    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
953      uint64_t val = Uint(vform, i);
954      SetRounding(i, (val & 1) == 1);
955      val >>= 1;
956      if (GetUnsignedSaturation(i) != kNotSaturated) {
957        // If the operation causes unsigned saturation, the bit shifted into the
958        // most significant bit must be set.
959        val |= (MaxUintFromFormat(vform) >> 1) + 1;
960      }
961      SetInt(vform, i, val);
962    }
963    return *this;
964  }
965
966  // Signed halve lanes of a vector, and use the carry state to set the top bit.
967  LogicVRegister& Halve(VectorFormat vform) {
968    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
969      int64_t val = Int(vform, i);
970      SetRounding(i, (val & 1) == 1);
971      val = ExtractSignedBitfield64(63, 1, val);  // >>= 1
972      if (GetSignedSaturation(i) == kNotSaturated) {
973        SetInt(vform, i, val);
974      } else {
975        // If the operation causes signed saturation, the sign bit must be
976        // inverted.
977        uint64_t uval = static_cast<uint64_t>(val);
978        SetUint(vform, i, uval ^ ((MaxUintFromFormat(vform) >> 1) + 1));
979      }
980    }
981    return *this;
982  }
983
984  int LaneCountFromFormat(VectorFormat vform) const {
985    if (IsSVEFormat(vform)) {
986      return register_.GetSizeInBits() / LaneSizeInBitsFromFormat(vform);
987    } else {
988      return vixl::aarch64::LaneCountFromFormat(vform);
989    }
990  }
991
992 private:
993  SimVRegister& register_;
994
995  // Allocate one saturation state entry per lane; largest register is type Q,
996  // and lanes can be a minimum of one byte wide.
997  Saturation saturated_[kZRegMaxSizeInBytes];
998
999  // Allocate one rounding state entry per lane.
1000  bool round_[kZRegMaxSizeInBytes];
1001};
1002
1003// Represent an SVE addressing mode and abstract per-lane address generation to
1004// make iteration easy.
1005//
1006// Contiguous accesses are described with a simple base address, the memory
1007// occupied by each lane (`SetMsizeInBytesLog2()`) and the number of elements in
1008// each struct (`SetRegCount()`).
1009//
1010// Scatter-gather accesses also require a SimVRegister and information about how
1011// to extract lanes from it.
1012class LogicSVEAddressVector {
1013 public:
1014  // scalar-plus-scalar
1015  // scalar-plus-immediate
1016  explicit LogicSVEAddressVector(uint64_t base)
1017      : base_(base),
1018        msize_in_bytes_log2_(kUnknownMsizeInBytesLog2),
1019        reg_count_(1),
1020        vector_(NULL),
1021        vector_form_(kFormatUndefined),
1022        vector_mod_(NO_SVE_OFFSET_MODIFIER),
1023        vector_shift_(0) {}
1024
1025  // scalar-plus-vector
1026  // vector-plus-immediate
1027  //    `base` should be the constant used for each element. That is, the value
1028  //    of `xn`, or `#<imm>`.
1029  //    `vector` should be the SimVRegister with offsets for each element. The
1030  //    vector format must be specified; SVE scatter/gather accesses typically
1031  //    support both 32-bit and 64-bit addressing.
1032  //
1033  //    `mod` and `shift` correspond to the modifiers applied to each element in
1034  //    scalar-plus-vector forms, such as those used for unpacking and
1035  //    sign-extension. They are not used for vector-plus-immediate.
1036  LogicSVEAddressVector(uint64_t base,
1037                        const SimVRegister* vector,
1038                        VectorFormat vform,
1039                        SVEOffsetModifier mod = NO_SVE_OFFSET_MODIFIER,
1040                        int shift = 0)
1041      : base_(base),
1042        msize_in_bytes_log2_(kUnknownMsizeInBytesLog2),
1043        reg_count_(1),
1044        vector_(vector),
1045        vector_form_(vform),
1046        vector_mod_(mod),
1047        vector_shift_(shift) {}
1048
1049  // Set `msize` -- the memory occupied by each lane -- for address
1050  // calculations.
1051  void SetMsizeInBytesLog2(int msize_in_bytes_log2) {
1052    VIXL_ASSERT(msize_in_bytes_log2 >= static_cast<int>(kBRegSizeInBytesLog2));
1053    VIXL_ASSERT(msize_in_bytes_log2 <= static_cast<int>(kDRegSizeInBytesLog2));
1054    msize_in_bytes_log2_ = msize_in_bytes_log2;
1055  }
1056
1057  bool HasMsize() const {
1058    return msize_in_bytes_log2_ != kUnknownMsizeInBytesLog2;
1059  }
1060
1061  int GetMsizeInBytesLog2() const {
1062    VIXL_ASSERT(HasMsize());
1063    return msize_in_bytes_log2_;
1064  }
1065  int GetMsizeInBitsLog2() const {
1066    return GetMsizeInBytesLog2() + kBitsPerByteLog2;
1067  }
1068
1069  int GetMsizeInBytes() const { return 1 << GetMsizeInBytesLog2(); }
1070  int GetMsizeInBits() const { return 1 << GetMsizeInBitsLog2(); }
1071
1072  void SetRegCount(int reg_count) {
1073    VIXL_ASSERT(reg_count >= 1);  // E.g. ld1/st1
1074    VIXL_ASSERT(reg_count <= 4);  // E.g. ld4/st4
1075    reg_count_ = reg_count;
1076  }
1077
1078  int GetRegCount() const { return reg_count_; }
1079
1080  // Full per-element address calculation for structured accesses.
1081  //
1082  // Note that the register number argument (`reg`) is zero-based.
1083  uint64_t GetElementAddress(int lane, int reg) const {
1084    VIXL_ASSERT(reg < GetRegCount());
1085    // Individual structures are always contiguous in memory, so this
1086    // implementation works for both contiguous and scatter-gather addressing.
1087    return GetStructAddress(lane) + (reg * GetMsizeInBytes());
1088  }
1089
1090  // Full per-struct address calculation for structured accesses.
1091  uint64_t GetStructAddress(int lane) const;
1092
1093  bool IsContiguous() const { return vector_ == NULL; }
1094  bool IsScatterGather() const { return !IsContiguous(); }
1095
1096 private:
1097  uint64_t base_;
1098  int msize_in_bytes_log2_;
1099  int reg_count_;
1100
1101  const SimVRegister* vector_;
1102  VectorFormat vector_form_;
1103  SVEOffsetModifier vector_mod_;
1104  int vector_shift_;
1105
1106  static const int kUnknownMsizeInBytesLog2 = -1;
1107};
1108
1109// The proper way to initialize a simulated system register (such as NZCV) is as
1110// follows:
1111//  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
1112class SimSystemRegister {
1113 public:
1114  // The default constructor represents a register which has no writable bits.
1115  // It is not possible to set its value to anything other than 0.
1116  SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
1117
1118  uint32_t GetRawValue() const { return value_; }
1119  VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) {
1120    return GetRawValue();
1121  }
1122
1123  void SetRawValue(uint32_t new_value) {
1124    value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
1125  }
1126
1127  uint32_t ExtractBits(int msb, int lsb) const {
1128    return ExtractUnsignedBitfield32(msb, lsb, value_);
1129  }
1130  VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) {
1131    return ExtractBits(msb, lsb);
1132  }
1133
1134  int32_t ExtractSignedBits(int msb, int lsb) const {
1135    return ExtractSignedBitfield32(msb, lsb, value_);
1136  }
1137  VIXL_DEPRECATED("ExtractSignedBits",
1138                  int32_t SignedBits(int msb, int lsb) const) {
1139    return ExtractSignedBits(msb, lsb);
1140  }
1141
1142  void SetBits(int msb, int lsb, uint32_t bits);
1143
1144  // Default system register values.
1145  static SimSystemRegister DefaultValueFor(SystemRegister id);
1146
1147#define DEFINE_GETTER(Name, HighBit, LowBit, Func)                            \
1148  uint32_t Get##Name() const { return this->Func(HighBit, LowBit); }          \
1149  VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \
1150  void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); }
1151#define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
1152  static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
1153
1154  SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
1155
1156#undef DEFINE_ZERO_BITS
1157#undef DEFINE_GETTER
1158
1159 protected:
1160  // Most system registers only implement a few of the bits in the word. Other
1161  // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
1162  // describes the bits which are not modifiable.
1163  SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
1164      : value_(value), write_ignore_mask_(write_ignore_mask) {}
1165
1166  uint32_t value_;
1167  uint32_t write_ignore_mask_;
1168};
1169
1170
1171class SimExclusiveLocalMonitor {
1172 public:
1173  SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) {
1174    Clear();
1175  }
1176
1177  // Clear the exclusive monitor (like clrex).
1178  void Clear() {
1179    address_ = 0;
1180    size_ = 0;
1181  }
1182
1183  // Clear the exclusive monitor most of the time.
1184  void MaybeClear() {
1185    if ((seed_ % kSkipClearProbability) != 0) {
1186      Clear();
1187    }
1188
1189    // Advance seed_ using a simple linear congruential generator.
1190    seed_ = (seed_ * 48271) % 2147483647;
1191  }
1192
1193  // Mark the address range for exclusive access (like load-exclusive).
1194  void MarkExclusive(uint64_t address, size_t size) {
1195    address_ = address;
1196    size_ = size;
1197  }
1198
1199  // Return true if the address range is marked (like store-exclusive).
1200  // This helper doesn't implicitly clear the monitor.
1201  bool IsExclusive(uint64_t address, size_t size) {
1202    VIXL_ASSERT(size > 0);
1203    // Be pedantic: Require both the address and the size to match.
1204    return (size == size_) && (address == address_);
1205  }
1206
1207 private:
1208  uint64_t address_;
1209  size_t size_;
1210
1211  const int kSkipClearProbability;
1212  uint32_t seed_;
1213};
1214
1215
1216// We can't accurate simulate the global monitor since it depends on external
1217// influences. Instead, this implementation occasionally causes accesses to
1218// fail, according to kPassProbability.
1219class SimExclusiveGlobalMonitor {
1220 public:
1221  SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {}
1222
1223  bool IsExclusive(uint64_t address, size_t size) {
1224    USE(address, size);
1225
1226    bool pass = (seed_ % kPassProbability) != 0;
1227    // Advance seed_ using a simple linear congruential generator.
1228    seed_ = (seed_ * 48271) % 2147483647;
1229    return pass;
1230  }
1231
1232 private:
1233  const int kPassProbability;
1234  uint32_t seed_;
1235};
1236
1237
1238class Debugger;
1239
1240
1241class Simulator : public DecoderVisitor {
1242 public:
1243#ifndef PANDA_BUILD
1244  explicit Simulator(Decoder* decoder,
1245                     FILE* stream = stdout,
1246                     SimStack::Allocated stack = SimStack().Allocate());
1247#else
1248  explicit Simulator(Decoder* decoder,
1249                     FILE* stream = stdout,
1250                     SimStack::Allocated stack = SimStack().Allocate()) = delete;
1251  Simulator(PandaAllocator* allocator,
1252            Decoder* decoder,
1253            SimStack::Allocated stack,
1254            FILE* stream = stdout);
1255#endif
1256  ~Simulator();
1257
1258#ifdef PANDA_BUILD
1259  AllocatorWrapper GetAllocator() const {
1260    return allocator_;
1261  }
1262#endif
1263
1264  void ResetState();
1265
1266  // Run the simulator.
1267  virtual void Run();
1268  void RunFrom(const Instruction* first);
1269
1270
1271#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
1272    (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
1273  // Templated `RunFrom` version taking care of passing arguments and returning
1274  // the result value.
1275  // This allows code like:
1276  //    int32_t res = simulator.RunFrom<int32_t, int32_t>(GenerateCode(),
1277  //                                                      0x123);
1278  // It requires VIXL's ABI features, and C++11 or greater.
1279  // Also, the initialisation of tuples is incorrect in GCC before 4.9.1:
1280  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
1281  template <typename R, typename... P>
1282  R RunFrom(const Instruction* code, P... arguments) {
1283    return RunFromStructHelper<R, P...>::Wrapper(this, code, arguments...);
1284  }
1285
1286  template <typename R, typename... P>
1287  struct RunFromStructHelper {
1288    static R Wrapper(Simulator* simulator,
1289                     const Instruction* code,
1290                     P... arguments) {
1291      ABI abi;
1292      std::tuple<P...> unused_tuple{
1293          // TODO: We currently do not support arguments passed on the stack. We
1294          // could do so by using `WriteGenericOperand()` here, but may need to
1295          // add features to handle situations where the stack is or is not set
1296          // up.
1297          (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
1298                                           .GetCPURegister(),
1299                                       arguments),
1300           arguments)...};
1301      simulator->RunFrom(code);
1302      return simulator->ReadGenericOperand<R>(abi.GetReturnGenericOperand<R>());
1303    }
1304  };
1305
1306  // Partial specialization when the return type is `void`.
1307  template <typename... P>
1308  struct RunFromStructHelper<void, P...> {
1309    static void Wrapper(Simulator* simulator,
1310                        const Instruction* code,
1311                        P... arguments) {
1312      ABI abi;
1313      std::tuple<P...> unused_tuple{
1314          // TODO: We currently do not support arguments passed on the stack. We
1315          // could do so by using `WriteGenericOperand()` here, but may need to
1316          // add features to handle situations where the stack is or is not set
1317          // up.
1318          (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
1319                                           .GetCPURegister(),
1320                                       arguments),
1321           arguments)...};
1322      simulator->RunFrom(code);
1323    }
1324  };
1325#endif
1326
1327  // Execution ends when the PC hits this address.
1328  static const Instruction* kEndOfSimAddress;
1329
1330  // Simulation helpers.
1331  bool IsSimulationFinished() const { return pc_ == kEndOfSimAddress; }
1332
1333  const Instruction* ReadPc() const { return pc_; }
1334  VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
1335
1336  enum BranchLogMode { LogBranches, NoBranchLog };
1337
1338  void WritePc(const Instruction* new_pc,
1339               BranchLogMode log_mode = LogBranches) {
1340    if (log_mode == LogBranches) LogTakenBranch(new_pc);
1341    pc_ = AddressUntag(new_pc);
1342    pc_modified_ = true;
1343  }
1344  VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) {
1345    return WritePc(new_pc);
1346  }
1347
1348  void IncrementPc() {
1349    if (!pc_modified_) {
1350      pc_ = pc_->GetNextInstruction();
1351    }
1352  }
1353  VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); }
1354
1355  BType ReadBType() const { return btype_; }
1356  void WriteNextBType(BType btype) { next_btype_ = btype; }
1357  void UpdateBType() {
1358    btype_ = next_btype_;
1359    next_btype_ = DefaultBType;
1360  }
1361
1362  // Helper function to determine BType for branches.
1363  BType GetBTypeFromInstruction(const Instruction* instr) const;
1364
1365  bool PcIsInGuardedPage() const { return guard_pages_; }
1366  void SetGuardedPages(bool guard_pages) { guard_pages_ = guard_pages; }
1367
1368  const Instruction* GetLastExecutedInstruction() const { return last_instr_; }
1369
1370  void ExecuteInstruction() {
1371    // The program counter should always be aligned.
1372    VIXL_ASSERT(IsWordAligned(pc_));
1373    pc_modified_ = false;
1374
1375    // On guarded pages, if BType is not zero, take an exception on any
1376    // instruction other than BTI, PACI[AB]SP, HLT or BRK.
1377    if (PcIsInGuardedPage() && (ReadBType() != DefaultBType)) {
1378      if (pc_->IsPAuth()) {
1379        Instr i = pc_->Mask(SystemPAuthMask);
1380        if ((i != PACIASP) && (i != PACIBSP)) {
1381          VIXL_ABORT_WITH_MSG(
1382              "Executing non-BTI instruction with wrong BType.");
1383        }
1384      } else if (!pc_->IsBti() && !pc_->IsException()) {
1385        VIXL_ABORT_WITH_MSG("Executing non-BTI instruction with wrong BType.");
1386      }
1387    }
1388
1389    bool last_instr_was_movprfx =
1390        (form_hash_ == "movprfx_z_z"_h) || (form_hash_ == "movprfx_z_p_z"_h);
1391
1392    // decoder_->Decode(...) triggers at least the following visitors:
1393    //  1. The CPUFeaturesAuditor (`cpu_features_auditor_`).
1394    //  2. The PrintDisassembler (`print_disasm_`), if enabled.
1395    //  3. The Simulator (`this`).
1396    // User can add additional visitors at any point, but the Simulator requires
1397    // that the ordering above is preserved.
1398    decoder_->Decode(pc_);
1399
1400    if (last_instr_was_movprfx) {
1401      VIXL_ASSERT(last_instr_ != NULL);
1402      VIXL_CHECK(pc_->CanTakeSVEMovprfx(form_hash_, last_instr_));
1403    }
1404
1405    last_instr_ = ReadPc();
1406    IncrementPc();
1407    LogAllWrittenRegisters();
1408    UpdateBType();
1409
1410    VIXL_CHECK(cpu_features_auditor_.InstructionIsAvailable());
1411  }
1412
1413  virtual void Visit(Metadata* metadata,
1414                     const Instruction* instr) VIXL_OVERRIDE;
1415
1416#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
1417  VISITOR_LIST_THAT_RETURN(DECLARE)
1418#undef DECLARE
1419#define DECLARE(A) \
1420  VIXL_NO_RETURN virtual void Visit##A(const Instruction* instr);
1421  VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
1422#undef DECLARE
1423
1424  void Simulate_PdT_PgZ_ZnT_ZmT(const Instruction* instr);
1425  void Simulate_PdT_Xn_Xm(const Instruction* instr);
1426  void Simulate_ZdB_Zn1B_Zn2B_imm(const Instruction* instr);
1427  void Simulate_ZdB_ZnB_ZmB(const Instruction* instr);
1428  void Simulate_ZdD_ZnD_ZmD_imm(const Instruction* instr);
1429  void Simulate_ZdH_PgM_ZnS(const Instruction* instr);
1430  void Simulate_ZdH_ZnH_ZmH_imm(const Instruction* instr);
1431  void Simulate_ZdS_PgM_ZnD(const Instruction* instr);
1432  void Simulate_ZdS_PgM_ZnS(const Instruction* instr);
1433  void Simulate_ZdS_ZnS_ZmS_imm(const Instruction* instr);
1434  void Simulate_ZdT_PgM_ZnT(const Instruction* instr);
1435  void Simulate_ZdT_PgZ_ZnT_ZmT(const Instruction* instr);
1436  void Simulate_ZdT_ZnT_ZmT(const Instruction* instr);
1437  void Simulate_ZdT_ZnT_ZmTb(const Instruction* instr);
1438  void Simulate_ZdT_ZnT_const(const Instruction* instr);
1439  void Simulate_ZdaD_ZnS_ZmS_imm(const Instruction* instr);
1440  void Simulate_ZdaH_ZnH_ZmH_imm_const(const Instruction* instr);
1441  void Simulate_ZdaS_ZnH_ZmH(const Instruction* instr);
1442  void Simulate_ZdaS_ZnH_ZmH_imm(const Instruction* instr);
1443  void Simulate_ZdaS_ZnS_ZmS_imm_const(const Instruction* instr);
1444  void Simulate_ZdaT_PgM_ZnTb(const Instruction* instr);
1445  void Simulate_ZdaT_ZnT_ZmT(const Instruction* instr);
1446  void Simulate_ZdaT_ZnT_const(const Instruction* instr);
1447  void Simulate_ZdaT_ZnTb_ZmTb(const Instruction* instr);
1448  void Simulate_ZdnT_PgM_ZdnT_ZmT(const Instruction* instr);
1449  void Simulate_ZdnT_PgM_ZdnT_const(const Instruction* instr);
1450  void Simulate_ZdnT_ZdnT_ZmT_const(const Instruction* instr);
1451  void Simulate_ZtD_PgZ_ZnD_Xm(const Instruction* instr);
1452  void Simulate_ZtD_Pg_ZnD_Xm(const Instruction* instr);
1453  void Simulate_ZtS_PgZ_ZnS_Xm(const Instruction* instr);
1454  void Simulate_ZtS_Pg_ZnS_Xm(const Instruction* instr);
1455
1456  void SimulateSVEHalvingAddSub(const Instruction* instr);
1457  void SimulateSVESaturatingArithmetic(const Instruction* instr);
1458  void SimulateSVEIntArithPair(const Instruction* instr);
1459  void SimulateSVENarrow(const Instruction* instr);
1460  void SimulateSVEInterleavedArithLong(const Instruction* instr);
1461  void SimulateSVEShiftLeftImm(const Instruction* instr);
1462  void SimulateSVEAddSubCarry(const Instruction* instr);
1463  void SimulateSVEAddSubHigh(const Instruction* instr);
1464  void SimulateSVEIntMulLongVec(const Instruction* instr);
1465  void SimulateSVESaturatingIntMulLongIdx(const Instruction* instr);
1466  void SimulateSVEExclusiveOrRotate(const Instruction* instr);
1467  void SimulateSVEBitwiseTernary(const Instruction* instr);
1468  void SimulateSVEComplexDotProduct(const Instruction* instr);
1469  void SimulateSVEMulIndex(const Instruction* instr);
1470  void SimulateSVEMlaMlsIndex(const Instruction* instr);
1471  void SimulateSVEComplexIntMulAdd(const Instruction* instr);
1472  void SimulateSVESaturatingMulAddHigh(const Instruction* instr);
1473  void SimulateSVESaturatingMulHighIndex(const Instruction* instr);
1474  void SimulateSVEFPConvertLong(const Instruction* instr);
1475  void SimulateMatrixMul(const Instruction* instr);
1476  void SimulateSVEFPMatrixMul(const Instruction* instr);
1477  void SimulateNEONMulByElementLong(const Instruction* instr);
1478  void SimulateNEONFPMulByElement(const Instruction* instr);
1479  void SimulateNEONFPMulByElementLong(const Instruction* instr);
1480  void SimulateNEONComplexMulByElement(const Instruction* instr);
1481  void SimulateNEONDotProdByElement(const Instruction* instr);
1482  void SimulateMTEAddSubTag(const Instruction* instr);
1483  void SimulateMTETagMaskInsert(const Instruction* instr);
1484  void SimulateMTESubPointer(const Instruction* instr);
1485  void SimulateMTELoadTag(const Instruction* instr);
1486  void SimulateMTEStoreTag(const Instruction* instr);
1487  void SimulateMTEStoreTagPair(const Instruction* instr);
1488  void Simulate_XdSP_XnSP_Xm(const Instruction* instr);
1489  void SimulateCpy(const Instruction* instr);
1490  void SimulateCpyFP(const Instruction* instr);
1491  void SimulateCpyP(const Instruction* instr);
1492  void SimulateCpyM(const Instruction* instr);
1493  void SimulateCpyE(const Instruction* instr);
1494  void SimulateSetP(const Instruction* instr);
1495  void SimulateSetM(const Instruction* instr);
1496  void SimulateSetE(const Instruction* instr);
1497  void SimulateSetGP(const Instruction* instr);
1498  void SimulateSetGM(const Instruction* instr);
1499  void SimulateSignedMinMax(const Instruction* instr);
1500  void SimulateUnsignedMinMax(const Instruction* instr);
1501
1502
1503  // Integer register accessors.
1504
1505  // Basic accessor: Read the register as the specified type.
1506  template <typename T>
1507  T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
1508    VIXL_ASSERT(
1509        code < kNumberOfRegisters ||
1510        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
1511    if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
1512      T result;
1513      memset(&result, 0, sizeof(result));
1514      return result;
1515    }
1516    if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
1517      code = 31;
1518    }
1519    return registers_[code].Get<T>();
1520  }
1521  template <typename T>
1522  VIXL_DEPRECATED("ReadRegister",
1523                  T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister)
1524                      const) {
1525    return ReadRegister<T>(code, r31mode);
1526  }
1527
1528  // Common specialized accessors for the ReadRegister() template.
1529  int32_t ReadWRegister(unsigned code,
1530                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
1531    return ReadRegister<int32_t>(code, r31mode);
1532  }
1533  VIXL_DEPRECATED("ReadWRegister",
1534                  int32_t wreg(unsigned code,
1535                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
1536    return ReadWRegister(code, r31mode);
1537  }
1538
1539  int64_t ReadXRegister(unsigned code,
1540                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
1541    return ReadRegister<int64_t>(code, r31mode);
1542  }
1543  VIXL_DEPRECATED("ReadXRegister",
1544                  int64_t xreg(unsigned code,
1545                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
1546    return ReadXRegister(code, r31mode);
1547  }
1548
1549  SimPRegister& ReadPRegister(unsigned code) {
1550    VIXL_ASSERT(code < kNumberOfPRegisters);
1551    return pregisters_[code];
1552  }
1553
1554  SimFFRRegister& ReadFFR() { return ffr_register_; }
1555
1556  // As above, with parameterized size and return type. The value is
1557  // either zero-extended or truncated to fit, as required.
1558  template <typename T>
1559  T ReadRegister(unsigned size,
1560                 unsigned code,
1561                 Reg31Mode r31mode = Reg31IsZeroRegister) const {
1562    uint64_t raw;
1563    switch (size) {
1564      case kWRegSize:
1565        raw = ReadRegister<uint32_t>(code, r31mode);
1566        break;
1567      case kXRegSize:
1568        raw = ReadRegister<uint64_t>(code, r31mode);
1569        break;
1570      default:
1571        VIXL_UNREACHABLE();
1572        return 0;
1573    }
1574
1575    T result;
1576    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
1577    // Copy the result and truncate to fit. This assumes a little-endian host.
1578    memcpy(&result, &raw, sizeof(result));
1579    return result;
1580  }
1581  template <typename T>
1582  VIXL_DEPRECATED("ReadRegister",
1583                  T reg(unsigned size,
1584                        unsigned code,
1585                        Reg31Mode r31mode = Reg31IsZeroRegister) const) {
1586    return ReadRegister<T>(size, code, r31mode);
1587  }
1588
1589  // Use int64_t by default if T is not specified.
1590  int64_t ReadRegister(unsigned size,
1591                       unsigned code,
1592                       Reg31Mode r31mode = Reg31IsZeroRegister) const {
1593    return ReadRegister<int64_t>(size, code, r31mode);
1594  }
1595  VIXL_DEPRECATED("ReadRegister",
1596                  int64_t reg(unsigned size,
1597                              unsigned code,
1598                              Reg31Mode r31mode = Reg31IsZeroRegister) const) {
1599    return ReadRegister(size, code, r31mode);
1600  }
1601
1602  enum RegLogMode { LogRegWrites, NoRegLog };
1603
1604  // Write 'value' into an integer register. The value is zero-extended. This
1605  // behaviour matches AArch64 register writes.
1606  //
1607  // SP may be specified in one of two ways:
1608  //  - (code == kSPRegInternalCode) && (r31mode == Reg31IsZeroRegister)
1609  //  - (code == 31) && (r31mode == Reg31IsStackPointer)
1610  template <typename T>
1611  void WriteRegister(unsigned code,
1612                     T value,
1613                     RegLogMode log_mode = LogRegWrites,
1614                     Reg31Mode r31mode = Reg31IsZeroRegister) {
1615    if (sizeof(T) < kWRegSizeInBytes) {
1616      // We use a C-style cast on purpose here.
1617      // Since we do not have access to 'constepxr if', the casts in this `if`
1618      // must be valid even if we know the code will never be executed, in
1619      // particular when `T` is a pointer type.
1620      int64_t tmp_64bit = (int64_t)value;
1621      int32_t tmp_32bit = static_cast<int32_t>(tmp_64bit);
1622      WriteRegister<int32_t>(code, tmp_32bit, log_mode, r31mode);
1623      return;
1624    }
1625
1626    VIXL_ASSERT((sizeof(T) == kWRegSizeInBytes) ||
1627                (sizeof(T) == kXRegSizeInBytes));
1628    VIXL_ASSERT(
1629        (code < kNumberOfRegisters) ||
1630        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
1631
1632    if (code == 31) {
1633      if (r31mode == Reg31IsZeroRegister) {
1634        // Discard writes to the zero register.
1635        return;
1636      } else {
1637        code = kSPRegInternalCode;
1638      }
1639    }
1640
1641    // registers_[31] is the stack pointer.
1642    VIXL_STATIC_ASSERT((kSPRegInternalCode % kNumberOfRegisters) == 31);
1643    registers_[code % kNumberOfRegisters].Write(value);
1644
1645    if (log_mode == LogRegWrites) {
1646      LogRegister(code, GetPrintRegisterFormatForSize(sizeof(T)));
1647    }
1648  }
1649  template <typename T>
1650  VIXL_DEPRECATED("WriteRegister",
1651                  void set_reg(unsigned code,
1652                               T value,
1653                               RegLogMode log_mode = LogRegWrites,
1654                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
1655    WriteRegister<T>(code, value, log_mode, r31mode);
1656  }
1657
1658  // Common specialized accessors for the set_reg() template.
1659  void WriteWRegister(unsigned code,
1660                      int32_t value,
1661                      RegLogMode log_mode = LogRegWrites,
1662                      Reg31Mode r31mode = Reg31IsZeroRegister) {
1663    WriteRegister(code, value, log_mode, r31mode);
1664  }
1665  VIXL_DEPRECATED("WriteWRegister",
1666                  void set_wreg(unsigned code,
1667                                int32_t value,
1668                                RegLogMode log_mode = LogRegWrites,
1669                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
1670    WriteWRegister(code, value, log_mode, r31mode);
1671  }
1672
1673  void WriteXRegister(unsigned code,
1674                      int64_t value,
1675                      RegLogMode log_mode = LogRegWrites,
1676                      Reg31Mode r31mode = Reg31IsZeroRegister) {
1677    WriteRegister(code, value, log_mode, r31mode);
1678  }
1679  VIXL_DEPRECATED("WriteXRegister",
1680                  void set_xreg(unsigned code,
1681                                int64_t value,
1682                                RegLogMode log_mode = LogRegWrites,
1683                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
1684    WriteXRegister(code, value, log_mode, r31mode);
1685  }
1686
1687  // As above, with parameterized size and type. The value is either
1688  // zero-extended or truncated to fit, as required.
1689  template <typename T>
1690  void WriteRegister(unsigned size,
1691                     unsigned code,
1692                     T value,
1693                     RegLogMode log_mode = LogRegWrites,
1694                     Reg31Mode r31mode = Reg31IsZeroRegister) {
1695    // Zero-extend the input.
1696    uint64_t raw = 0;
1697    VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw));
1698    memcpy(&raw, &value, sizeof(value));
1699
1700    // Write (and possibly truncate) the value.
1701    switch (size) {
1702      case kWRegSize:
1703        WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode);
1704        break;
1705      case kXRegSize:
1706        WriteRegister(code, raw, log_mode, r31mode);
1707        break;
1708      default:
1709        VIXL_UNREACHABLE();
1710        return;
1711    }
1712  }
1713  template <typename T>
1714  VIXL_DEPRECATED("WriteRegister",
1715                  void set_reg(unsigned size,
1716                               unsigned code,
1717                               T value,
1718                               RegLogMode log_mode = LogRegWrites,
1719                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
1720    WriteRegister(size, code, value, log_mode, r31mode);
1721  }
1722
1723  // Common specialized accessors for the set_reg() template.
1724
1725  // Commonly-used special cases.
1726  template <typename T>
1727  void WriteLr(T value) {
1728    WriteRegister(kLinkRegCode, value);
1729  }
1730  template <typename T>
1731  VIXL_DEPRECATED("WriteLr", void set_lr(T value)) {
1732    WriteLr(value);
1733  }
1734
1735  template <typename T>
1736  void WriteSp(T value) {
1737    WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer);
1738  }
1739  template <typename T>
1740  VIXL_DEPRECATED("WriteSp", void set_sp(T value)) {
1741    WriteSp(value);
1742  }
1743
1744  // Vector register accessors.
1745  // These are equivalent to the integer register accessors, but for vector
1746  // registers.
1747
1748  // A structure for representing a 128-bit Q register.
1749  struct qreg_t {
1750    uint8_t val[kQRegSizeInBytes];
1751  };
1752
1753  // A structure for representing a SVE Z register.
1754  struct zreg_t {
1755    uint8_t val[kZRegMaxSizeInBytes];
1756  };
1757
1758  // Basic accessor: read the register as the specified type.
1759  template <typename T>
1760  T ReadVRegister(unsigned code) const {
1761    VIXL_STATIC_ASSERT(
1762        (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) ||
1763        (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) ||
1764        (sizeof(T) == kQRegSizeInBytes));
1765    VIXL_ASSERT(code < kNumberOfVRegisters);
1766
1767    return vregisters_[code].Get<T>();
1768  }
1769  template <typename T>
1770  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) {
1771    return ReadVRegister<T>(code);
1772  }
1773
1774  // Common specialized accessors for the vreg() template.
1775  int8_t ReadBRegister(unsigned code) const {
1776    return ReadVRegister<int8_t>(code);
1777  }
1778  VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) {
1779    return ReadBRegister(code);
1780  }
1781
1782  vixl::internal::SimFloat16 ReadHRegister(unsigned code) const {
1783    return RawbitsToFloat16(ReadHRegisterBits(code));
1784  }
1785  VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) {
1786    return Float16ToRawbits(ReadHRegister(code));
1787  }
1788
1789  uint16_t ReadHRegisterBits(unsigned code) const {
1790    return ReadVRegister<uint16_t>(code);
1791  }
1792
1793  float ReadSRegister(unsigned code) const {
1794    return ReadVRegister<float>(code);
1795  }
1796  VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) {
1797    return ReadSRegister(code);
1798  }
1799
1800  uint32_t ReadSRegisterBits(unsigned code) const {
1801    return ReadVRegister<uint32_t>(code);
1802  }
1803  VIXL_DEPRECATED("ReadSRegisterBits",
1804                  uint32_t sreg_bits(unsigned code) const) {
1805    return ReadSRegisterBits(code);
1806  }
1807
1808  double ReadDRegister(unsigned code) const {
1809    return ReadVRegister<double>(code);
1810  }
1811  VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) {
1812    return ReadDRegister(code);
1813  }
1814
1815  uint64_t ReadDRegisterBits(unsigned code) const {
1816    return ReadVRegister<uint64_t>(code);
1817  }
1818  VIXL_DEPRECATED("ReadDRegisterBits",
1819                  uint64_t dreg_bits(unsigned code) const) {
1820    return ReadDRegisterBits(code);
1821  }
1822
1823  qreg_t ReadQRegister(unsigned code) const {
1824    return ReadVRegister<qreg_t>(code);
1825  }
1826  VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) {
1827    return ReadQRegister(code);
1828  }
1829
1830  // As above, with parameterized size and return type. The value is
1831  // either zero-extended or truncated to fit, as required.
1832  template <typename T>
1833  T ReadVRegister(unsigned size, unsigned code) const {
1834    uint64_t raw = 0;
1835    T result;
1836
1837    switch (size) {
1838      case kSRegSize:
1839        raw = ReadVRegister<uint32_t>(code);
1840        break;
1841      case kDRegSize:
1842        raw = ReadVRegister<uint64_t>(code);
1843        break;
1844      default:
1845        VIXL_UNREACHABLE();
1846        break;
1847    }
1848
1849    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
1850    // Copy the result and truncate to fit. This assumes a little-endian host.
1851    memcpy(&result, &raw, sizeof(result));
1852    return result;
1853  }
1854  template <typename T>
1855  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) {
1856    return ReadVRegister<T>(size, code);
1857  }
1858
1859  SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; }
1860  VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) {
1861    return ReadVRegister(code);
1862  }
1863
1864  // Basic accessor: Write the specified value.
1865  template <typename T>
1866  void WriteVRegister(unsigned code,
1867                      T value,
1868                      RegLogMode log_mode = LogRegWrites) {
1869    VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) ||
1870                       (sizeof(value) == kHRegSizeInBytes) ||
1871                       (sizeof(value) == kSRegSizeInBytes) ||
1872                       (sizeof(value) == kDRegSizeInBytes) ||
1873                       (sizeof(value) == kQRegSizeInBytes) ||
1874                       (sizeof(value) == kZRegMaxSizeInBytes));
1875    VIXL_ASSERT(code < kNumberOfVRegisters);
1876    vregisters_[code].Write(value);
1877
1878    if (log_mode == LogRegWrites) {
1879      LogVRegister(code, GetPrintRegisterFormat(value));
1880    }
1881  }
1882  template <typename T>
1883  VIXL_DEPRECATED("WriteVRegister",
1884                  void set_vreg(unsigned code,
1885                                T value,
1886                                RegLogMode log_mode = LogRegWrites)) {
1887    WriteVRegister(code, value, log_mode);
1888  }
1889
1890  // Common specialized accessors for the WriteVRegister() template.
1891  void WriteBRegister(unsigned code,
1892                      int8_t value,
1893                      RegLogMode log_mode = LogRegWrites) {
1894    WriteVRegister(code, value, log_mode);
1895  }
1896  VIXL_DEPRECATED("WriteBRegister",
1897                  void set_breg(unsigned code,
1898                                int8_t value,
1899                                RegLogMode log_mode = LogRegWrites)) {
1900    return WriteBRegister(code, value, log_mode);
1901  }
1902
1903  void WriteHRegister(unsigned code,
1904                      vixl::internal::SimFloat16 value,
1905                      RegLogMode log_mode = LogRegWrites) {
1906    WriteVRegister(code, Float16ToRawbits(value), log_mode);
1907  }
1908
1909  void WriteHRegister(unsigned code,
1910                      int16_t value,
1911                      RegLogMode log_mode = LogRegWrites) {
1912    WriteVRegister(code, value, log_mode);
1913  }
1914  VIXL_DEPRECATED("WriteHRegister",
1915                  void set_hreg(unsigned code,
1916                                int16_t value,
1917                                RegLogMode log_mode = LogRegWrites)) {
1918    return WriteHRegister(code, value, log_mode);
1919  }
1920
1921  void WriteSRegister(unsigned code,
1922                      float value,
1923                      RegLogMode log_mode = LogRegWrites) {
1924    WriteVRegister(code, value, log_mode);
1925  }
1926  VIXL_DEPRECATED("WriteSRegister",
1927                  void set_sreg(unsigned code,
1928                                float value,
1929                                RegLogMode log_mode = LogRegWrites)) {
1930    WriteSRegister(code, value, log_mode);
1931  }
1932
1933  void WriteSRegisterBits(unsigned code,
1934                          uint32_t value,
1935                          RegLogMode log_mode = LogRegWrites) {
1936    WriteVRegister(code, value, log_mode);
1937  }
1938  VIXL_DEPRECATED("WriteSRegisterBits",
1939                  void set_sreg_bits(unsigned code,
1940                                     uint32_t value,
1941                                     RegLogMode log_mode = LogRegWrites)) {
1942    WriteSRegisterBits(code, value, log_mode);
1943  }
1944
1945  void WriteDRegister(unsigned code,
1946                      double value,
1947                      RegLogMode log_mode = LogRegWrites) {
1948    WriteVRegister(code, value, log_mode);
1949  }
1950  VIXL_DEPRECATED("WriteDRegister",
1951                  void set_dreg(unsigned code,
1952                                double value,
1953                                RegLogMode log_mode = LogRegWrites)) {
1954    WriteDRegister(code, value, log_mode);
1955  }
1956
1957  void WriteDRegisterBits(unsigned code,
1958                          uint64_t value,
1959                          RegLogMode log_mode = LogRegWrites) {
1960    WriteVRegister(code, value, log_mode);
1961  }
1962  VIXL_DEPRECATED("WriteDRegisterBits",
1963                  void set_dreg_bits(unsigned code,
1964                                     uint64_t value,
1965                                     RegLogMode log_mode = LogRegWrites)) {
1966    WriteDRegisterBits(code, value, log_mode);
1967  }
1968
1969  void WriteQRegister(unsigned code,
1970                      qreg_t value,
1971                      RegLogMode log_mode = LogRegWrites) {
1972    WriteVRegister(code, value, log_mode);
1973  }
1974  VIXL_DEPRECATED("WriteQRegister",
1975                  void set_qreg(unsigned code,
1976                                qreg_t value,
1977                                RegLogMode log_mode = LogRegWrites)) {
1978    WriteQRegister(code, value, log_mode);
1979  }
1980
1981  void WriteZRegister(unsigned code,
1982                      zreg_t value,
1983                      RegLogMode log_mode = LogRegWrites) {
1984    WriteVRegister(code, value, log_mode);
1985  }
1986
1987  template <typename T>
1988  T ReadRegister(Register reg) const {
1989    return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister);
1990  }
1991
1992  template <typename T>
1993  void WriteRegister(Register reg,
1994                     T value,
1995                     RegLogMode log_mode = LogRegWrites) {
1996    WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister);
1997  }
1998
1999  template <typename T>
2000  T ReadVRegister(VRegister vreg) const {
2001    return ReadVRegister<T>(vreg.GetCode());
2002  }
2003
2004  template <typename T>
2005  void WriteVRegister(VRegister vreg,
2006                      T value,
2007                      RegLogMode log_mode = LogRegWrites) {
2008    WriteVRegister<T>(vreg.GetCode(), value, log_mode);
2009  }
2010
2011  template <typename T>
2012  T ReadCPURegister(CPURegister reg) const {
2013    if (reg.IsVRegister()) {
2014      return ReadVRegister<T>(VRegister(reg));
2015    } else {
2016      return ReadRegister<T>(Register(reg));
2017    }
2018  }
2019
2020  template <typename T>
2021  void WriteCPURegister(CPURegister reg,
2022                        T value,
2023                        RegLogMode log_mode = LogRegWrites) {
2024    if (reg.IsVRegister()) {
2025      WriteVRegister<T>(VRegister(reg), value, log_mode);
2026    } else {
2027      WriteRegister<T>(Register(reg), value, log_mode);
2028    }
2029  }
2030
2031  template <typename T, typename A>
2032  T MemRead(A address) const {
2033    Instruction const* pc = ReadPc();
2034    return memory_.Read<T>(address, pc);
2035  }
2036
2037  template <typename T, typename A>
2038  void MemWrite(A address, T value) const {
2039    Instruction const* pc = ReadPc();
2040    return memory_.Write(address, value, pc);
2041  }
2042
2043  template <typename A>
2044  uint64_t MemReadUint(int size_in_bytes, A address) const {
2045    return memory_.ReadUint(size_in_bytes, address);
2046  }
2047
2048  template <typename A>
2049  int64_t MemReadInt(int size_in_bytes, A address) const {
2050    return memory_.ReadInt(size_in_bytes, address);
2051  }
2052
2053  template <typename A>
2054  void MemWrite(int size_in_bytes, A address, uint64_t value) const {
2055    return memory_.Write(size_in_bytes, address, value);
2056  }
2057
2058  void LoadLane(LogicVRegister dst,
2059                VectorFormat vform,
2060                int index,
2061                uint64_t addr) const {
2062    unsigned msize_in_bytes = LaneSizeInBytesFromFormat(vform);
2063    LoadUintToLane(dst, vform, msize_in_bytes, index, addr);
2064  }
2065
2066  void LoadUintToLane(LogicVRegister dst,
2067                      VectorFormat vform,
2068                      unsigned msize_in_bytes,
2069                      int index,
2070                      uint64_t addr) const {
2071    dst.SetUint(vform, index, MemReadUint(msize_in_bytes, addr));
2072  }
2073
2074  void LoadIntToLane(LogicVRegister dst,
2075                     VectorFormat vform,
2076                     unsigned msize_in_bytes,
2077                     int index,
2078                     uint64_t addr) const {
2079    dst.SetInt(vform, index, MemReadInt(msize_in_bytes, addr));
2080  }
2081
2082  void StoreLane(const LogicVRegister& src,
2083                 VectorFormat vform,
2084                 int index,
2085                 uint64_t addr) const {
2086    unsigned msize_in_bytes = LaneSizeInBytesFromFormat(vform);
2087    MemWrite(msize_in_bytes, addr, src.Uint(vform, index));
2088  }
2089
2090  uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
2091
2092  template <typename T>
2093  T ReadGenericOperand(GenericOperand operand) const {
2094    if (operand.IsCPURegister()) {
2095      return ReadCPURegister<T>(operand.GetCPURegister());
2096    } else {
2097      VIXL_ASSERT(operand.IsMemOperand());
2098      return MemRead<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
2099    }
2100  }
2101
2102  template <typename T>
2103  void WriteGenericOperand(GenericOperand operand,
2104                           T value,
2105                           RegLogMode log_mode = LogRegWrites) {
2106    if (operand.IsCPURegister()) {
2107      // Outside SIMD, registers are 64-bit or a subset of a 64-bit register. If
2108      // the width of the value to write is smaller than 64 bits, the unused
2109      // bits may contain unrelated values that the code following this write
2110      // needs to handle gracefully.
2111      // Here we fill the unused bits with a predefined pattern to catch issues
2112      // early.
2113      VIXL_ASSERT(operand.GetCPURegister().GetSizeInBits() <= 64);
2114      uint64_t raw = 0xdeadda1adeadda1a;
2115      memcpy(&raw, &value, sizeof(value));
2116      WriteCPURegister(operand.GetCPURegister(), raw, log_mode);
2117    } else {
2118      VIXL_ASSERT(operand.IsMemOperand());
2119      MemWrite(ComputeMemOperandAddress(operand.GetMemOperand()), value);
2120    }
2121  }
2122
2123  bool ReadN() const { return nzcv_.GetN() != 0; }
2124  VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); }
2125
2126  bool ReadZ() const { return nzcv_.GetZ() != 0; }
2127  VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); }
2128
2129  bool ReadC() const { return nzcv_.GetC() != 0; }
2130  VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); }
2131
2132  bool ReadV() const { return nzcv_.GetV() != 0; }
2133  VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); }
2134
2135  SimSystemRegister& ReadNzcv() { return nzcv_; }
2136  VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); }
2137
2138  // TODO: Find a way to make the fpcr_ members return the proper types, so
2139  // these accessors are not necessary.
2140  FPRounding ReadRMode() const {
2141    return static_cast<FPRounding>(fpcr_.GetRMode());
2142  }
2143  VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); }
2144
2145  UseDefaultNaN ReadDN() const {
2146    return fpcr_.GetDN() != 0 ? kUseDefaultNaN : kIgnoreDefaultNaN;
2147  }
2148
2149  VIXL_DEPRECATED("ReadDN", bool DN()) {
2150    return ReadDN() == kUseDefaultNaN ? true : false;
2151  }
2152
2153  SimSystemRegister& ReadFpcr() { return fpcr_; }
2154  VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); }
2155
2156  // Specify relevant register formats for Print(V)Register and related helpers.
2157  enum PrintRegisterFormat {
2158    // The lane size.
2159    kPrintRegLaneSizeB = 0 << 0,
2160    kPrintRegLaneSizeH = 1 << 0,
2161    kPrintRegLaneSizeS = 2 << 0,
2162    kPrintRegLaneSizeW = kPrintRegLaneSizeS,
2163    kPrintRegLaneSizeD = 3 << 0,
2164    kPrintRegLaneSizeX = kPrintRegLaneSizeD,
2165    kPrintRegLaneSizeQ = 4 << 0,
2166    kPrintRegLaneSizeUnknown = 5 << 0,
2167
2168    kPrintRegLaneSizeOffset = 0,
2169    kPrintRegLaneSizeMask = 7 << 0,
2170
2171    // The overall register size.
2172    kPrintRegAsScalar = 0,
2173    kPrintRegAsDVector = 1 << 3,
2174    kPrintRegAsQVector = 2 << 3,
2175    kPrintRegAsSVEVector = 3 << 3,
2176
2177    kPrintRegAsVectorMask = 3 << 3,
2178
2179    // Indicate floating-point format lanes. (This flag is only supported for
2180    // S-, H-, and D-sized lanes.)
2181    kPrintRegAsFP = 1 << 5,
2182
2183    // With this flag, print helpers won't check that the upper bits are zero.
2184    // This also forces the register name to be printed with the `reg<msb:0>`
2185    // format.
2186    //
2187    // The flag is supported with any PrintRegisterFormat other than those with
2188    // kPrintRegAsSVEVector.
2189    kPrintRegPartial = 1 << 6,
2190
2191// Supported combinations.
2192// These exist so that they can be referred to by name, but also because C++
2193// does not allow enum types to hold values that aren't explicitly
2194// enumerated, and we want to be able to combine the above flags.
2195
2196// Scalar formats.
2197#define VIXL_DECL_PRINT_REG_SCALAR(size)                           \
2198  kPrint##size##Reg = kPrintRegLaneSize##size | kPrintRegAsScalar, \
2199  kPrint##size##RegPartial = kPrintRegLaneSize##size | kPrintRegPartial
2200#define VIXL_DECL_PRINT_REG_SCALAR_FP(size)                  \
2201  VIXL_DECL_PRINT_REG_SCALAR(size)                           \
2202  , kPrint##size##RegFP = kPrint##size##Reg | kPrintRegAsFP, \
2203    kPrint##size##RegPartialFP = kPrint##size##RegPartial | kPrintRegAsFP
2204    VIXL_DECL_PRINT_REG_SCALAR(W),
2205    VIXL_DECL_PRINT_REG_SCALAR(X),
2206    VIXL_DECL_PRINT_REG_SCALAR_FP(H),
2207    VIXL_DECL_PRINT_REG_SCALAR_FP(S),
2208    VIXL_DECL_PRINT_REG_SCALAR_FP(D),
2209    VIXL_DECL_PRINT_REG_SCALAR(Q),
2210#undef VIXL_DECL_PRINT_REG_SCALAR
2211#undef VIXL_DECL_PRINT_REG_SCALAR_FP
2212
2213#define VIXL_DECL_PRINT_REG_NEON(count, type, size)                     \
2214  kPrintReg##count##type = kPrintRegLaneSize##type | kPrintRegAs##size, \
2215  kPrintReg##count##type##Partial = kPrintReg##count##type | kPrintRegPartial
2216#define VIXL_DECL_PRINT_REG_NEON_FP(count, type, size)                   \
2217  VIXL_DECL_PRINT_REG_NEON(count, type, size)                            \
2218  , kPrintReg##count##type##FP = kPrintReg##count##type | kPrintRegAsFP, \
2219    kPrintReg##count##type##PartialFP =                                  \
2220        kPrintReg##count##type##Partial | kPrintRegAsFP
2221    VIXL_DECL_PRINT_REG_NEON(1, B, Scalar),
2222    VIXL_DECL_PRINT_REG_NEON(8, B, DVector),
2223    VIXL_DECL_PRINT_REG_NEON(16, B, QVector),
2224    VIXL_DECL_PRINT_REG_NEON_FP(1, H, Scalar),
2225    VIXL_DECL_PRINT_REG_NEON_FP(4, H, DVector),
2226    VIXL_DECL_PRINT_REG_NEON_FP(8, H, QVector),
2227    VIXL_DECL_PRINT_REG_NEON_FP(1, S, Scalar),
2228    VIXL_DECL_PRINT_REG_NEON_FP(2, S, DVector),
2229    VIXL_DECL_PRINT_REG_NEON_FP(4, S, QVector),
2230    VIXL_DECL_PRINT_REG_NEON_FP(1, D, Scalar),
2231    VIXL_DECL_PRINT_REG_NEON_FP(2, D, QVector),
2232    VIXL_DECL_PRINT_REG_NEON(1, Q, Scalar),
2233#undef VIXL_DECL_PRINT_REG_NEON
2234#undef VIXL_DECL_PRINT_REG_NEON_FP
2235
2236#define VIXL_DECL_PRINT_REG_SVE(type)                                 \
2237  kPrintRegVn##type = kPrintRegLaneSize##type | kPrintRegAsSVEVector, \
2238  kPrintRegVn##type##Partial = kPrintRegVn##type | kPrintRegPartial
2239#define VIXL_DECL_PRINT_REG_SVE_FP(type)                       \
2240  VIXL_DECL_PRINT_REG_SVE(type)                                \
2241  , kPrintRegVn##type##FP = kPrintRegVn##type | kPrintRegAsFP, \
2242    kPrintRegVn##type##PartialFP = kPrintRegVn##type##Partial | kPrintRegAsFP
2243    VIXL_DECL_PRINT_REG_SVE(B),
2244    VIXL_DECL_PRINT_REG_SVE_FP(H),
2245    VIXL_DECL_PRINT_REG_SVE_FP(S),
2246    VIXL_DECL_PRINT_REG_SVE_FP(D),
2247    VIXL_DECL_PRINT_REG_SVE(Q)
2248#undef VIXL_DECL_PRINT_REG_SVE
2249#undef VIXL_DECL_PRINT_REG_SVE_FP
2250  };
2251
2252  // Return `format` with the kPrintRegPartial flag set.
2253  PrintRegisterFormat GetPrintRegPartial(PrintRegisterFormat format) {
2254    // Every PrintRegisterFormat has a kPrintRegPartial counterpart, so the
2255    // result of this cast will always be well-defined.
2256    return static_cast<PrintRegisterFormat>(format | kPrintRegPartial);
2257  }
2258
2259  // For SVE formats, return the format of a Q register part of it.
2260  PrintRegisterFormat GetPrintRegAsQChunkOfSVE(PrintRegisterFormat format) {
2261    VIXL_ASSERT((format & kPrintRegAsVectorMask) == kPrintRegAsSVEVector);
2262    // Keep the FP and lane size fields.
2263    int q_format = format & (kPrintRegLaneSizeMask | kPrintRegAsFP);
2264    // The resulting format must always be partial, because we're not formatting
2265    // the whole Z register.
2266    q_format |= (kPrintRegAsQVector | kPrintRegPartial);
2267
2268    // This cast is always safe because NEON QVector formats support every
2269    // combination of FP and lane size that SVE formats do.
2270    return static_cast<PrintRegisterFormat>(q_format);
2271  }
2272
2273  unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
2274    VIXL_ASSERT((format & kPrintRegLaneSizeMask) != kPrintRegLaneSizeUnknown);
2275    return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
2276  }
2277
2278  unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
2279    return 1 << GetPrintRegLaneSizeInBytesLog2(format);
2280  }
2281
2282  unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
2283    switch (format & kPrintRegAsVectorMask) {
2284      case kPrintRegAsScalar:
2285        return GetPrintRegLaneSizeInBytesLog2(format);
2286      case kPrintRegAsDVector:
2287        return kDRegSizeInBytesLog2;
2288      case kPrintRegAsQVector:
2289        return kQRegSizeInBytesLog2;
2290      default:
2291      case kPrintRegAsSVEVector:
2292        // We print SVE vectors in Q-sized chunks. These need special handling,
2293        // and it's probably an error to call this function in that case.
2294        VIXL_UNREACHABLE();
2295        return kQRegSizeInBytesLog2;
2296    }
2297  }
2298
2299  unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
2300    return 1 << GetPrintRegSizeInBytesLog2(format);
2301  }
2302
2303  unsigned GetPrintRegSizeInBitsLog2(PrintRegisterFormat format) {
2304    return GetPrintRegSizeInBytesLog2(format) + kBitsPerByteLog2;
2305  }
2306
2307  unsigned GetPrintRegSizeInBits(PrintRegisterFormat format) {
2308    return 1 << GetPrintRegSizeInBitsLog2(format);
2309  }
2310
2311  const char* GetPartialRegSuffix(PrintRegisterFormat format) {
2312    switch (GetPrintRegSizeInBitsLog2(format)) {
2313      case kBRegSizeLog2:
2314        return "<7:0>";
2315      case kHRegSizeLog2:
2316        return "<15:0>";
2317      case kSRegSizeLog2:
2318        return "<31:0>";
2319      case kDRegSizeLog2:
2320        return "<63:0>";
2321      case kQRegSizeLog2:
2322        return "<127:0>";
2323    }
2324    VIXL_UNREACHABLE();
2325    return "<UNKNOWN>";
2326  }
2327
2328  unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
2329    unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
2330    unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
2331    VIXL_ASSERT(reg_size_log2 >= lane_size_log2);
2332    return 1 << (reg_size_log2 - lane_size_log2);
2333  }
2334
2335  uint16_t GetPrintRegLaneMask(PrintRegisterFormat format) {
2336    int print_as = format & kPrintRegAsVectorMask;
2337    if (print_as == kPrintRegAsScalar) return 1;
2338
2339    // Vector formats, including SVE formats printed in Q-sized chunks.
2340    static const uint16_t masks[] = {0xffff, 0x5555, 0x1111, 0x0101, 0x0001};
2341    unsigned size_in_bytes_log2 = GetPrintRegLaneSizeInBytesLog2(format);
2342    VIXL_ASSERT(size_in_bytes_log2 < ArrayLength(masks));
2343    uint16_t mask = masks[size_in_bytes_log2];
2344
2345    // Exclude lanes that aren't visible in D vectors.
2346    if (print_as == kPrintRegAsDVector) mask &= 0x00ff;
2347    return mask;
2348  }
2349
2350  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size,
2351                                                    unsigned lane_size);
2352
2353  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) {
2354    return GetPrintRegisterFormatForSize(size, size);
2355  }
2356
2357  PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) {
2358    switch (size) {
2359      default:
2360        VIXL_UNREACHABLE();
2361        return kPrintDReg;
2362      case kDRegSizeInBytes:
2363        return kPrintDReg;
2364      case kSRegSizeInBytes:
2365        return kPrintSReg;
2366      case kHRegSizeInBytes:
2367        return kPrintHReg;
2368    }
2369  }
2370
2371  PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
2372    if ((GetPrintRegLaneSizeInBytes(format) == kHRegSizeInBytes) ||
2373        (GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) ||
2374        (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) {
2375      return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
2376    }
2377    return format;
2378  }
2379
2380  PrintRegisterFormat GetPrintRegisterFormatForSizeTryFP(unsigned size) {
2381    return GetPrintRegisterFormatTryFP(GetPrintRegisterFormatForSize(size));
2382  }
2383
2384  template <typename T>
2385  PrintRegisterFormat GetPrintRegisterFormat(T value) {
2386    return GetPrintRegisterFormatForSize(sizeof(value));
2387  }
2388
2389  PrintRegisterFormat GetPrintRegisterFormat(double value) {
2390    VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes);
2391    return GetPrintRegisterFormatForSizeFP(sizeof(value));
2392  }
2393
2394  PrintRegisterFormat GetPrintRegisterFormat(float value) {
2395    VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes);
2396    return GetPrintRegisterFormatForSizeFP(sizeof(value));
2397  }
2398
2399  PrintRegisterFormat GetPrintRegisterFormat(Float16 value) {
2400    VIXL_STATIC_ASSERT(sizeof(Float16ToRawbits(value)) == kHRegSizeInBytes);
2401    return GetPrintRegisterFormatForSizeFP(sizeof(Float16ToRawbits(value)));
2402  }
2403
2404  PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
2405  PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
2406
2407  // Print all registers of the specified types.
2408  void PrintRegisters();
2409  void PrintVRegisters();
2410  void PrintZRegisters();
2411  void PrintSystemRegisters();
2412
2413  // As above, but only print the registers that have been updated.
2414  void PrintWrittenRegisters();
2415  void PrintWrittenVRegisters();
2416  void PrintWrittenPRegisters();
2417
2418  // As above, but respect LOG_REG and LOG_VREG.
2419  void LogWrittenRegisters() {
2420    if (ShouldTraceRegs()) PrintWrittenRegisters();
2421  }
2422  void LogWrittenVRegisters() {
2423    if (ShouldTraceVRegs()) PrintWrittenVRegisters();
2424  }
2425  void LogWrittenPRegisters() {
2426    if (ShouldTraceVRegs()) PrintWrittenPRegisters();
2427  }
2428  void LogAllWrittenRegisters() {
2429    LogWrittenRegisters();
2430    LogWrittenVRegisters();
2431    LogWrittenPRegisters();
2432  }
2433
2434  // The amount of space to leave for a register name. This is used to keep the
2435  // values vertically aligned. The longest register name has the form
2436  // "z31<2047:1920>". The total overall value indentation must also take into
2437  // account the fixed formatting: "# {name}: 0x{value}".
2438  static const int kPrintRegisterNameFieldWidth = 14;
2439
2440  // Print whole, individual register values.
2441  // - The format can be used to restrict how much of the register is printed,
2442  //   but such formats indicate that the unprinted high-order bits are zero and
2443  //   these helpers will assert that.
2444  // - If the format includes the kPrintRegAsFP flag then human-friendly FP
2445  //   value annotations will be printed.
2446  // - The suffix can be used to add annotations (such as memory access
2447  //   details), or to suppress the newline.
2448  void PrintRegister(int code,
2449                     PrintRegisterFormat format = kPrintXReg,
2450                     const char* suffix = "\n");
2451  void PrintVRegister(int code,
2452                      PrintRegisterFormat format = kPrintReg1Q,
2453                      const char* suffix = "\n");
2454  // PrintZRegister and PrintPRegister print over several lines, so they cannot
2455  // allow the suffix to be overridden.
2456  void PrintZRegister(int code, PrintRegisterFormat format = kPrintRegVnQ);
2457  void PrintPRegister(int code, PrintRegisterFormat format = kPrintRegVnQ);
2458  void PrintFFR(PrintRegisterFormat format = kPrintRegVnQ);
2459  // Print a single Q-sized part of a Z register, or the corresponding two-byte
2460  // part of a P register. These print single lines, and therefore allow the
2461  // suffix to be overridden. The format must include the kPrintRegPartial flag.
2462  void PrintPartialZRegister(int code,
2463                             int q_index,
2464                             PrintRegisterFormat format = kPrintRegVnQ,
2465                             const char* suffix = "\n");
2466  void PrintPartialPRegister(int code,
2467                             int q_index,
2468                             PrintRegisterFormat format = kPrintRegVnQ,
2469                             const char* suffix = "\n");
2470  void PrintPartialPRegister(const char* name,
2471                             const SimPRegister& reg,
2472                             int q_index,
2473                             PrintRegisterFormat format = kPrintRegVnQ,
2474                             const char* suffix = "\n");
2475
2476  // Like Print*Register (above), but respect trace parameters.
2477  void LogRegister(unsigned code, PrintRegisterFormat format) {
2478    if (ShouldTraceRegs()) PrintRegister(code, format);
2479  }
2480  void LogVRegister(unsigned code, PrintRegisterFormat format) {
2481    if (ShouldTraceVRegs()) PrintVRegister(code, format);
2482  }
2483  void LogZRegister(unsigned code, PrintRegisterFormat format) {
2484    if (ShouldTraceVRegs()) PrintZRegister(code, format);
2485  }
2486  void LogPRegister(unsigned code, PrintRegisterFormat format) {
2487    if (ShouldTraceVRegs()) PrintPRegister(code, format);
2488  }
2489  void LogFFR(PrintRegisterFormat format) {
2490    if (ShouldTraceVRegs()) PrintFFR(format);
2491  }
2492
2493  // Other state updates, including system registers.
2494  void PrintSystemRegister(SystemRegister id);
2495  void PrintTakenBranch(const Instruction* target);
2496  void LogSystemRegister(SystemRegister id) {
2497    if (ShouldTraceSysRegs()) PrintSystemRegister(id);
2498  }
2499  void LogTakenBranch(const Instruction* target) {
2500    if (ShouldTraceBranches()) PrintTakenBranch(target);
2501  }
2502
2503  // Trace memory accesses.
2504
2505  // Common, contiguous register accesses (such as for scalars).
2506  // The *Write variants automatically set kPrintRegPartial on the format.
2507  void PrintRead(int rt_code, PrintRegisterFormat format, uintptr_t address);
2508  void PrintExtendingRead(int rt_code,
2509                          PrintRegisterFormat format,
2510                          int access_size_in_bytes,
2511                          uintptr_t address);
2512  void PrintWrite(int rt_code, PrintRegisterFormat format, uintptr_t address);
2513  void PrintVRead(int rt_code, PrintRegisterFormat format, uintptr_t address);
2514  void PrintVWrite(int rt_code, PrintRegisterFormat format, uintptr_t address);
2515  // Simple, unpredicated SVE accesses always access the whole vector, and never
2516  // know the lane type, so there's no need to accept a `format`.
2517  void PrintZRead(int rt_code, uintptr_t address) {
2518    vregisters_[rt_code].NotifyRegisterLogged();
2519    PrintZAccess(rt_code, "<-", address);
2520  }
2521  void PrintZWrite(int rt_code, uintptr_t address) {
2522    PrintZAccess(rt_code, "->", address);
2523  }
2524  void PrintPRead(int rt_code, uintptr_t address) {
2525    pregisters_[rt_code].NotifyRegisterLogged();
2526    PrintPAccess(rt_code, "<-", address);
2527  }
2528  void PrintPWrite(int rt_code, uintptr_t address) {
2529    PrintPAccess(rt_code, "->", address);
2530  }
2531
2532  // Like Print* (above), but respect GetTraceParameters().
2533  void LogRead(int rt_code, PrintRegisterFormat format, uintptr_t address) {
2534    if (ShouldTraceRegs()) PrintRead(rt_code, format, address);
2535  }
2536  void LogExtendingRead(int rt_code,
2537                        PrintRegisterFormat format,
2538                        int access_size_in_bytes,
2539                        uintptr_t address) {
2540    if (ShouldTraceRegs()) {
2541      PrintExtendingRead(rt_code, format, access_size_in_bytes, address);
2542    }
2543  }
2544  void LogWrite(int rt_code, PrintRegisterFormat format, uintptr_t address) {
2545    if (ShouldTraceWrites()) PrintWrite(rt_code, format, address);
2546  }
2547  void LogVRead(int rt_code, PrintRegisterFormat format, uintptr_t address) {
2548    if (ShouldTraceVRegs()) PrintVRead(rt_code, format, address);
2549  }
2550  void LogVWrite(int rt_code, PrintRegisterFormat format, uintptr_t address) {
2551    if (ShouldTraceWrites()) PrintVWrite(rt_code, format, address);
2552  }
2553  void LogZRead(int rt_code, uintptr_t address) {
2554    if (ShouldTraceVRegs()) PrintZRead(rt_code, address);
2555  }
2556  void LogZWrite(int rt_code, uintptr_t address) {
2557    if (ShouldTraceWrites()) PrintZWrite(rt_code, address);
2558  }
2559  void LogPRead(int rt_code, uintptr_t address) {
2560    if (ShouldTraceVRegs()) PrintPRead(rt_code, address);
2561  }
2562  void LogPWrite(int rt_code, uintptr_t address) {
2563    if (ShouldTraceWrites()) PrintPWrite(rt_code, address);
2564  }
2565  void LogMemTransfer(uintptr_t dst, uintptr_t src, uint8_t value) {
2566    if (ShouldTraceWrites()) PrintMemTransfer(dst, src, value);
2567  }
2568  // Helpers for the above, where the access operation is parameterised.
2569  // - For loads, set op = "<-".
2570  // - For stores, set op = "->".
2571  void PrintAccess(int rt_code,
2572                   PrintRegisterFormat format,
2573                   const char* op,
2574                   uintptr_t address);
2575  void PrintVAccess(int rt_code,
2576                    PrintRegisterFormat format,
2577                    const char* op,
2578                    uintptr_t address);
2579  void PrintMemTransfer(uintptr_t dst, uintptr_t src, uint8_t value);
2580  // Simple, unpredicated SVE accesses always access the whole vector, and never
2581  // know the lane type, so these don't accept a `format`.
2582  void PrintZAccess(int rt_code, const char* op, uintptr_t address);
2583  void PrintPAccess(int rt_code, const char* op, uintptr_t address);
2584
2585  // Multiple-structure accesses.
2586  void PrintVStructAccess(int rt_code,
2587                          int reg_count,
2588                          PrintRegisterFormat format,
2589                          const char* op,
2590                          uintptr_t address);
2591  // Single-structure (single-lane) accesses.
2592  void PrintVSingleStructAccess(int rt_code,
2593                                int reg_count,
2594                                int lane,
2595                                PrintRegisterFormat format,
2596                                const char* op,
2597                                uintptr_t address);
2598  // Replicating accesses.
2599  void PrintVReplicatingStructAccess(int rt_code,
2600                                     int reg_count,
2601                                     PrintRegisterFormat format,
2602                                     const char* op,
2603                                     uintptr_t address);
2604
2605  // Multiple-structure accesses.
2606  void PrintZStructAccess(int rt_code,
2607                          int reg_count,
2608                          const LogicPRegister& pg,
2609                          PrintRegisterFormat format,
2610                          int msize_in_bytes,
2611                          const char* op,
2612                          const LogicSVEAddressVector& addr);
2613
2614  // Register-printing helper for all structured accessors.
2615  //
2616  // All lanes (according to `format`) are printed, but lanes indicated by
2617  // `focus_mask` are of particular interest. Each bit corresponds to a byte in
2618  // the printed register, in a manner similar to SVE's predicates. Currently,
2619  // this is used to determine when to print human-readable FP annotations.
2620  void PrintVRegistersForStructuredAccess(int rt_code,
2621                                          int reg_count,
2622                                          uint16_t focus_mask,
2623                                          PrintRegisterFormat format);
2624
2625  // As for the VRegister variant, but print partial Z register names.
2626  void PrintZRegistersForStructuredAccess(int rt_code,
2627                                          int q_index,
2628                                          int reg_count,
2629                                          uint16_t focus_mask,
2630                                          PrintRegisterFormat format);
2631
2632  // Print part of a memory access. This should be used for annotating
2633  // non-trivial accesses, such as structured or sign-extending loads. Call
2634  // Print*Register (or Print*RegistersForStructuredAccess), then
2635  // PrintPartialAccess for each contiguous access that makes up the
2636  // instruction.
2637  //
2638  //  access_mask:
2639  //      The lanes to be printed. Each bit corresponds to a byte in the printed
2640  //      register, in a manner similar to SVE's predicates, except that the
2641  //      lane size is not respected when interpreting lane_mask: unaligned bits
2642  //      must be zeroed.
2643  //
2644  //      This function asserts that this mask is non-zero.
2645  //
2646  //  future_access_mask:
2647  //      The lanes to be printed by a future invocation. This must be specified
2648  //      because vertical lines are drawn for partial accesses that haven't yet
2649  //      been printed. The format is the same as for accessed_mask.
2650  //
2651  //      If a lane is active in both `access_mask` and `future_access_mask`,
2652  //      `access_mask` takes precedence.
2653  //
2654  //  struct_element_count:
2655  //      The number of elements in each structure. For non-structured accesses,
2656  //      set this to one. Along with lane_size_in_bytes, this is used determine
2657  //      the size of each access, and to format the accessed value.
2658  //
2659  //  op:
2660  //      For stores, use "->". For loads, use "<-".
2661  //
2662  //  address:
2663  //      The address of this partial access. (Not the base address of the whole
2664  //      instruction.) The traced value is read from this address (according to
2665  //      part_count and lane_size_in_bytes) so it must be accessible, and when
2666  //      tracing stores, the store must have been executed before this function
2667  //      is called.
2668  //
2669  //  reg_size_in_bytes:
2670  //      The size of the register being accessed. This helper is usually used
2671  //      for V registers or Q-sized chunks of Z registers, so that is the
2672  //      default, but it is possible to use this to annotate X register
2673  //      accesses by specifying kXRegSizeInBytes.
2674  //
2675  // The return value is a future_access_mask suitable for the next iteration,
2676  // so that it is possible to execute this in a loop, until the mask is zero.
2677  // Note that accessed_mask must still be updated by the caller for each call.
2678  uint16_t PrintPartialAccess(uint16_t access_mask,
2679                              uint16_t future_access_mask,
2680                              int struct_element_count,
2681                              int lane_size_in_bytes,
2682                              const char* op,
2683                              uintptr_t address,
2684                              int reg_size_in_bytes = kQRegSizeInBytes);
2685
2686  // Print an abstract register value. This works for all register types, and
2687  // can print parts of registers. This exists to ensure consistent formatting
2688  // of values.
2689  void PrintRegisterValue(const uint8_t* value,
2690                          int value_size,
2691                          PrintRegisterFormat format);
2692  template <typename T>
2693  void PrintRegisterValue(const T& sim_register, PrintRegisterFormat format) {
2694    PrintRegisterValue(sim_register.GetBytes(),
2695                       std::min(sim_register.GetSizeInBytes(),
2696                                kQRegSizeInBytes),
2697                       format);
2698  }
2699
2700  // As above, but format as an SVE predicate value, using binary notation with
2701  // spaces between each bit so that they align with the Z register bytes that
2702  // they predicate.
2703  void PrintPRegisterValue(uint16_t value);
2704
2705  void PrintRegisterValueFPAnnotations(const uint8_t* value,
2706                                       uint16_t lane_mask,
2707                                       PrintRegisterFormat format);
2708  template <typename T>
2709  void PrintRegisterValueFPAnnotations(const T& sim_register,
2710                                       uint16_t lane_mask,
2711                                       PrintRegisterFormat format) {
2712    PrintRegisterValueFPAnnotations(sim_register.GetBytes(), lane_mask, format);
2713  }
2714  template <typename T>
2715  void PrintRegisterValueFPAnnotations(const T& sim_register,
2716                                       PrintRegisterFormat format) {
2717    PrintRegisterValueFPAnnotations(sim_register.GetBytes(),
2718                                    GetPrintRegLaneMask(format),
2719                                    format);
2720  }
2721
2722  VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
2723  void DoTrace(const Instruction* instr);
2724  void DoLog(const Instruction* instr);
2725
2726  static const char* WRegNameForCode(unsigned code,
2727                                     Reg31Mode mode = Reg31IsZeroRegister);
2728  static const char* XRegNameForCode(unsigned code,
2729                                     Reg31Mode mode = Reg31IsZeroRegister);
2730  static const char* BRegNameForCode(unsigned code);
2731  static const char* HRegNameForCode(unsigned code);
2732  static const char* SRegNameForCode(unsigned code);
2733  static const char* DRegNameForCode(unsigned code);
2734  static const char* VRegNameForCode(unsigned code);
2735  static const char* ZRegNameForCode(unsigned code);
2736  static const char* PRegNameForCode(unsigned code);
2737
2738  bool IsColouredTrace() const { return coloured_trace_; }
2739  VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) {
2740    return IsColouredTrace();
2741  }
2742
2743  void SetColouredTrace(bool value);
2744  VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) {
2745    SetColouredTrace(value);
2746  }
2747
2748  // Values for traces parameters defined in simulator-constants-aarch64.h in
2749  // enum TraceParameters.
2750  int GetTraceParameters() const { return trace_parameters_; }
2751  VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) {
2752    return GetTraceParameters();
2753  }
2754
2755  bool ShouldTraceWrites() const {
2756    return (GetTraceParameters() & LOG_WRITE) != 0;
2757  }
2758  bool ShouldTraceRegs() const {
2759    return (GetTraceParameters() & LOG_REGS) != 0;
2760  }
2761  bool ShouldTraceVRegs() const {
2762    return (GetTraceParameters() & LOG_VREGS) != 0;
2763  }
2764  bool ShouldTraceSysRegs() const {
2765    return (GetTraceParameters() & LOG_SYSREGS) != 0;
2766  }
2767  bool ShouldTraceBranches() const {
2768    return (GetTraceParameters() & LOG_BRANCH) != 0;
2769  }
2770
2771  void SetTraceParameters(int parameters);
2772  VIXL_DEPRECATED("SetTraceParameters",
2773                  void set_trace_parameters(int parameters)) {
2774    SetTraceParameters(parameters);
2775  }
2776
2777  // Clear the simulated local monitor to force the next store-exclusive
2778  // instruction to fail.
2779  void ClearLocalMonitor() { local_monitor_.Clear(); }
2780
2781  void SilenceExclusiveAccessWarning() {
2782    print_exclusive_access_warning_ = false;
2783  }
2784
2785  void CheckIsValidUnalignedAtomicAccess(int rn,
2786                                         uint64_t address,
2787                                         unsigned access_size) {
2788    // Verify that the address is available to the host.
2789    VIXL_ASSERT(address == static_cast<uintptr_t>(address));
2790
2791    if (GetCPUFeatures()->Has(CPUFeatures::kUSCAT)) {
2792      // Check that the access falls entirely within one atomic access granule.
2793      if (AlignDown(address, kAtomicAccessGranule) !=
2794          AlignDown(address + access_size - 1, kAtomicAccessGranule)) {
2795        VIXL_ALIGNMENT_EXCEPTION();
2796      }
2797    } else {
2798      // Check that the access is aligned.
2799      if (AlignDown(address, access_size) != address) {
2800        VIXL_ALIGNMENT_EXCEPTION();
2801      }
2802    }
2803
2804    // The sp must be aligned to 16 bytes when it is accessed.
2805    if ((rn == kSpRegCode) && (AlignDown(address, 16) != address)) {
2806      VIXL_ALIGNMENT_EXCEPTION();
2807    }
2808  }
2809
2810  enum PointerType { kDataPointer, kInstructionPointer };
2811
2812  struct PACKey {
2813    uint64_t high;
2814    uint64_t low;
2815    int number;
2816  };
2817
2818  // Current implementation is that all pointers are tagged.
2819  bool HasTBI(uint64_t ptr, PointerType type) {
2820    USE(ptr, type);
2821    return true;
2822  }
2823
2824  // Current implementation uses 48-bit virtual addresses.
2825  int GetBottomPACBit(uint64_t ptr, int ttbr) {
2826    USE(ptr, ttbr);
2827    VIXL_ASSERT((ttbr == 0) || (ttbr == 1));
2828    return 48;
2829  }
2830
2831  // The top PAC bit is 55 for the purposes of relative bit fields with TBI,
2832  // however bit 55 is the TTBR bit regardless of TBI so isn't part of the PAC
2833  // codes in pointers.
2834  int GetTopPACBit(uint64_t ptr, PointerType type) {
2835    return HasTBI(ptr, type) ? 55 : 63;
2836  }
2837
2838  // Armv8.3 Pointer authentication helpers.
2839  uint64_t CalculatePACMask(uint64_t ptr, PointerType type, int ext_bit);
2840  uint64_t ComputePAC(uint64_t data, uint64_t context, PACKey key);
2841  uint64_t AuthPAC(uint64_t ptr,
2842                   uint64_t context,
2843                   PACKey key,
2844                   PointerType type);
2845  uint64_t AddPAC(uint64_t ptr, uint64_t context, PACKey key, PointerType type);
2846  uint64_t StripPAC(uint64_t ptr, PointerType type);
2847  void PACHelper(int dst,
2848                 int src,
2849                 PACKey key,
2850                 decltype(&Simulator::AddPAC) pac_fn);
2851
2852  // Armv8.5 MTE helpers.
2853  uint64_t ChooseNonExcludedTag(uint64_t tag,
2854                                uint64_t offset,
2855                                uint64_t exclude = 0) {
2856    VIXL_ASSERT(IsUint4(tag) && IsUint4(offset) && IsUint16(exclude));
2857
2858    if (exclude == 0xffff) {
2859      return 0;
2860    }
2861
2862    if (offset == 0) {
2863      while ((exclude & (1 << tag)) != 0) {
2864        tag = (tag + 1) % 16;
2865      }
2866    }
2867
2868    while (offset > 0) {
2869      offset--;
2870      tag = (tag + 1) % 16;
2871      while ((exclude & (1 << tag)) != 0) {
2872        tag = (tag + 1) % 16;
2873      }
2874    }
2875    return tag;
2876  }
2877
2878  uint64_t GetAddressWithAllocationTag(uint64_t addr, uint64_t tag) {
2879    VIXL_ASSERT(IsUint4(tag));
2880    return (addr & ~(UINT64_C(0xf) << 56)) | (tag << 56);
2881  }
2882
2883  // Create or remove a mapping with memory protection. Memory attributes such
2884  // as MTE and BTI are represented by metadata in Simulator.
2885  void* Mmap(
2886      void* address, size_t length, int prot, int flags, int fd, off_t offset);
2887
2888  int Munmap(void* address, size_t length, int prot);
2889
2890  // The common CPUFeatures interface with the set of available features.
2891
2892  CPUFeatures* GetCPUFeatures() {
2893    return cpu_features_auditor_.GetCPUFeatures();
2894  }
2895
2896  void SetCPUFeatures(const CPUFeatures& cpu_features) {
2897    cpu_features_auditor_.SetCPUFeatures(cpu_features);
2898  }
2899
2900  // The set of features that the simulator has encountered.
2901  const CPUFeatures& GetSeenFeatures() {
2902    return cpu_features_auditor_.GetSeenFeatures();
2903  }
2904  void ResetSeenFeatures() { cpu_features_auditor_.ResetSeenFeatures(); }
2905
2906// Runtime call emulation support.
2907// It requires VIXL's ABI features, and C++11 or greater.
2908// Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
2909// in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
2910#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
2911    (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
2912
2913#define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
2914
2915// The implementation of the runtime call helpers require the functionality
2916// provided by `std::index_sequence`. It is only available from C++14, but
2917// we want runtime call simulation to work from C++11, so we emulate if
2918// necessary.
2919#if __cplusplus >= 201402L
2920  template <std::size_t... I>
2921  using local_index_sequence = std::index_sequence<I...>;
2922  template <typename... P>
2923  using __local_index_sequence_for = std::index_sequence_for<P...>;
2924#else
2925  // Emulate the behaviour of `std::index_sequence` and
2926  // `std::index_sequence_for`.
2927  // Naming follow the `std` names, prefixed with `emulated_`.
2928  template <size_t... I>
2929  struct emulated_index_sequence {};
2930
2931  // A recursive template to create a sequence of indexes.
2932  // The base case (for `N == 0`) is declared outside of the class scope, as
2933  // required by C++.
2934  template <std::size_t N, size_t... I>
2935  struct emulated_make_index_sequence_helper
2936      : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
2937
2938  template <std::size_t N>
2939  struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
2940  };
2941
2942  template <typename... P>
2943  struct emulated_index_sequence_for
2944      : emulated_make_index_sequence<sizeof...(P)> {};
2945
2946  template <std::size_t... I>
2947  using local_index_sequence = emulated_index_sequence<I...>;
2948  template <typename... P>
2949  using __local_index_sequence_for = emulated_index_sequence_for<P...>;
2950#endif
2951
2952  // Expand the argument tuple and perform the call.
2953  template <typename R, typename... P, std::size_t... I>
2954  R DoRuntimeCall(R (*function)(P...),
2955                  std::tuple<P...> arguments,
2956                  local_index_sequence<I...>) {
2957    USE(arguments);
2958    return function(std::get<I>(arguments)...);
2959  }
2960
2961  template <typename R, typename... P>
2962  void RuntimeCallNonVoid(R (*function)(P...)) {
2963    ABI abi;
2964    std::tuple<P...> argument_operands{
2965        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
2966    R return_value = DoRuntimeCall(function,
2967                                   argument_operands,
2968                                   __local_index_sequence_for<P...>{});
2969    WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
2970  }
2971
2972  template <typename R, typename... P>
2973  void RuntimeCallVoid(R (*function)(P...)) {
2974    ABI abi;
2975    std::tuple<P...> argument_operands{
2976        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
2977    DoRuntimeCall(function,
2978                  argument_operands,
2979                  __local_index_sequence_for<P...>{});
2980  }
2981
2982  // We use `struct` for `void` return type specialisation.
2983  template <typename R, typename... P>
2984  struct RuntimeCallStructHelper {
2985    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
2986      R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
2987      simulator->RuntimeCallNonVoid(function);
2988    }
2989  };
2990
2991  // Partial specialization when the return type is `void`.
2992  template <typename... P>
2993  struct RuntimeCallStructHelper<void, P...> {
2994    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
2995      void (*function)(P...) =
2996          reinterpret_cast<void (*)(P...)>(function_pointer);
2997      simulator->RuntimeCallVoid(function);
2998    }
2999  };
3000#endif
3001
3002  // Configure the simulated value of 'VL', which is the size of a Z register.
3003  // Because this cannot occur during a program's lifetime, this function also
3004  // resets the SVE registers.
3005  void SetVectorLengthInBits(unsigned vector_length);
3006
3007  unsigned GetVectorLengthInBits() const { return vector_length_; }
3008  unsigned GetVectorLengthInBytes() const {
3009    VIXL_ASSERT((vector_length_ % kBitsPerByte) == 0);
3010    return vector_length_ / kBitsPerByte;
3011  }
3012  unsigned GetPredicateLengthInBits() const {
3013    VIXL_ASSERT((GetVectorLengthInBits() % kZRegBitsPerPRegBit) == 0);
3014    return GetVectorLengthInBits() / kZRegBitsPerPRegBit;
3015  }
3016  unsigned GetPredicateLengthInBytes() const {
3017    VIXL_ASSERT((GetVectorLengthInBytes() % kZRegBitsPerPRegBit) == 0);
3018    return GetVectorLengthInBytes() / kZRegBitsPerPRegBit;
3019  }
3020
3021  unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) const {
3022    if (IsSVEFormat(vform)) {
3023      return GetVectorLengthInBits();
3024    } else {
3025      return vixl::aarch64::RegisterSizeInBitsFromFormat(vform);
3026    }
3027  }
3028
3029  unsigned RegisterSizeInBytesFromFormat(VectorFormat vform) const {
3030    unsigned size_in_bits = RegisterSizeInBitsFromFormat(vform);
3031    VIXL_ASSERT((size_in_bits % kBitsPerByte) == 0);
3032    return size_in_bits / kBitsPerByte;
3033  }
3034
3035  int LaneCountFromFormat(VectorFormat vform) const {
3036    if (IsSVEFormat(vform)) {
3037      return GetVectorLengthInBits() / LaneSizeInBitsFromFormat(vform);
3038    } else {
3039      return vixl::aarch64::LaneCountFromFormat(vform);
3040    }
3041  }
3042
3043  bool IsFirstActive(VectorFormat vform,
3044                     const LogicPRegister& mask,
3045                     const LogicPRegister& bits) {
3046    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3047      if (mask.IsActive(vform, i)) {
3048        return bits.IsActive(vform, i);
3049      }
3050    }
3051    return false;
3052  }
3053
3054  bool AreNoneActive(VectorFormat vform,
3055                     const LogicPRegister& mask,
3056                     const LogicPRegister& bits) {
3057    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3058      if (mask.IsActive(vform, i) && bits.IsActive(vform, i)) {
3059        return false;
3060      }
3061    }
3062    return true;
3063  }
3064
3065  bool IsLastActive(VectorFormat vform,
3066                    const LogicPRegister& mask,
3067                    const LogicPRegister& bits) {
3068    for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
3069      if (mask.IsActive(vform, i)) {
3070        return bits.IsActive(vform, i);
3071      }
3072    }
3073    return false;
3074  }
3075
3076  void PredTest(VectorFormat vform,
3077                const LogicPRegister& mask,
3078                const LogicPRegister& bits) {
3079    ReadNzcv().SetN(IsFirstActive(vform, mask, bits));
3080    ReadNzcv().SetZ(AreNoneActive(vform, mask, bits));
3081    ReadNzcv().SetC(!IsLastActive(vform, mask, bits));
3082    ReadNzcv().SetV(0);
3083    LogSystemRegister(NZCV);
3084  }
3085
3086  SimPRegister& GetPTrue() { return pregister_all_true_; }
3087
3088  template <typename T>
3089  size_t CleanGranuleTag(T address, size_t length = kMTETagGranuleInBytes) {
3090    size_t count = 0;
3091    for (size_t offset = 0; offset < length; offset += kMTETagGranuleInBytes) {
3092      count +=
3093          meta_data_.CleanMTETag(reinterpret_cast<uintptr_t>(address) + offset);
3094    }
3095    size_t expected =
3096        length / kMTETagGranuleInBytes + (length % kMTETagGranuleInBytes != 0);
3097
3098    // Give a warning when the memory region that is being unmapped isn't all
3099    // either MTE protected or not.
3100    if (count != expected) {
3101      std::stringstream sstream;
3102      sstream << std::hex
3103              << "MTE WARNING : the memory region being unmapped "
3104                 "starting at address 0x"
3105              << reinterpret_cast<uint64_t>(address)
3106              << "is not fully MTE protected.\n";
3107      VIXL_WARNING(sstream.str().c_str());
3108    }
3109    return count;
3110  }
3111
3112  template <typename T>
3113  void SetGranuleTag(T address,
3114                     int tag,
3115                     size_t length = kMTETagGranuleInBytes) {
3116    for (size_t offset = 0; offset < length; offset += kMTETagGranuleInBytes) {
3117      meta_data_.SetMTETag((uintptr_t)(address) + offset, tag);
3118    }
3119  }
3120
3121  template <typename T>
3122  int GetGranuleTag(T address) {
3123    return meta_data_.GetMTETag(address);
3124  }
3125
3126  // Generate a random address tag, and any tags specified in the input are
3127  // excluded from the selection.
3128  uint64_t GenerateRandomTag(uint16_t exclude = 0);
3129
3130  // Register a new BranchInterception object. If 'function' is branched to
3131  // (e.g: "bl function") in the future; instead, if provided, 'callback' will
3132  // be called otherwise a runtime call will be performed on 'function'.
3133  //
3134  // For example: this can be used to always perform runtime calls on
3135  // non-AArch64 functions without using the macroassembler.
3136  template <typename R, typename... P>
3137  void RegisterBranchInterception(R (*function)(P...),
3138                                  InterceptionCallback callback = nullptr) {
3139    meta_data_.RegisterBranchInterception(*function, callback);
3140  }
3141
3142  // Return the current output stream in use by the simulator.
3143  FILE* GetOutputStream() const { return stream_; }
3144
3145  bool IsDebuggerEnabled() const { return debugger_enabled_; }
3146
3147  void SetDebuggerEnabled(bool enabled) { debugger_enabled_ = enabled; }
3148
3149  Debugger* GetDebugger() const {
3150#ifndef PANDA_BUILD
3151    return debugger_.get();
3152#else
3153    return debugger_;
3154#endif
3155  }
3156
3157 protected:
3158  const char* clr_normal;
3159  const char* clr_flag_name;
3160  const char* clr_flag_value;
3161  const char* clr_reg_name;
3162  const char* clr_reg_value;
3163  const char* clr_vreg_name;
3164  const char* clr_vreg_value;
3165  const char* clr_preg_name;
3166  const char* clr_preg_value;
3167  const char* clr_memory_address;
3168  const char* clr_warning;
3169  const char* clr_warning_message;
3170  const char* clr_printf;
3171  const char* clr_branch_marker;
3172
3173  // Simulation helpers ------------------------------------
3174
3175  void ResetSystemRegisters();
3176  void ResetRegisters();
3177  void ResetVRegisters();
3178  void ResetPRegisters();
3179  void ResetFFR();
3180
3181  bool ConditionPassed(Condition cond) {
3182    switch (cond) {
3183      case eq:
3184        return ReadZ();
3185      case ne:
3186        return !ReadZ();
3187      case hs:
3188        return ReadC();
3189      case lo:
3190        return !ReadC();
3191      case mi:
3192        return ReadN();
3193      case pl:
3194        return !ReadN();
3195      case vs:
3196        return ReadV();
3197      case vc:
3198        return !ReadV();
3199      case hi:
3200        return ReadC() && !ReadZ();
3201      case ls:
3202        return !(ReadC() && !ReadZ());
3203      case ge:
3204        return ReadN() == ReadV();
3205      case lt:
3206        return ReadN() != ReadV();
3207      case gt:
3208        return !ReadZ() && (ReadN() == ReadV());
3209      case le:
3210        return !(!ReadZ() && (ReadN() == ReadV()));
3211      case nv:
3212        VIXL_FALLTHROUGH();
3213      case al:
3214        return true;
3215      default:
3216        VIXL_UNREACHABLE();
3217        return false;
3218    }
3219  }
3220
3221  bool ConditionPassed(Instr cond) {
3222    return ConditionPassed(static_cast<Condition>(cond));
3223  }
3224
3225  bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
3226
3227  void AddSubHelper(const Instruction* instr, int64_t op2);
3228  uint64_t AddWithCarry(unsigned reg_size,
3229                        bool set_flags,
3230                        uint64_t left,
3231                        uint64_t right,
3232                        int carry_in = 0);
3233  std::pair<uint64_t, uint8_t> AddWithCarry(unsigned reg_size,
3234                                            uint64_t left,
3235                                            uint64_t right,
3236                                            int carry_in);
3237  using vixl_uint128_t = std::pair<uint64_t, uint64_t>;
3238  vixl_uint128_t Add128(vixl_uint128_t x, vixl_uint128_t y);
3239  vixl_uint128_t Mul64(uint64_t x, uint64_t y);
3240  vixl_uint128_t Neg128(vixl_uint128_t x);
3241  void LogicalHelper(const Instruction* instr, int64_t op2);
3242  void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
3243  void LoadStoreHelper(const Instruction* instr,
3244                       int64_t offset,
3245                       AddrMode addrmode);
3246  void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
3247  template <typename T>
3248  void CompareAndSwapHelper(const Instruction* instr);
3249  template <typename T>
3250  void CompareAndSwapPairHelper(const Instruction* instr);
3251  template <typename T>
3252  void AtomicMemorySimpleHelper(const Instruction* instr);
3253  template <typename T>
3254  void AtomicMemorySwapHelper(const Instruction* instr);
3255  template <typename T>
3256  void LoadAcquireRCpcHelper(const Instruction* instr);
3257  template <typename T1, typename T2>
3258  void LoadAcquireRCpcUnscaledOffsetHelper(const Instruction* instr);
3259  template <typename T>
3260  void StoreReleaseUnscaledOffsetHelper(const Instruction* instr);
3261  uintptr_t AddressModeHelper(unsigned addr_reg,
3262                              int64_t offset,
3263                              AddrMode addrmode);
3264  void NEONLoadStoreMultiStructHelper(const Instruction* instr,
3265                                      AddrMode addr_mode);
3266  void NEONLoadStoreSingleStructHelper(const Instruction* instr,
3267                                       AddrMode addr_mode);
3268  template <uint32_t mops_type>
3269  void MOPSPHelper(const Instruction* instr) {
3270    VIXL_ASSERT(instr->IsConsistentMOPSTriplet<mops_type>());
3271
3272    int d = instr->GetRd();
3273    int n = instr->GetRn();
3274    int s = instr->GetRs();
3275
3276    // Aliased registers and xzr are disallowed for Xd and Xn.
3277    if ((d == n) || (d == s) || (n == s) || (d == 31) || (n == 31)) {
3278      VisitUnallocated(instr);
3279    }
3280
3281    // Additionally, Xs may not be xzr for cpy.
3282    if ((mops_type == "cpy"_h) && (s == 31)) {
3283      VisitUnallocated(instr);
3284    }
3285
3286    // Bits 31 and 30 must be zero.
3287    if (instr->ExtractBits(31, 30) != 0) {
3288      VisitUnallocated(instr);
3289    }
3290
3291    // Saturate copy count.
3292    uint64_t xn = ReadXRegister(n);
3293    int saturation_bits = (mops_type == "cpy"_h) ? 55 : 63;
3294    if ((xn >> saturation_bits) != 0) {
3295      xn = (UINT64_C(1) << saturation_bits) - 1;
3296      if (mops_type == "setg"_h) {
3297        // Align saturated value to granule.
3298        xn &= ~UINT64_C(kMTETagGranuleInBytes - 1);
3299      }
3300      WriteXRegister(n, xn);
3301    }
3302
3303    ReadNzcv().SetN(0);
3304    ReadNzcv().SetZ(0);
3305    ReadNzcv().SetC(1);  // Indicates "option B" implementation.
3306    ReadNzcv().SetV(0);
3307  }
3308
3309  int64_t ShiftOperand(unsigned reg_size,
3310                       uint64_t value,
3311                       Shift shift_type,
3312                       unsigned amount) const;
3313  int64_t ExtendValue(unsigned reg_width,
3314                      int64_t value,
3315                      Extend extend_type,
3316                      unsigned left_shift = 0) const;
3317  uint64_t PolynomialMult(uint64_t op1,
3318                          uint64_t op2,
3319                          int lane_size_in_bits) const;
3320
3321  void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
3322  void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
3323  void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
3324  void ld1r(VectorFormat vform,
3325            VectorFormat unpack_vform,
3326            LogicVRegister dst,
3327            uint64_t addr,
3328            bool is_signed = false);
3329  void ld2(VectorFormat vform,
3330           LogicVRegister dst1,
3331           LogicVRegister dst2,
3332           uint64_t addr);
3333  void ld2(VectorFormat vform,
3334           LogicVRegister dst1,
3335           LogicVRegister dst2,
3336           int index,
3337           uint64_t addr);
3338  void ld2r(VectorFormat vform,
3339            LogicVRegister dst1,
3340            LogicVRegister dst2,
3341            uint64_t addr);
3342  void ld3(VectorFormat vform,
3343           LogicVRegister dst1,
3344           LogicVRegister dst2,
3345           LogicVRegister dst3,
3346           uint64_t addr);
3347  void ld3(VectorFormat vform,
3348           LogicVRegister dst1,
3349           LogicVRegister dst2,
3350           LogicVRegister dst3,
3351           int index,
3352           uint64_t addr);
3353  void ld3r(VectorFormat vform,
3354            LogicVRegister dst1,
3355            LogicVRegister dst2,
3356            LogicVRegister dst3,
3357            uint64_t addr);
3358  void ld4(VectorFormat vform,
3359           LogicVRegister dst1,
3360           LogicVRegister dst2,
3361           LogicVRegister dst3,
3362           LogicVRegister dst4,
3363           uint64_t addr);
3364  void ld4(VectorFormat vform,
3365           LogicVRegister dst1,
3366           LogicVRegister dst2,
3367           LogicVRegister dst3,
3368           LogicVRegister dst4,
3369           int index,
3370           uint64_t addr);
3371  void ld4r(VectorFormat vform,
3372            LogicVRegister dst1,
3373            LogicVRegister dst2,
3374            LogicVRegister dst3,
3375            LogicVRegister dst4,
3376            uint64_t addr);
3377  void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
3378  void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
3379  void st2(VectorFormat vform,
3380           LogicVRegister src,
3381           LogicVRegister src2,
3382           uint64_t addr);
3383  void st2(VectorFormat vform,
3384           LogicVRegister src,
3385           LogicVRegister src2,
3386           int index,
3387           uint64_t addr);
3388  void st3(VectorFormat vform,
3389           LogicVRegister src,
3390           LogicVRegister src2,
3391           LogicVRegister src3,
3392           uint64_t addr);
3393  void st3(VectorFormat vform,
3394           LogicVRegister src,
3395           LogicVRegister src2,
3396           LogicVRegister src3,
3397           int index,
3398           uint64_t addr);
3399  void st4(VectorFormat vform,
3400           LogicVRegister src,
3401           LogicVRegister src2,
3402           LogicVRegister src3,
3403           LogicVRegister src4,
3404           uint64_t addr);
3405  void st4(VectorFormat vform,
3406           LogicVRegister src,
3407           LogicVRegister src2,
3408           LogicVRegister src3,
3409           LogicVRegister src4,
3410           int index,
3411           uint64_t addr);
3412  LogicVRegister cmp(VectorFormat vform,
3413                     LogicVRegister dst,
3414                     const LogicVRegister& src1,
3415                     const LogicVRegister& src2,
3416                     Condition cond);
3417  LogicVRegister cmp(VectorFormat vform,
3418                     LogicVRegister dst,
3419                     const LogicVRegister& src1,
3420                     int imm,
3421                     Condition cond);
3422  LogicVRegister cmptst(VectorFormat vform,
3423                        LogicVRegister dst,
3424                        const LogicVRegister& src1,
3425                        const LogicVRegister& src2);
3426  LogicVRegister add(VectorFormat vform,
3427                     LogicVRegister dst,
3428                     const LogicVRegister& src1,
3429                     const LogicVRegister& src2);
3430  // Add `value` to each lane of `src1`, treating `value` as unsigned for the
3431  // purposes of setting the saturation flags.
3432  LogicVRegister add_uint(VectorFormat vform,
3433                          LogicVRegister dst,
3434                          const LogicVRegister& src1,
3435                          uint64_t value);
3436  LogicVRegister addp(VectorFormat vform,
3437                      LogicVRegister dst,
3438                      const LogicVRegister& src1,
3439                      const LogicVRegister& src2);
3440  LogicPRegister brka(LogicPRegister pd,
3441                      const LogicPRegister& pg,
3442                      const LogicPRegister& pn);
3443  LogicPRegister brkb(LogicPRegister pd,
3444                      const LogicPRegister& pg,
3445                      const LogicPRegister& pn);
3446  LogicPRegister brkn(LogicPRegister pdm,
3447                      const LogicPRegister& pg,
3448                      const LogicPRegister& pn);
3449  LogicPRegister brkpa(LogicPRegister pd,
3450                       const LogicPRegister& pg,
3451                       const LogicPRegister& pn,
3452                       const LogicPRegister& pm);
3453  LogicPRegister brkpb(LogicPRegister pd,
3454                       const LogicPRegister& pg,
3455                       const LogicPRegister& pn,
3456                       const LogicPRegister& pm);
3457  // dst = srca + src1 * src2
3458  LogicVRegister mla(VectorFormat vform,
3459                     LogicVRegister dst,
3460                     const LogicVRegister& srca,
3461                     const LogicVRegister& src1,
3462                     const LogicVRegister& src2);
3463  // dst = srca - src1 * src2
3464  LogicVRegister mls(VectorFormat vform,
3465                     LogicVRegister dst,
3466                     const LogicVRegister& srca,
3467                     const LogicVRegister& src1,
3468                     const LogicVRegister& src2);
3469  LogicVRegister mul(VectorFormat vform,
3470                     LogicVRegister dst,
3471                     const LogicVRegister& src1,
3472                     const LogicVRegister& src2);
3473  LogicVRegister mul(VectorFormat vform,
3474                     LogicVRegister dst,
3475                     const LogicVRegister& src1,
3476                     const LogicVRegister& src2,
3477                     int index);
3478  LogicVRegister mla(VectorFormat vform,
3479                     LogicVRegister dst,
3480                     const LogicVRegister& src1,
3481                     const LogicVRegister& src2,
3482                     int index);
3483  LogicVRegister mls(VectorFormat vform,
3484                     LogicVRegister dst,
3485                     const LogicVRegister& src1,
3486                     const LogicVRegister& src2,
3487                     int index);
3488  LogicVRegister pmul(VectorFormat vform,
3489                      LogicVRegister dst,
3490                      const LogicVRegister& src1,
3491                      const LogicVRegister& src2);
3492  LogicVRegister sdiv(VectorFormat vform,
3493                      LogicVRegister dst,
3494                      const LogicVRegister& src1,
3495                      const LogicVRegister& src2);
3496  LogicVRegister udiv(VectorFormat vform,
3497                      LogicVRegister dst,
3498                      const LogicVRegister& src1,
3499                      const LogicVRegister& src2);
3500
3501  typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
3502                                                   LogicVRegister dst,
3503                                                   const LogicVRegister& src1,
3504                                                   const LogicVRegister& src2,
3505                                                   int index);
3506  LogicVRegister fmul(VectorFormat vform,
3507                      LogicVRegister dst,
3508                      const LogicVRegister& src1,
3509                      const LogicVRegister& src2,
3510                      int index);
3511  LogicVRegister fmla(VectorFormat vform,
3512                      LogicVRegister dst,
3513                      const LogicVRegister& src1,
3514                      const LogicVRegister& src2,
3515                      int index);
3516  LogicVRegister fmlal(VectorFormat vform,
3517                       LogicVRegister dst,
3518                       const LogicVRegister& src1,
3519                       const LogicVRegister& src2,
3520                       int index);
3521  LogicVRegister fmlal2(VectorFormat vform,
3522                        LogicVRegister dst,
3523                        const LogicVRegister& src1,
3524                        const LogicVRegister& src2,
3525                        int index);
3526  LogicVRegister fmls(VectorFormat vform,
3527                      LogicVRegister dst,
3528                      const LogicVRegister& src1,
3529                      const LogicVRegister& src2,
3530                      int index);
3531  LogicVRegister fmlsl(VectorFormat vform,
3532                       LogicVRegister dst,
3533                       const LogicVRegister& src1,
3534                       const LogicVRegister& src2,
3535                       int index);
3536  LogicVRegister fmlsl2(VectorFormat vform,
3537                        LogicVRegister dst,
3538                        const LogicVRegister& src1,
3539                        const LogicVRegister& src2,
3540                        int index);
3541  LogicVRegister fmulx(VectorFormat vform,
3542                       LogicVRegister dst,
3543                       const LogicVRegister& src1,
3544                       const LogicVRegister& src2,
3545                       int index);
3546  LogicVRegister smulh(VectorFormat vform,
3547                       LogicVRegister dst,
3548                       const LogicVRegister& src1,
3549                       const LogicVRegister& src2);
3550  LogicVRegister umulh(VectorFormat vform,
3551                       LogicVRegister dst,
3552                       const LogicVRegister& src1,
3553                       const LogicVRegister& src2);
3554  LogicVRegister sqdmull(VectorFormat vform,
3555                         LogicVRegister dst,
3556                         const LogicVRegister& src1,
3557                         const LogicVRegister& src2,
3558                         int index);
3559  LogicVRegister sqdmlal(VectorFormat vform,
3560                         LogicVRegister dst,
3561                         const LogicVRegister& src1,
3562                         const LogicVRegister& src2,
3563                         int index);
3564  LogicVRegister sqdmlsl(VectorFormat vform,
3565                         LogicVRegister dst,
3566                         const LogicVRegister& src1,
3567                         const LogicVRegister& src2,
3568                         int index);
3569  LogicVRegister sqdmulh(VectorFormat vform,
3570                         LogicVRegister dst,
3571                         const LogicVRegister& src1,
3572                         const LogicVRegister& src2,
3573                         int index);
3574  LogicVRegister sqrdmulh(VectorFormat vform,
3575                          LogicVRegister dst,
3576                          const LogicVRegister& src1,
3577                          const LogicVRegister& src2,
3578                          int index);
3579  LogicVRegister sqrdmlah(VectorFormat vform,
3580                          LogicVRegister dst,
3581                          const LogicVRegister& src1,
3582                          const LogicVRegister& src2,
3583                          int index);
3584  LogicVRegister sqrdmlsh(VectorFormat vform,
3585                          LogicVRegister dst,
3586                          const LogicVRegister& src1,
3587                          const LogicVRegister& src2,
3588                          int index);
3589  LogicVRegister sub(VectorFormat vform,
3590                     LogicVRegister dst,
3591                     const LogicVRegister& src1,
3592                     const LogicVRegister& src2);
3593  // Subtract `value` from each lane of `src1`, treating `value` as unsigned for
3594  // the purposes of setting the saturation flags.
3595  LogicVRegister sub_uint(VectorFormat vform,
3596                          LogicVRegister dst,
3597                          const LogicVRegister& src1,
3598                          uint64_t value);
3599  LogicVRegister and_(VectorFormat vform,
3600                      LogicVRegister dst,
3601                      const LogicVRegister& src1,
3602                      const LogicVRegister& src2);
3603  LogicVRegister orr(VectorFormat vform,
3604                     LogicVRegister dst,
3605                     const LogicVRegister& src1,
3606                     const LogicVRegister& src2);
3607  LogicVRegister orn(VectorFormat vform,
3608                     LogicVRegister dst,
3609                     const LogicVRegister& src1,
3610                     const LogicVRegister& src2);
3611  LogicVRegister eor(VectorFormat vform,
3612                     LogicVRegister dst,
3613                     const LogicVRegister& src1,
3614                     const LogicVRegister& src2);
3615  LogicVRegister bic(VectorFormat vform,
3616                     LogicVRegister dst,
3617                     const LogicVRegister& src1,
3618                     const LogicVRegister& src2);
3619  LogicVRegister bic(VectorFormat vform,
3620                     LogicVRegister dst,
3621                     const LogicVRegister& src,
3622                     uint64_t imm);
3623  LogicVRegister bif(VectorFormat vform,
3624                     LogicVRegister dst,
3625                     const LogicVRegister& src1,
3626                     const LogicVRegister& src2);
3627  LogicVRegister bit(VectorFormat vform,
3628                     LogicVRegister dst,
3629                     const LogicVRegister& src1,
3630                     const LogicVRegister& src2);
3631  LogicVRegister bsl(VectorFormat vform,
3632                     LogicVRegister dst,
3633                     const LogicVRegister& src_mask,
3634                     const LogicVRegister& src1,
3635                     const LogicVRegister& src2);
3636  LogicVRegister cls(VectorFormat vform,
3637                     LogicVRegister dst,
3638                     const LogicVRegister& src);
3639  LogicVRegister clz(VectorFormat vform,
3640                     LogicVRegister dst,
3641                     const LogicVRegister& src);
3642  LogicVRegister cnot(VectorFormat vform,
3643                      LogicVRegister dst,
3644                      const LogicVRegister& src);
3645  LogicVRegister cnt(VectorFormat vform,
3646                     LogicVRegister dst,
3647                     const LogicVRegister& src);
3648  LogicVRegister not_(VectorFormat vform,
3649                      LogicVRegister dst,
3650                      const LogicVRegister& src);
3651  LogicVRegister rbit(VectorFormat vform,
3652                      LogicVRegister dst,
3653                      const LogicVRegister& src);
3654  LogicVRegister rev(VectorFormat vform,
3655                     LogicVRegister dst,
3656                     const LogicVRegister& src);
3657  LogicVRegister rev_byte(VectorFormat vform,
3658                          LogicVRegister dst,
3659                          const LogicVRegister& src,
3660                          int rev_size);
3661  LogicVRegister rev16(VectorFormat vform,
3662                       LogicVRegister dst,
3663                       const LogicVRegister& src);
3664  LogicVRegister rev32(VectorFormat vform,
3665                       LogicVRegister dst,
3666                       const LogicVRegister& src);
3667  LogicVRegister rev64(VectorFormat vform,
3668                       LogicVRegister dst,
3669                       const LogicVRegister& src);
3670  LogicVRegister addlp(VectorFormat vform,
3671                       LogicVRegister dst,
3672                       const LogicVRegister& src,
3673                       bool is_signed,
3674                       bool do_accumulate);
3675  LogicVRegister saddlp(VectorFormat vform,
3676                        LogicVRegister dst,
3677                        const LogicVRegister& src);
3678  LogicVRegister uaddlp(VectorFormat vform,
3679                        LogicVRegister dst,
3680                        const LogicVRegister& src);
3681  LogicVRegister sadalp(VectorFormat vform,
3682                        LogicVRegister dst,
3683                        const LogicVRegister& src);
3684  LogicVRegister uadalp(VectorFormat vform,
3685                        LogicVRegister dst,
3686                        const LogicVRegister& src);
3687  LogicVRegister ror(VectorFormat vform,
3688                     LogicVRegister dst,
3689                     const LogicVRegister& src,
3690                     int rotation);
3691  LogicVRegister ext(VectorFormat vform,
3692                     LogicVRegister dst,
3693                     const LogicVRegister& src1,
3694                     const LogicVRegister& src2,
3695                     int index);
3696  LogicVRegister rotate_elements_right(VectorFormat vform,
3697                                       LogicVRegister dst,
3698                                       const LogicVRegister& src,
3699                                       int index);
3700  template <typename T>
3701  LogicVRegister fcadd(VectorFormat vform,
3702                       LogicVRegister dst,
3703                       const LogicVRegister& src1,
3704                       const LogicVRegister& src2,
3705                       int rot);
3706  LogicVRegister fcadd(VectorFormat vform,
3707                       LogicVRegister dst,
3708                       const LogicVRegister& src1,
3709                       const LogicVRegister& src2,
3710                       int rot);
3711  template <typename T>
3712  LogicVRegister fcmla(VectorFormat vform,
3713                       LogicVRegister dst,
3714                       const LogicVRegister& src1,
3715                       const LogicVRegister& src2,
3716                       const LogicVRegister& acc,
3717                       int index,
3718                       int rot);
3719  LogicVRegister fcmla(VectorFormat vform,
3720                       LogicVRegister dst,
3721                       const LogicVRegister& src1,
3722                       const LogicVRegister& src2,
3723                       int index,
3724                       int rot);
3725  LogicVRegister fcmla(VectorFormat vform,
3726                       LogicVRegister dst,
3727                       const LogicVRegister& src1,
3728                       const LogicVRegister& src2,
3729                       const LogicVRegister& acc,
3730                       int rot);
3731  template <typename T>
3732  LogicVRegister fadda(VectorFormat vform,
3733                       LogicVRegister acc,
3734                       const LogicPRegister& pg,
3735                       const LogicVRegister& src);
3736  LogicVRegister fadda(VectorFormat vform,
3737                       LogicVRegister acc,
3738                       const LogicPRegister& pg,
3739                       const LogicVRegister& src);
3740  LogicVRegister cadd(VectorFormat vform,
3741                      LogicVRegister dst,
3742                      const LogicVRegister& src1,
3743                      const LogicVRegister& src2,
3744                      int rot,
3745                      bool saturate = false);
3746  LogicVRegister cmla(VectorFormat vform,
3747                      LogicVRegister dst,
3748                      const LogicVRegister& srca,
3749                      const LogicVRegister& src1,
3750                      const LogicVRegister& src2,
3751                      int rot);
3752  LogicVRegister cmla(VectorFormat vform,
3753                      LogicVRegister dst,
3754                      const LogicVRegister& srca,
3755                      const LogicVRegister& src1,
3756                      const LogicVRegister& src2,
3757                      int index,
3758                      int rot);
3759  LogicVRegister bgrp(VectorFormat vform,
3760                      LogicVRegister dst,
3761                      const LogicVRegister& src1,
3762                      const LogicVRegister& src2,
3763                      bool do_bext = false);
3764  LogicVRegister bdep(VectorFormat vform,
3765                      LogicVRegister dst,
3766                      const LogicVRegister& src1,
3767                      const LogicVRegister& src2);
3768  LogicVRegister histogram(VectorFormat vform,
3769                           LogicVRegister dst,
3770                           const LogicPRegister& pg,
3771                           const LogicVRegister& src1,
3772                           const LogicVRegister& src2,
3773                           bool do_segmented = false);
3774  LogicVRegister index(VectorFormat vform,
3775                       LogicVRegister dst,
3776                       uint64_t start,
3777                       uint64_t step);
3778  LogicVRegister ins_element(VectorFormat vform,
3779                             LogicVRegister dst,
3780                             int dst_index,
3781                             const LogicVRegister& src,
3782                             int src_index);
3783  LogicVRegister ins_immediate(VectorFormat vform,
3784                               LogicVRegister dst,
3785                               int dst_index,
3786                               uint64_t imm);
3787  LogicVRegister insr(VectorFormat vform, LogicVRegister dst, uint64_t imm);
3788  LogicVRegister dup_element(VectorFormat vform,
3789                             LogicVRegister dst,
3790                             const LogicVRegister& src,
3791                             int src_index);
3792  LogicVRegister dup_elements_to_segments(VectorFormat vform,
3793                                          LogicVRegister dst,
3794                                          const LogicVRegister& src,
3795                                          int src_index);
3796  LogicVRegister dup_elements_to_segments(
3797      VectorFormat vform,
3798      LogicVRegister dst,
3799      const std::pair<int, int>& src_and_index);
3800  LogicVRegister dup_immediate(VectorFormat vform,
3801                               LogicVRegister dst,
3802                               uint64_t imm);
3803  LogicVRegister mov(VectorFormat vform,
3804                     LogicVRegister dst,
3805                     const LogicVRegister& src);
3806  LogicPRegister mov(LogicPRegister dst, const LogicPRegister& src);
3807  LogicVRegister mov_merging(VectorFormat vform,
3808                             LogicVRegister dst,
3809                             const SimPRegister& pg,
3810                             const LogicVRegister& src);
3811  LogicVRegister mov_zeroing(VectorFormat vform,
3812                             LogicVRegister dst,
3813                             const SimPRegister& pg,
3814                             const LogicVRegister& src);
3815  LogicVRegister mov_alternating(VectorFormat vform,
3816                                 LogicVRegister dst,
3817                                 const LogicVRegister& src,
3818                                 int start_at);
3819  LogicPRegister mov_merging(LogicPRegister dst,
3820                             const LogicPRegister& pg,
3821                             const LogicPRegister& src);
3822  LogicPRegister mov_zeroing(LogicPRegister dst,
3823                             const LogicPRegister& pg,
3824                             const LogicPRegister& src);
3825  LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
3826  LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
3827  LogicVRegister orr(VectorFormat vform,
3828                     LogicVRegister dst,
3829                     const LogicVRegister& src,
3830                     uint64_t imm);
3831  LogicVRegister sshl(VectorFormat vform,
3832                      LogicVRegister dst,
3833                      const LogicVRegister& src1,
3834                      const LogicVRegister& src2,
3835                      bool shift_is_8bit = true);
3836  LogicVRegister ushl(VectorFormat vform,
3837                      LogicVRegister dst,
3838                      const LogicVRegister& src1,
3839                      const LogicVRegister& src2,
3840                      bool shift_is_8bit = true);
3841  LogicVRegister sshr(VectorFormat vform,
3842                      LogicVRegister dst,
3843                      const LogicVRegister& src1,
3844                      const LogicVRegister& src2);
3845  LogicVRegister ushr(VectorFormat vform,
3846                      LogicVRegister dst,
3847                      const LogicVRegister& src1,
3848                      const LogicVRegister& src2);
3849  // Perform a "conditional last" operation. The first part of the pair is true
3850  // if any predicate lane is active, false otherwise. The second part takes the
3851  // value of the last active (plus offset) lane, or last (plus offset) lane if
3852  // none active.
3853  std::pair<bool, uint64_t> clast(VectorFormat vform,
3854                                  const LogicPRegister& pg,
3855                                  const LogicVRegister& src2,
3856                                  int offset_from_last_active);
3857  LogicPRegister match(VectorFormat vform,
3858                       LogicPRegister dst,
3859                       const LogicVRegister& haystack,
3860                       const LogicVRegister& needles,
3861                       bool negate_match);
3862  LogicVRegister compact(VectorFormat vform,
3863                         LogicVRegister dst,
3864                         const LogicPRegister& pg,
3865                         const LogicVRegister& src);
3866  LogicVRegister splice(VectorFormat vform,
3867                        LogicVRegister dst,
3868                        const LogicPRegister& pg,
3869                        const LogicVRegister& src1,
3870                        const LogicVRegister& src2);
3871  LogicVRegister sel(VectorFormat vform,
3872                     LogicVRegister dst,
3873                     const SimPRegister& pg,
3874                     const LogicVRegister& src1,
3875                     const LogicVRegister& src2);
3876  LogicPRegister sel(LogicPRegister dst,
3877                     const LogicPRegister& pg,
3878                     const LogicPRegister& src1,
3879                     const LogicPRegister& src2);
3880  LogicVRegister sminmax(VectorFormat vform,
3881                         LogicVRegister dst,
3882                         const LogicVRegister& src1,
3883                         const LogicVRegister& src2,
3884                         bool max);
3885  LogicVRegister smax(VectorFormat vform,
3886                      LogicVRegister dst,
3887                      const LogicVRegister& src1,
3888                      const LogicVRegister& src2);
3889  LogicVRegister smin(VectorFormat vform,
3890                      LogicVRegister dst,
3891                      const LogicVRegister& src1,
3892                      const LogicVRegister& src2);
3893  LogicVRegister sminmaxp(VectorFormat vform,
3894                          LogicVRegister dst,
3895                          const LogicVRegister& src1,
3896                          const LogicVRegister& src2,
3897                          bool max);
3898  LogicVRegister smaxp(VectorFormat vform,
3899                       LogicVRegister dst,
3900                       const LogicVRegister& src1,
3901                       const LogicVRegister& src2);
3902  LogicVRegister sminp(VectorFormat vform,
3903                       LogicVRegister dst,
3904                       const LogicVRegister& src1,
3905                       const LogicVRegister& src2);
3906  LogicVRegister addp(VectorFormat vform,
3907                      LogicVRegister dst,
3908                      const LogicVRegister& src);
3909  LogicVRegister addv(VectorFormat vform,
3910                      LogicVRegister dst,
3911                      const LogicVRegister& src);
3912  LogicVRegister uaddlv(VectorFormat vform,
3913                        LogicVRegister dst,
3914                        const LogicVRegister& src);
3915  LogicVRegister saddlv(VectorFormat vform,
3916                        LogicVRegister dst,
3917                        const LogicVRegister& src);
3918  LogicVRegister sminmaxv(VectorFormat vform,
3919                          LogicVRegister dst,
3920                          const LogicPRegister& pg,
3921                          const LogicVRegister& src,
3922                          bool max);
3923  LogicVRegister smaxv(VectorFormat vform,
3924                       LogicVRegister dst,
3925                       const LogicVRegister& src);
3926  LogicVRegister sminv(VectorFormat vform,
3927                       LogicVRegister dst,
3928                       const LogicVRegister& src);
3929  LogicVRegister uxtl(VectorFormat vform,
3930                      LogicVRegister dst,
3931                      const LogicVRegister& src,
3932                      bool is_2 = false);
3933  LogicVRegister uxtl2(VectorFormat vform,
3934                       LogicVRegister dst,
3935                       const LogicVRegister& src);
3936  LogicVRegister sxtl(VectorFormat vform,
3937                      LogicVRegister dst,
3938                      const LogicVRegister& src,
3939                      bool is_2 = false);
3940  LogicVRegister sxtl2(VectorFormat vform,
3941                       LogicVRegister dst,
3942                       const LogicVRegister& src);
3943  LogicVRegister uxt(VectorFormat vform,
3944                     LogicVRegister dst,
3945                     const LogicVRegister& src,
3946                     unsigned from_size_in_bits);
3947  LogicVRegister sxt(VectorFormat vform,
3948                     LogicVRegister dst,
3949                     const LogicVRegister& src,
3950                     unsigned from_size_in_bits);
3951  LogicVRegister tbl(VectorFormat vform,
3952                     LogicVRegister dst,
3953                     const LogicVRegister& tab,
3954                     const LogicVRegister& ind);
3955  LogicVRegister tbl(VectorFormat vform,
3956                     LogicVRegister dst,
3957                     const LogicVRegister& tab,
3958                     const LogicVRegister& tab2,
3959                     const LogicVRegister& ind);
3960  LogicVRegister tbl(VectorFormat vform,
3961                     LogicVRegister dst,
3962                     const LogicVRegister& tab,
3963                     const LogicVRegister& tab2,
3964                     const LogicVRegister& tab3,
3965                     const LogicVRegister& ind);
3966  LogicVRegister tbl(VectorFormat vform,
3967                     LogicVRegister dst,
3968                     const LogicVRegister& tab,
3969                     const LogicVRegister& tab2,
3970                     const LogicVRegister& tab3,
3971                     const LogicVRegister& tab4,
3972                     const LogicVRegister& ind);
3973  LogicVRegister Table(VectorFormat vform,
3974                       LogicVRegister dst,
3975                       const LogicVRegister& ind,
3976                       bool zero_out_of_bounds,
3977                       const LogicVRegister* tab1,
3978                       const LogicVRegister* tab2 = NULL,
3979                       const LogicVRegister* tab3 = NULL,
3980                       const LogicVRegister* tab4 = NULL);
3981  LogicVRegister tbx(VectorFormat vform,
3982                     LogicVRegister dst,
3983                     const LogicVRegister& tab,
3984                     const LogicVRegister& ind);
3985  LogicVRegister tbx(VectorFormat vform,
3986                     LogicVRegister dst,
3987                     const LogicVRegister& tab,
3988                     const LogicVRegister& tab2,
3989                     const LogicVRegister& ind);
3990  LogicVRegister tbx(VectorFormat vform,
3991                     LogicVRegister dst,
3992                     const LogicVRegister& tab,
3993                     const LogicVRegister& tab2,
3994                     const LogicVRegister& tab3,
3995                     const LogicVRegister& ind);
3996  LogicVRegister tbx(VectorFormat vform,
3997                     LogicVRegister dst,
3998                     const LogicVRegister& tab,
3999                     const LogicVRegister& tab2,
4000                     const LogicVRegister& tab3,
4001                     const LogicVRegister& tab4,
4002                     const LogicVRegister& ind);
4003  LogicVRegister uaddl(VectorFormat vform,
4004                       LogicVRegister dst,
4005                       const LogicVRegister& src1,
4006                       const LogicVRegister& src2);
4007  LogicVRegister uaddl2(VectorFormat vform,
4008                        LogicVRegister dst,
4009                        const LogicVRegister& src1,
4010                        const LogicVRegister& src2);
4011  LogicVRegister uaddw(VectorFormat vform,
4012                       LogicVRegister dst,
4013                       const LogicVRegister& src1,
4014                       const LogicVRegister& src2);
4015  LogicVRegister uaddw2(VectorFormat vform,
4016                        LogicVRegister dst,
4017                        const LogicVRegister& src1,
4018                        const LogicVRegister& src2);
4019  LogicVRegister saddl(VectorFormat vform,
4020                       LogicVRegister dst,
4021                       const LogicVRegister& src1,
4022                       const LogicVRegister& src2);
4023  LogicVRegister saddl2(VectorFormat vform,
4024                        LogicVRegister dst,
4025                        const LogicVRegister& src1,
4026                        const LogicVRegister& src2);
4027  LogicVRegister saddw(VectorFormat vform,
4028                       LogicVRegister dst,
4029                       const LogicVRegister& src1,
4030                       const LogicVRegister& src2);
4031  LogicVRegister saddw2(VectorFormat vform,
4032                        LogicVRegister dst,
4033                        const LogicVRegister& src1,
4034                        const LogicVRegister& src2);
4035  LogicVRegister usubl(VectorFormat vform,
4036                       LogicVRegister dst,
4037                       const LogicVRegister& src1,
4038                       const LogicVRegister& src2);
4039  LogicVRegister usubl2(VectorFormat vform,
4040                        LogicVRegister dst,
4041                        const LogicVRegister& src1,
4042                        const LogicVRegister& src2);
4043  LogicVRegister usubw(VectorFormat vform,
4044                       LogicVRegister dst,
4045                       const LogicVRegister& src1,
4046                       const LogicVRegister& src2);
4047  LogicVRegister usubw2(VectorFormat vform,
4048                        LogicVRegister dst,
4049                        const LogicVRegister& src1,
4050                        const LogicVRegister& src2);
4051  LogicVRegister ssubl(VectorFormat vform,
4052                       LogicVRegister dst,
4053                       const LogicVRegister& src1,
4054                       const LogicVRegister& src2);
4055  LogicVRegister ssubl2(VectorFormat vform,
4056                        LogicVRegister dst,
4057                        const LogicVRegister& src1,
4058                        const LogicVRegister& src2);
4059  LogicVRegister ssubw(VectorFormat vform,
4060                       LogicVRegister dst,
4061                       const LogicVRegister& src1,
4062                       const LogicVRegister& src2);
4063  LogicVRegister ssubw2(VectorFormat vform,
4064                        LogicVRegister dst,
4065                        const LogicVRegister& src1,
4066                        const LogicVRegister& src2);
4067  LogicVRegister uminmax(VectorFormat vform,
4068                         LogicVRegister dst,
4069                         const LogicVRegister& src1,
4070                         const LogicVRegister& src2,
4071                         bool max);
4072  LogicVRegister umax(VectorFormat vform,
4073                      LogicVRegister dst,
4074                      const LogicVRegister& src1,
4075                      const LogicVRegister& src2);
4076  LogicVRegister umin(VectorFormat vform,
4077                      LogicVRegister dst,
4078                      const LogicVRegister& src1,
4079                      const LogicVRegister& src2);
4080  LogicVRegister uminmaxp(VectorFormat vform,
4081                          LogicVRegister dst,
4082                          const LogicVRegister& src1,
4083                          const LogicVRegister& src2,
4084                          bool max);
4085  LogicVRegister umaxp(VectorFormat vform,
4086                       LogicVRegister dst,
4087                       const LogicVRegister& src1,
4088                       const LogicVRegister& src2);
4089  LogicVRegister uminp(VectorFormat vform,
4090                       LogicVRegister dst,
4091                       const LogicVRegister& src1,
4092                       const LogicVRegister& src2);
4093  LogicVRegister uminmaxv(VectorFormat vform,
4094                          LogicVRegister dst,
4095                          const LogicPRegister& pg,
4096                          const LogicVRegister& src,
4097                          bool max);
4098  LogicVRegister umaxv(VectorFormat vform,
4099                       LogicVRegister dst,
4100                       const LogicVRegister& src);
4101  LogicVRegister uminv(VectorFormat vform,
4102                       LogicVRegister dst,
4103                       const LogicVRegister& src);
4104  LogicVRegister trn1(VectorFormat vform,
4105                      LogicVRegister dst,
4106                      const LogicVRegister& src1,
4107                      const LogicVRegister& src2);
4108  LogicVRegister trn2(VectorFormat vform,
4109                      LogicVRegister dst,
4110                      const LogicVRegister& src1,
4111                      const LogicVRegister& src2);
4112  LogicVRegister zip1(VectorFormat vform,
4113                      LogicVRegister dst,
4114                      const LogicVRegister& src1,
4115                      const LogicVRegister& src2);
4116  LogicVRegister zip2(VectorFormat vform,
4117                      LogicVRegister dst,
4118                      const LogicVRegister& src1,
4119                      const LogicVRegister& src2);
4120  LogicVRegister uzp1(VectorFormat vform,
4121                      LogicVRegister dst,
4122                      const LogicVRegister& src1,
4123                      const LogicVRegister& src2);
4124  LogicVRegister uzp2(VectorFormat vform,
4125                      LogicVRegister dst,
4126                      const LogicVRegister& src1,
4127                      const LogicVRegister& src2);
4128  LogicVRegister shl(VectorFormat vform,
4129                     LogicVRegister dst,
4130                     const LogicVRegister& src,
4131                     int shift);
4132  LogicVRegister scvtf(VectorFormat vform,
4133                       unsigned dst_data_size_in_bits,
4134                       unsigned src_data_size_in_bits,
4135                       LogicVRegister dst,
4136                       const LogicPRegister& pg,
4137                       const LogicVRegister& src,
4138                       FPRounding round,
4139                       int fbits = 0);
4140  LogicVRegister scvtf(VectorFormat vform,
4141                       LogicVRegister dst,
4142                       const LogicVRegister& src,
4143                       int fbits,
4144                       FPRounding rounding_mode);
4145  LogicVRegister ucvtf(VectorFormat vform,
4146                       unsigned dst_data_size,
4147                       unsigned src_data_size,
4148                       LogicVRegister dst,
4149                       const LogicPRegister& pg,
4150                       const LogicVRegister& src,
4151                       FPRounding round,
4152                       int fbits = 0);
4153  LogicVRegister ucvtf(VectorFormat vform,
4154                       LogicVRegister dst,
4155                       const LogicVRegister& src,
4156                       int fbits,
4157                       FPRounding rounding_mode);
4158  LogicVRegister sshll(VectorFormat vform,
4159                       LogicVRegister dst,
4160                       const LogicVRegister& src,
4161                       int shift);
4162  LogicVRegister sshll2(VectorFormat vform,
4163                        LogicVRegister dst,
4164                        const LogicVRegister& src,
4165                        int shift);
4166  LogicVRegister shll(VectorFormat vform,
4167                      LogicVRegister dst,
4168                      const LogicVRegister& src);
4169  LogicVRegister shll2(VectorFormat vform,
4170                       LogicVRegister dst,
4171                       const LogicVRegister& src);
4172  LogicVRegister ushll(VectorFormat vform,
4173                       LogicVRegister dst,
4174                       const LogicVRegister& src,
4175                       int shift);
4176  LogicVRegister ushll2(VectorFormat vform,
4177                        LogicVRegister dst,
4178                        const LogicVRegister& src,
4179                        int shift);
4180  LogicVRegister sli(VectorFormat vform,
4181                     LogicVRegister dst,
4182                     const LogicVRegister& src,
4183                     int shift);
4184  LogicVRegister sri(VectorFormat vform,
4185                     LogicVRegister dst,
4186                     const LogicVRegister& src,
4187                     int shift);
4188  LogicVRegister sshr(VectorFormat vform,
4189                      LogicVRegister dst,
4190                      const LogicVRegister& src,
4191                      int shift);
4192  LogicVRegister ushr(VectorFormat vform,
4193                      LogicVRegister dst,
4194                      const LogicVRegister& src,
4195                      int shift);
4196  LogicVRegister ssra(VectorFormat vform,
4197                      LogicVRegister dst,
4198                      const LogicVRegister& src,
4199                      int shift);
4200  LogicVRegister usra(VectorFormat vform,
4201                      LogicVRegister dst,
4202                      const LogicVRegister& src,
4203                      int shift);
4204  LogicVRegister srsra(VectorFormat vform,
4205                       LogicVRegister dst,
4206                       const LogicVRegister& src,
4207                       int shift);
4208  LogicVRegister ursra(VectorFormat vform,
4209                       LogicVRegister dst,
4210                       const LogicVRegister& src,
4211                       int shift);
4212  LogicVRegister suqadd(VectorFormat vform,
4213                        LogicVRegister dst,
4214                        const LogicVRegister& src1,
4215                        const LogicVRegister& src2);
4216  LogicVRegister usqadd(VectorFormat vform,
4217                        LogicVRegister dst,
4218                        const LogicVRegister& src1,
4219                        const LogicVRegister& src2);
4220  LogicVRegister sqshl(VectorFormat vform,
4221                       LogicVRegister dst,
4222                       const LogicVRegister& src,
4223                       int shift);
4224  LogicVRegister uqshl(VectorFormat vform,
4225                       LogicVRegister dst,
4226                       const LogicVRegister& src,
4227                       int shift);
4228  LogicVRegister sqshlu(VectorFormat vform,
4229                        LogicVRegister dst,
4230                        const LogicVRegister& src,
4231                        int shift);
4232  LogicVRegister abs(VectorFormat vform,
4233                     LogicVRegister dst,
4234                     const LogicVRegister& src);
4235  LogicVRegister neg(VectorFormat vform,
4236                     LogicVRegister dst,
4237                     const LogicVRegister& src);
4238  LogicVRegister extractnarrow(VectorFormat vform,
4239                               LogicVRegister dst,
4240                               bool dst_is_signed,
4241                               const LogicVRegister& src,
4242                               bool src_is_signed);
4243  LogicVRegister xtn(VectorFormat vform,
4244                     LogicVRegister dst,
4245                     const LogicVRegister& src);
4246  LogicVRegister sqxtn(VectorFormat vform,
4247                       LogicVRegister dst,
4248                       const LogicVRegister& src);
4249  LogicVRegister uqxtn(VectorFormat vform,
4250                       LogicVRegister dst,
4251                       const LogicVRegister& src);
4252  LogicVRegister sqxtun(VectorFormat vform,
4253                        LogicVRegister dst,
4254                        const LogicVRegister& src);
4255  LogicVRegister absdiff(VectorFormat vform,
4256                         LogicVRegister dst,
4257                         const LogicVRegister& src1,
4258                         const LogicVRegister& src2,
4259                         bool is_signed);
4260  LogicVRegister saba(VectorFormat vform,
4261                      LogicVRegister dst,
4262                      const LogicVRegister& src1,
4263                      const LogicVRegister& src2);
4264  LogicVRegister uaba(VectorFormat vform,
4265                      LogicVRegister dst,
4266                      const LogicVRegister& src1,
4267                      const LogicVRegister& src2);
4268  LogicVRegister shrn(VectorFormat vform,
4269                      LogicVRegister dst,
4270                      const LogicVRegister& src,
4271                      int shift);
4272  LogicVRegister shrn2(VectorFormat vform,
4273                       LogicVRegister dst,
4274                       const LogicVRegister& src,
4275                       int shift);
4276  LogicVRegister rshrn(VectorFormat vform,
4277                       LogicVRegister dst,
4278                       const LogicVRegister& src,
4279                       int shift);
4280  LogicVRegister rshrn2(VectorFormat vform,
4281                        LogicVRegister dst,
4282                        const LogicVRegister& src,
4283                        int shift);
4284  LogicVRegister uqshrn(VectorFormat vform,
4285                        LogicVRegister dst,
4286                        const LogicVRegister& src,
4287                        int shift);
4288  LogicVRegister uqshrn2(VectorFormat vform,
4289                         LogicVRegister dst,
4290                         const LogicVRegister& src,
4291                         int shift);
4292  LogicVRegister uqrshrn(VectorFormat vform,
4293                         LogicVRegister dst,
4294                         const LogicVRegister& src,
4295                         int shift);
4296  LogicVRegister uqrshrn2(VectorFormat vform,
4297                          LogicVRegister dst,
4298                          const LogicVRegister& src,
4299                          int shift);
4300  LogicVRegister sqshrn(VectorFormat vform,
4301                        LogicVRegister dst,
4302                        const LogicVRegister& src,
4303                        int shift);
4304  LogicVRegister sqshrn2(VectorFormat vform,
4305                         LogicVRegister dst,
4306                         const LogicVRegister& src,
4307                         int shift);
4308  LogicVRegister sqrshrn(VectorFormat vform,
4309                         LogicVRegister dst,
4310                         const LogicVRegister& src,
4311                         int shift);
4312  LogicVRegister sqrshrn2(VectorFormat vform,
4313                          LogicVRegister dst,
4314                          const LogicVRegister& src,
4315                          int shift);
4316  LogicVRegister sqshrun(VectorFormat vform,
4317                         LogicVRegister dst,
4318                         const LogicVRegister& src,
4319                         int shift);
4320  LogicVRegister sqshrun2(VectorFormat vform,
4321                          LogicVRegister dst,
4322                          const LogicVRegister& src,
4323                          int shift);
4324  LogicVRegister sqrshrun(VectorFormat vform,
4325                          LogicVRegister dst,
4326                          const LogicVRegister& src,
4327                          int shift);
4328  LogicVRegister sqrshrun2(VectorFormat vform,
4329                           LogicVRegister dst,
4330                           const LogicVRegister& src,
4331                           int shift);
4332  LogicVRegister sqrdmulh(VectorFormat vform,
4333                          LogicVRegister dst,
4334                          const LogicVRegister& src1,
4335                          const LogicVRegister& src2,
4336                          bool round = true);
4337  LogicVRegister dot(VectorFormat vform,
4338                     LogicVRegister dst,
4339                     const LogicVRegister& src1,
4340                     const LogicVRegister& src2,
4341                     bool is_src1_signed,
4342                     bool is_src2_signed);
4343  LogicVRegister sdot(VectorFormat vform,
4344                      LogicVRegister dst,
4345                      const LogicVRegister& src1,
4346                      const LogicVRegister& src2);
4347  LogicVRegister udot(VectorFormat vform,
4348                      LogicVRegister dst,
4349                      const LogicVRegister& src1,
4350                      const LogicVRegister& src2);
4351  LogicVRegister usdot(VectorFormat vform,
4352                       LogicVRegister dst,
4353                       const LogicVRegister& src1,
4354                       const LogicVRegister& src2);
4355  LogicVRegister cdot(VectorFormat vform,
4356                      LogicVRegister dst,
4357                      const LogicVRegister& acc,
4358                      const LogicVRegister& src1,
4359                      const LogicVRegister& src2,
4360                      int rot);
4361  LogicVRegister sqrdcmlah(VectorFormat vform,
4362                           LogicVRegister dst,
4363                           const LogicVRegister& srca,
4364                           const LogicVRegister& src1,
4365                           const LogicVRegister& src2,
4366                           int rot);
4367  LogicVRegister sqrdcmlah(VectorFormat vform,
4368                           LogicVRegister dst,
4369                           const LogicVRegister& srca,
4370                           const LogicVRegister& src1,
4371                           const LogicVRegister& src2,
4372                           int index,
4373                           int rot);
4374  LogicVRegister sqrdmlash(VectorFormat vform,
4375                           LogicVRegister dst,
4376                           const LogicVRegister& src1,
4377                           const LogicVRegister& src2,
4378                           bool round = true,
4379                           bool sub_op = false);
4380  LogicVRegister sqrdmlash_d(VectorFormat vform,
4381                             LogicVRegister dst,
4382                             const LogicVRegister& src1,
4383                             const LogicVRegister& src2,
4384                             bool round = true,
4385                             bool sub_op = false);
4386  LogicVRegister sqrdmlah(VectorFormat vform,
4387                          LogicVRegister dst,
4388                          const LogicVRegister& src1,
4389                          const LogicVRegister& src2,
4390                          bool round = true);
4391  LogicVRegister sqrdmlsh(VectorFormat vform,
4392                          LogicVRegister dst,
4393                          const LogicVRegister& src1,
4394                          const LogicVRegister& src2,
4395                          bool round = true);
4396  LogicVRegister sqdmulh(VectorFormat vform,
4397                         LogicVRegister dst,
4398                         const LogicVRegister& src1,
4399                         const LogicVRegister& src2);
4400  LogicVRegister matmul(VectorFormat vform_dst,
4401                        LogicVRegister dst,
4402                        const LogicVRegister& src1,
4403                        const LogicVRegister& src2,
4404                        bool src1_signed,
4405                        bool src2_signed);
4406  template <typename T>
4407  LogicVRegister fmatmul(VectorFormat vform,
4408                         LogicVRegister srcdst,
4409                         const LogicVRegister& src1,
4410                         const LogicVRegister& src2);
4411  LogicVRegister fmatmul(VectorFormat vform,
4412                         LogicVRegister srcdst,
4413                         const LogicVRegister& src1,
4414                         const LogicVRegister& src2);
4415#define NEON_3VREG_LOGIC_LIST(V) \
4416  V(addhn)                       \
4417  V(addhn2)                      \
4418  V(raddhn)                      \
4419  V(raddhn2)                     \
4420  V(subhn)                       \
4421  V(subhn2)                      \
4422  V(rsubhn)                      \
4423  V(rsubhn2)                     \
4424  V(pmull)                       \
4425  V(pmull2)                      \
4426  V(sabal)                       \
4427  V(sabal2)                      \
4428  V(uabal)                       \
4429  V(uabal2)                      \
4430  V(sabdl)                       \
4431  V(sabdl2)                      \
4432  V(uabdl)                       \
4433  V(uabdl2)                      \
4434  V(smull2)                      \
4435  V(umull2)                      \
4436  V(smlal2)                      \
4437  V(umlal2)                      \
4438  V(smlsl2)                      \
4439  V(umlsl2)                      \
4440  V(sqdmlal2)                    \
4441  V(sqdmlsl2)                    \
4442  V(sqdmull2)
4443
4444#define DEFINE_LOGIC_FUNC(FXN)                   \
4445  LogicVRegister FXN(VectorFormat vform,         \
4446                     LogicVRegister dst,         \
4447                     const LogicVRegister& src1, \
4448                     const LogicVRegister& src2);
4449  NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
4450#undef DEFINE_LOGIC_FUNC
4451
4452#define NEON_MULL_LIST(V) \
4453  V(smull)                \
4454  V(umull)                \
4455  V(smlal)                \
4456  V(umlal)                \
4457  V(smlsl)                \
4458  V(umlsl)                \
4459  V(sqdmlal)              \
4460  V(sqdmlsl)              \
4461  V(sqdmull)
4462
4463#define DECLARE_NEON_MULL_OP(FN)                \
4464  LogicVRegister FN(VectorFormat vform,         \
4465                    LogicVRegister dst,         \
4466                    const LogicVRegister& src1, \
4467                    const LogicVRegister& src2, \
4468                    bool is_2 = false);
4469  NEON_MULL_LIST(DECLARE_NEON_MULL_OP)
4470#undef DECLARE_NEON_MULL_OP
4471
4472#define NEON_FP3SAME_LIST(V) \
4473  V(fadd, FPAdd, false)      \
4474  V(fsub, FPSub, true)       \
4475  V(fmul, FPMul, true)       \
4476  V(fmulx, FPMulx, true)     \
4477  V(fdiv, FPDiv, true)       \
4478  V(fmax, FPMax, false)      \
4479  V(fmin, FPMin, false)      \
4480  V(fmaxnm, FPMaxNM, false)  \
4481  V(fminnm, FPMinNM, false)
4482
4483#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
4484  template <typename T>                            \
4485  LogicVRegister FN(VectorFormat vform,            \
4486                    LogicVRegister dst,            \
4487                    const LogicVRegister& src1,    \
4488                    const LogicVRegister& src2);   \
4489  LogicVRegister FN(VectorFormat vform,            \
4490                    LogicVRegister dst,            \
4491                    const LogicVRegister& src1,    \
4492                    const LogicVRegister& src2);
4493  NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
4494#undef DECLARE_NEON_FP_VECTOR_OP
4495
4496#define NEON_FPPAIRWISE_LIST(V) \
4497  V(faddp, fadd, FPAdd)         \
4498  V(fmaxp, fmax, FPMax)         \
4499  V(fmaxnmp, fmaxnm, FPMaxNM)   \
4500  V(fminp, fmin, FPMin)         \
4501  V(fminnmp, fminnm, FPMinNM)
4502
4503#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)      \
4504  LogicVRegister FNP(VectorFormat vform,          \
4505                     LogicVRegister dst,          \
4506                     const LogicVRegister& src1,  \
4507                     const LogicVRegister& src2); \
4508  LogicVRegister FNP(VectorFormat vform,          \
4509                     LogicVRegister dst,          \
4510                     const LogicVRegister& src);
4511  NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
4512#undef DECLARE_NEON_FP_PAIR_OP
4513
4514  enum FrintMode {
4515    kFrintToInteger = 0,
4516    kFrintToInt32 = 32,
4517    kFrintToInt64 = 64
4518  };
4519
4520  template <typename T>
4521  LogicVRegister frecps(VectorFormat vform,
4522                        LogicVRegister dst,
4523                        const LogicVRegister& src1,
4524                        const LogicVRegister& src2);
4525  LogicVRegister frecps(VectorFormat vform,
4526                        LogicVRegister dst,
4527                        const LogicVRegister& src1,
4528                        const LogicVRegister& src2);
4529  template <typename T>
4530  LogicVRegister frsqrts(VectorFormat vform,
4531                         LogicVRegister dst,
4532                         const LogicVRegister& src1,
4533                         const LogicVRegister& src2);
4534  LogicVRegister frsqrts(VectorFormat vform,
4535                         LogicVRegister dst,
4536                         const LogicVRegister& src1,
4537                         const LogicVRegister& src2);
4538  template <typename T>
4539  LogicVRegister fmla(VectorFormat vform,
4540                      LogicVRegister dst,
4541                      const LogicVRegister& srca,
4542                      const LogicVRegister& src1,
4543                      const LogicVRegister& src2);
4544  LogicVRegister fmla(VectorFormat vform,
4545                      LogicVRegister dst,
4546                      const LogicVRegister& srca,
4547                      const LogicVRegister& src1,
4548                      const LogicVRegister& src2);
4549  template <typename T>
4550  LogicVRegister fmls(VectorFormat vform,
4551                      LogicVRegister dst,
4552                      const LogicVRegister& srca,
4553                      const LogicVRegister& src1,
4554                      const LogicVRegister& src2);
4555  LogicVRegister fmls(VectorFormat vform,
4556                      LogicVRegister dst,
4557                      const LogicVRegister& srca,
4558                      const LogicVRegister& src1,
4559                      const LogicVRegister& src2);
4560  LogicVRegister fnmul(VectorFormat vform,
4561                       LogicVRegister dst,
4562                       const LogicVRegister& src1,
4563                       const LogicVRegister& src2);
4564
4565  LogicVRegister fmlal(VectorFormat vform,
4566                       LogicVRegister dst,
4567                       const LogicVRegister& src1,
4568                       const LogicVRegister& src2);
4569  LogicVRegister fmlal2(VectorFormat vform,
4570                        LogicVRegister dst,
4571                        const LogicVRegister& src1,
4572                        const LogicVRegister& src2);
4573  LogicVRegister fmlsl(VectorFormat vform,
4574                       LogicVRegister dst,
4575                       const LogicVRegister& src1,
4576                       const LogicVRegister& src2);
4577  LogicVRegister fmlsl2(VectorFormat vform,
4578                        LogicVRegister dst,
4579                        const LogicVRegister& src1,
4580                        const LogicVRegister& src2);
4581
4582  template <typename T>
4583  LogicVRegister fcmp(VectorFormat vform,
4584                      LogicVRegister dst,
4585                      const LogicVRegister& src1,
4586                      const LogicVRegister& src2,
4587                      Condition cond);
4588  LogicVRegister fcmp(VectorFormat vform,
4589                      LogicVRegister dst,
4590                      const LogicVRegister& src1,
4591                      const LogicVRegister& src2,
4592                      Condition cond);
4593  LogicVRegister fabscmp(VectorFormat vform,
4594                         LogicVRegister dst,
4595                         const LogicVRegister& src1,
4596                         const LogicVRegister& src2,
4597                         Condition cond);
4598  LogicVRegister fcmp_zero(VectorFormat vform,
4599                           LogicVRegister dst,
4600                           const LogicVRegister& src,
4601                           Condition cond);
4602
4603  template <typename T>
4604  LogicVRegister fneg(VectorFormat vform,
4605                      LogicVRegister dst,
4606                      const LogicVRegister& src);
4607  LogicVRegister fneg(VectorFormat vform,
4608                      LogicVRegister dst,
4609                      const LogicVRegister& src);
4610  template <typename T>
4611  LogicVRegister frecpx(VectorFormat vform,
4612                        LogicVRegister dst,
4613                        const LogicVRegister& src);
4614  LogicVRegister frecpx(VectorFormat vform,
4615                        LogicVRegister dst,
4616                        const LogicVRegister& src);
4617  LogicVRegister ftsmul(VectorFormat vform,
4618                        LogicVRegister dst,
4619                        const LogicVRegister& src1,
4620                        const LogicVRegister& src2);
4621  LogicVRegister ftssel(VectorFormat vform,
4622                        LogicVRegister dst,
4623                        const LogicVRegister& src1,
4624                        const LogicVRegister& src2);
4625  LogicVRegister ftmad(VectorFormat vform,
4626                       LogicVRegister dst,
4627                       const LogicVRegister& src1,
4628                       const LogicVRegister& src2,
4629                       unsigned index);
4630  LogicVRegister fexpa(VectorFormat vform,
4631                       LogicVRegister dst,
4632                       const LogicVRegister& src);
4633  LogicVRegister flogb(VectorFormat vform,
4634                       LogicVRegister dst,
4635                       const LogicVRegister& src);
4636  template <typename T>
4637  LogicVRegister fscale(VectorFormat vform,
4638                        LogicVRegister dst,
4639                        const LogicVRegister& src1,
4640                        const LogicVRegister& src2);
4641  LogicVRegister fscale(VectorFormat vform,
4642                        LogicVRegister dst,
4643                        const LogicVRegister& src1,
4644                        const LogicVRegister& src2);
4645  template <typename T>
4646  LogicVRegister fabs_(VectorFormat vform,
4647                       LogicVRegister dst,
4648                       const LogicVRegister& src);
4649  LogicVRegister fabs_(VectorFormat vform,
4650                       LogicVRegister dst,
4651                       const LogicVRegister& src);
4652  LogicVRegister fabd(VectorFormat vform,
4653                      LogicVRegister dst,
4654                      const LogicVRegister& src1,
4655                      const LogicVRegister& src2);
4656  LogicVRegister frint(VectorFormat vform,
4657                       LogicVRegister dst,
4658                       const LogicVRegister& src,
4659                       FPRounding rounding_mode,
4660                       bool inexact_exception = false,
4661                       FrintMode frint_mode = kFrintToInteger);
4662  LogicVRegister fcvt(VectorFormat dst_vform,
4663                      VectorFormat src_vform,
4664                      LogicVRegister dst,
4665                      const LogicPRegister& pg,
4666                      const LogicVRegister& src);
4667  LogicVRegister fcvts(VectorFormat vform,
4668                       unsigned dst_data_size_in_bits,
4669                       unsigned src_data_size_in_bits,
4670                       LogicVRegister dst,
4671                       const LogicPRegister& pg,
4672                       const LogicVRegister& src,
4673                       FPRounding round,
4674                       int fbits = 0);
4675  LogicVRegister fcvts(VectorFormat vform,
4676                       LogicVRegister dst,
4677                       const LogicVRegister& src,
4678                       FPRounding rounding_mode,
4679                       int fbits = 0);
4680  LogicVRegister fcvtu(VectorFormat vform,
4681                       unsigned dst_data_size_in_bits,
4682                       unsigned src_data_size_in_bits,
4683                       LogicVRegister dst,
4684                       const LogicPRegister& pg,
4685                       const LogicVRegister& src,
4686                       FPRounding round,
4687                       int fbits = 0);
4688  LogicVRegister fcvtu(VectorFormat vform,
4689                       LogicVRegister dst,
4690                       const LogicVRegister& src,
4691                       FPRounding rounding_mode,
4692                       int fbits = 0);
4693  LogicVRegister fcvtl(VectorFormat vform,
4694                       LogicVRegister dst,
4695                       const LogicVRegister& src);
4696  LogicVRegister fcvtl2(VectorFormat vform,
4697                        LogicVRegister dst,
4698                        const LogicVRegister& src);
4699  LogicVRegister fcvtn(VectorFormat vform,
4700                       LogicVRegister dst,
4701                       const LogicVRegister& src);
4702  LogicVRegister fcvtn2(VectorFormat vform,
4703                        LogicVRegister dst,
4704                        const LogicVRegister& src);
4705  LogicVRegister fcvtxn(VectorFormat vform,
4706                        LogicVRegister dst,
4707                        const LogicVRegister& src);
4708  LogicVRegister fcvtxn2(VectorFormat vform,
4709                         LogicVRegister dst,
4710                         const LogicVRegister& src);
4711  LogicVRegister fsqrt(VectorFormat vform,
4712                       LogicVRegister dst,
4713                       const LogicVRegister& src);
4714  LogicVRegister frsqrte(VectorFormat vform,
4715                         LogicVRegister dst,
4716                         const LogicVRegister& src);
4717  LogicVRegister frecpe(VectorFormat vform,
4718                        LogicVRegister dst,
4719                        const LogicVRegister& src,
4720                        FPRounding rounding);
4721  LogicVRegister ursqrte(VectorFormat vform,
4722                         LogicVRegister dst,
4723                         const LogicVRegister& src);
4724  LogicVRegister urecpe(VectorFormat vform,
4725                        LogicVRegister dst,
4726                        const LogicVRegister& src);
4727
4728  LogicPRegister pfalse(LogicPRegister dst);
4729  LogicPRegister pfirst(LogicPRegister dst,
4730                        const LogicPRegister& pg,
4731                        const LogicPRegister& src);
4732  LogicPRegister ptrue(VectorFormat vform, LogicPRegister dst, int pattern);
4733  LogicPRegister pnext(VectorFormat vform,
4734                       LogicPRegister dst,
4735                       const LogicPRegister& pg,
4736                       const LogicPRegister& src);
4737
4738  LogicVRegister asrd(VectorFormat vform,
4739                      LogicVRegister dst,
4740                      const LogicVRegister& src1,
4741                      int shift);
4742
4743  LogicVRegister andv(VectorFormat vform,
4744                      LogicVRegister dst,
4745                      const LogicPRegister& pg,
4746                      const LogicVRegister& src);
4747  LogicVRegister eorv(VectorFormat vform,
4748                      LogicVRegister dst,
4749                      const LogicPRegister& pg,
4750                      const LogicVRegister& src);
4751  LogicVRegister orv(VectorFormat vform,
4752                     LogicVRegister dst,
4753                     const LogicPRegister& pg,
4754                     const LogicVRegister& src);
4755  LogicVRegister saddv(VectorFormat vform,
4756                       LogicVRegister dst,
4757                       const LogicPRegister& pg,
4758                       const LogicVRegister& src);
4759  LogicVRegister sminv(VectorFormat vform,
4760                       LogicVRegister dst,
4761                       const LogicPRegister& pg,
4762                       const LogicVRegister& src);
4763  LogicVRegister smaxv(VectorFormat vform,
4764                       LogicVRegister dst,
4765                       const LogicPRegister& pg,
4766                       const LogicVRegister& src);
4767  LogicVRegister uaddv(VectorFormat vform,
4768                       LogicVRegister dst,
4769                       const LogicPRegister& pg,
4770                       const LogicVRegister& src);
4771  LogicVRegister uminv(VectorFormat vform,
4772                       LogicVRegister dst,
4773                       const LogicPRegister& pg,
4774                       const LogicVRegister& src);
4775  LogicVRegister umaxv(VectorFormat vform,
4776                       LogicVRegister dst,
4777                       const LogicPRegister& pg,
4778                       const LogicVRegister& src);
4779
4780  LogicVRegister interleave_top_bottom(VectorFormat vform,
4781                                       LogicVRegister dst,
4782                                       const LogicVRegister& src);
4783
4784  template <typename T>
4785  struct TFPPairOp {
4786    typedef T (Simulator::*type)(T a, T b);
4787  };
4788
4789  template <typename T>
4790  LogicVRegister FPPairedAcrossHelper(VectorFormat vform,
4791                                      LogicVRegister dst,
4792                                      const LogicVRegister& src,
4793                                      typename TFPPairOp<T>::type fn,
4794                                      uint64_t inactive_value);
4795
4796  LogicVRegister FPPairedAcrossHelper(
4797      VectorFormat vform,
4798      LogicVRegister dst,
4799      const LogicVRegister& src,
4800      typename TFPPairOp<vixl::internal::SimFloat16>::type fn16,
4801      typename TFPPairOp<float>::type fn32,
4802      typename TFPPairOp<double>::type fn64,
4803      uint64_t inactive_value);
4804
4805  LogicVRegister fminv(VectorFormat vform,
4806                       LogicVRegister dst,
4807                       const LogicVRegister& src);
4808  LogicVRegister fmaxv(VectorFormat vform,
4809                       LogicVRegister dst,
4810                       const LogicVRegister& src);
4811  LogicVRegister fminnmv(VectorFormat vform,
4812                         LogicVRegister dst,
4813                         const LogicVRegister& src);
4814  LogicVRegister fmaxnmv(VectorFormat vform,
4815                         LogicVRegister dst,
4816                         const LogicVRegister& src);
4817  LogicVRegister faddv(VectorFormat vform,
4818                       LogicVRegister dst,
4819                       const LogicVRegister& src);
4820
4821  static const uint32_t CRC32_POLY = 0x04C11DB7;
4822  static const uint32_t CRC32C_POLY = 0x1EDC6F41;
4823  uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
4824  template <typename T>
4825  uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
4826  uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
4827
4828  void SysOp_W(int op, int64_t val);
4829
4830  template <typename T>
4831  T FPRecipSqrtEstimate(T op);
4832  template <typename T>
4833  T FPRecipEstimate(T op, FPRounding rounding);
4834  template <typename T, typename R>
4835  R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
4836
4837  void FPCompare(double val0, double val1, FPTrapFlags trap);
4838  double FPRoundInt(double value, FPRounding round_mode);
4839  double FPRoundInt(double value, FPRounding round_mode, FrintMode frint_mode);
4840  double FPRoundIntCommon(double value, FPRounding round_mode);
4841  double recip_sqrt_estimate(double a);
4842  double recip_estimate(double a);
4843  double FPRecipSqrtEstimate(double a);
4844  double FPRecipEstimate(double a);
4845  double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
4846  double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
4847  float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
4848  float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
4849  ::vixl::internal::SimFloat16 FixedToFloat16(int64_t src,
4850                                              int fbits,
4851                                              FPRounding round_mode);
4852  ::vixl::internal::SimFloat16 UFixedToFloat16(uint64_t src,
4853                                               int fbits,
4854                                               FPRounding round_mode);
4855  int16_t FPToInt16(double value, FPRounding rmode);
4856  int32_t FPToInt32(double value, FPRounding rmode);
4857  int64_t FPToInt64(double value, FPRounding rmode);
4858  uint16_t FPToUInt16(double value, FPRounding rmode);
4859  uint32_t FPToUInt32(double value, FPRounding rmode);
4860  uint64_t FPToUInt64(double value, FPRounding rmode);
4861  int32_t FPToFixedJS(double value);
4862
4863  template <typename T>
4864  T FPAdd(T op1, T op2);
4865
4866  template <typename T>
4867  T FPNeg(T op);
4868
4869  template <typename T>
4870  T FPDiv(T op1, T op2);
4871
4872  template <typename T>
4873  T FPMax(T a, T b);
4874
4875  template <typename T>
4876  T FPMaxNM(T a, T b);
4877
4878  template <typename T>
4879  T FPMin(T a, T b);
4880
4881  template <typename T>
4882  T FPMinNM(T a, T b);
4883
4884  template <typename T>
4885  T FPMulNaNs(T op1, T op2);
4886
4887  template <typename T>
4888  T FPMul(T op1, T op2);
4889
4890  template <typename T>
4891  T FPMulx(T op1, T op2);
4892
4893  template <typename T>
4894  T FPMulAdd(T a, T op1, T op2);
4895
4896  template <typename T>
4897  T FPSqrt(T op);
4898
4899  template <typename T>
4900  T FPSub(T op1, T op2);
4901
4902  template <typename T>
4903  T FPRecipStepFused(T op1, T op2);
4904
4905  template <typename T>
4906  T FPRSqrtStepFused(T op1, T op2);
4907
4908  // This doesn't do anything at the moment. We'll need it if we want support
4909  // for cumulative exception bits or floating-point exceptions.
4910  void FPProcessException() {}
4911
4912  bool FPProcessNaNs(const Instruction* instr);
4913
4914  // Pseudo Printf instruction
4915  void DoPrintf(const Instruction* instr);
4916
4917  // Pseudo-instructions to configure CPU features dynamically.
4918  void DoConfigureCPUFeatures(const Instruction* instr);
4919
4920  void DoSaveCPUFeatures(const Instruction* instr);
4921  void DoRestoreCPUFeatures(const Instruction* instr);
4922
4923  // General arithmetic helpers ----------------------------
4924
4925  // Add `delta` to the accumulator (`acc`), optionally saturate, then zero- or
4926  // sign-extend. Initial `acc` bits outside `n` are ignored, but the delta must
4927  // be a valid int<n>_t.
4928  uint64_t IncDecN(uint64_t acc,
4929                   int64_t delta,
4930                   unsigned n,
4931                   bool is_saturating = false,
4932                   bool is_signed = false);
4933
4934  // SVE helpers -------------------------------------------
4935  LogicVRegister SVEBitwiseLogicalUnpredicatedHelper(LogicalOp op,
4936                                                     VectorFormat vform,
4937                                                     LogicVRegister zd,
4938                                                     const LogicVRegister& zn,
4939                                                     const LogicVRegister& zm);
4940
4941  LogicPRegister SVEPredicateLogicalHelper(SVEPredicateLogicalOp op,
4942                                           LogicPRegister Pd,
4943                                           const LogicPRegister& pn,
4944                                           const LogicPRegister& pm);
4945
4946  LogicVRegister SVEBitwiseImmHelper(SVEBitwiseLogicalWithImm_UnpredicatedOp op,
4947                                     VectorFormat vform,
4948                                     LogicVRegister zd,
4949                                     uint64_t imm);
4950  enum UnpackType { kHiHalf, kLoHalf };
4951  enum ExtendType { kSignedExtend, kUnsignedExtend };
4952  LogicVRegister unpk(VectorFormat vform,
4953                      LogicVRegister zd,
4954                      const LogicVRegister& zn,
4955                      UnpackType unpack_type,
4956                      ExtendType extend_type);
4957
4958  LogicPRegister SVEIntCompareVectorsHelper(Condition cc,
4959                                            VectorFormat vform,
4960                                            LogicPRegister dst,
4961                                            const LogicPRegister& mask,
4962                                            const LogicVRegister& src1,
4963                                            const LogicVRegister& src2,
4964                                            bool is_wide_elements = false,
4965                                            FlagsUpdate flags = SetFlags);
4966
4967  void SVEGatherLoadScalarPlusVectorHelper(const Instruction* instr,
4968                                           VectorFormat vform,
4969                                           SVEOffsetModifier mod);
4970
4971  // Store each active zt<i>[lane] to `addr.GetElementAddress(lane, ...)`.
4972  //
4973  // `zt_code` specifies the code of the first register (zt). Each additional
4974  // register (up to `reg_count`) is `(zt_code + i) % 32`.
4975  //
4976  // This helper calls LogZWrite in the proper way, according to `addr`.
4977  void SVEStructuredStoreHelper(VectorFormat vform,
4978                                const LogicPRegister& pg,
4979                                unsigned zt_code,
4980                                const LogicSVEAddressVector& addr);
4981  // Load each active zt<i>[lane] from `addr.GetElementAddress(lane, ...)`.
4982  void SVEStructuredLoadHelper(VectorFormat vform,
4983                               const LogicPRegister& pg,
4984                               unsigned zt_code,
4985                               const LogicSVEAddressVector& addr,
4986                               bool is_signed = false);
4987
4988  enum SVEFaultTolerantLoadType {
4989    // - Elements active in both FFR and pg are accessed as usual. If the access
4990    //   fails, the corresponding lane and all subsequent lanes are filled with
4991    //   an unpredictable value, and made inactive in FFR.
4992    //
4993    // - Elements active in FFR but not pg are set to zero.
4994    //
4995    // - Elements that are not active in FFR are filled with an unpredictable
4996    //   value, regardless of pg.
4997    kSVENonFaultLoad,
4998
4999    // If type == kSVEFirstFaultLoad, the behaviour is the same, except that the
5000    // first active element is always accessed, regardless of FFR, and will
5001    // generate a real fault if it is inaccessible. If the lane is not active in
5002    // FFR, the actual value loaded into the result is still unpredictable.
5003    kSVEFirstFaultLoad
5004  };
5005
5006  // Load with first-faulting or non-faulting load semantics, respecting and
5007  // updating FFR.
5008  void SVEFaultTolerantLoadHelper(VectorFormat vform,
5009                                  const LogicPRegister& pg,
5010                                  unsigned zt_code,
5011                                  const LogicSVEAddressVector& addr,
5012                                  SVEFaultTolerantLoadType type,
5013                                  bool is_signed);
5014
5015  LogicVRegister SVEBitwiseShiftHelper(Shift shift_op,
5016                                       VectorFormat vform,
5017                                       LogicVRegister dst,
5018                                       const LogicVRegister& src1,
5019                                       const LogicVRegister& src2,
5020                                       bool is_wide_elements);
5021
5022  // Pack all even- or odd-numbered elements of source vector side by side and
5023  // place in elements of lower half the destination vector, and leave the upper
5024  // half all zero.
5025  //    [...| H | G | F | E | D | C | B | A ]
5026  // => [...................| G | E | C | A ]
5027  LogicVRegister pack_even_elements(VectorFormat vform,
5028                                    LogicVRegister dst,
5029                                    const LogicVRegister& src);
5030
5031  //    [...| H | G | F | E | D | C | B | A ]
5032  // => [...................| H | F | D | B ]
5033  LogicVRegister pack_odd_elements(VectorFormat vform,
5034                                   LogicVRegister dst,
5035                                   const LogicVRegister& src);
5036
5037  LogicVRegister adcl(VectorFormat vform,
5038                      LogicVRegister dst,
5039                      const LogicVRegister& src1,
5040                      const LogicVRegister& src2,
5041                      bool top);
5042
5043  template <typename T>
5044  LogicVRegister FTMaddHelper(VectorFormat vform,
5045                              LogicVRegister dst,
5046                              const LogicVRegister& src1,
5047                              const LogicVRegister& src2,
5048                              uint64_t coeff_pos,
5049                              uint64_t coeff_neg);
5050
5051  // Return the first or last active lane, or -1 if none are active.
5052  int GetFirstActive(VectorFormat vform, const LogicPRegister& pg) const;
5053  int GetLastActive(VectorFormat vform, const LogicPRegister& pg) const;
5054
5055  int CountActiveLanes(VectorFormat vform, const LogicPRegister& pg) const;
5056
5057  // Count active and true lanes in `pn`.
5058  int CountActiveAndTrueLanes(VectorFormat vform,
5059                              const LogicPRegister& pg,
5060                              const LogicPRegister& pn) const;
5061
5062  // Count the number of lanes referred to by `pattern`, given the vector
5063  // length. If `pattern` is not a recognised SVEPredicateConstraint, this
5064  // returns zero.
5065  int GetPredicateConstraintLaneCount(VectorFormat vform, int pattern) const;
5066
5067  // Simulate a runtime call.
5068  void DoRuntimeCall(const Instruction* instr);
5069
5070  // Processor state ---------------------------------------
5071
5072  // Simulated monitors for exclusive access instructions.
5073  SimExclusiveLocalMonitor local_monitor_;
5074  SimExclusiveGlobalMonitor global_monitor_;
5075
5076  // Output stream.
5077  FILE* stream_;
5078  PrintDisassembler* print_disasm_;
5079
5080  // General purpose registers. Register 31 is the stack pointer.
5081  SimRegister registers_[kNumberOfRegisters];
5082
5083  // Vector registers
5084  SimVRegister vregisters_[kNumberOfVRegisters];
5085
5086  // SVE predicate registers.
5087  SimPRegister pregisters_[kNumberOfPRegisters];
5088
5089  // SVE first-fault register.
5090  SimFFRRegister ffr_register_;
5091
5092  // A pseudo SVE predicate register with all bits set to true.
5093  SimPRegister pregister_all_true_;
5094
5095  // Program Status Register.
5096  // bits[31, 27]: Condition flags N, Z, C, and V.
5097  //               (Negative, Zero, Carry, Overflow)
5098  SimSystemRegister nzcv_;
5099
5100  // Floating-Point Control Register
5101  SimSystemRegister fpcr_;
5102
5103  // Only a subset of FPCR features are supported by the simulator. This helper
5104  // checks that the FPCR settings are supported.
5105  //
5106  // This is checked when floating-point instructions are executed, not when
5107  // FPCR is set. This allows generated code to modify FPCR for external
5108  // functions, or to save and restore it when entering and leaving generated
5109  // code.
5110  void AssertSupportedFPCR() {
5111    // No flush-to-zero support.
5112    VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
5113    // Ties-to-even rounding only.
5114    VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
5115    // No alternative half-precision support.
5116    VIXL_ASSERT(ReadFpcr().GetAHP() == 0);
5117  }
5118
5119  static int CalcNFlag(uint64_t result, unsigned reg_size) {
5120    return (result >> (reg_size - 1)) & 1;
5121  }
5122
5123  static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
5124
5125  static const uint32_t kConditionFlagsMask = 0xf0000000;
5126
5127  Memory memory_;
5128
5129  static const size_t kDefaultStackGuardStartSize = 0;
5130  static const size_t kDefaultStackGuardEndSize = 4 * 1024;
5131  static const size_t kDefaultStackUsableSize = 8 * 1024;
5132
5133  Decoder* decoder_;
5134  // Indicates if the pc has been modified by the instruction and should not be
5135  // automatically incremented.
5136  bool pc_modified_;
5137  const Instruction* pc_;
5138
5139  // Pointer to the last simulated instruction, used for checking the validity
5140  // of the current instruction with the previous instruction, such as movprfx.
5141  Instruction const* last_instr_;
5142
5143  // Branch type register, used for branch target identification.
5144  BType btype_;
5145
5146  // Next value of branch type register after the current instruction has been
5147  // decoded.
5148  BType next_btype_;
5149
5150  // Global flag for enabling guarded pages.
5151  // TODO: implement guarding at page granularity, rather than globally.
5152  bool guard_pages_;
5153
5154  static const char* xreg_names[];
5155  static const char* wreg_names[];
5156  static const char* breg_names[];
5157  static const char* hreg_names[];
5158  static const char* sreg_names[];
5159  static const char* dreg_names[];
5160  static const char* vreg_names[];
5161  static const char* zreg_names[];
5162  static const char* preg_names[];
5163
5164 private:
5165  using FormToVisitorFnMap = FormToVisitorFnMapT<Simulator>;
5166
5167  static const FormToVisitorFnMap FORM_TO_VISITOR;
5168
5169  static const FormToVisitorFnMap* GetFormToVisitorFnMap();
5170
5171  uint32_t form_hash_;
5172
5173  static const PACKey kPACKeyIA;
5174  static const PACKey kPACKeyIB;
5175  static const PACKey kPACKeyDA;
5176  static const PACKey kPACKeyDB;
5177  static const PACKey kPACKeyGA;
5178
5179  bool CanReadMemory(uintptr_t address, size_t size);
5180
5181  // CanReadMemory needs placeholder file descriptors, so we use a pipe. We can
5182  // save some system call overhead by opening them on construction, rather than
5183  // on every call to CanReadMemory.
5184  int placeholder_pipe_fd_[2];
5185
5186  template <typename T>
5187  static T FPDefaultNaN();
5188
5189  // Standard NaN processing.
5190  template <typename T>
5191  T FPProcessNaN(T op) {
5192    VIXL_ASSERT(IsNaN(op));
5193    if (IsSignallingNaN(op)) {
5194      FPProcessException();
5195    }
5196    return (ReadDN() == kUseDefaultNaN) ? FPDefaultNaN<T>() : ToQuietNaN(op);
5197  }
5198
5199  template <typename T>
5200  T FPProcessNaNs(T op1, T op2) {
5201    if (IsSignallingNaN(op1)) {
5202      return FPProcessNaN(op1);
5203    } else if (IsSignallingNaN(op2)) {
5204      return FPProcessNaN(op2);
5205    } else if (IsNaN(op1)) {
5206      VIXL_ASSERT(IsQuietNaN(op1));
5207      return FPProcessNaN(op1);
5208    } else if (IsNaN(op2)) {
5209      VIXL_ASSERT(IsQuietNaN(op2));
5210      return FPProcessNaN(op2);
5211    } else {
5212      return 0.0;
5213    }
5214  }
5215
5216  template <typename T>
5217  T FPProcessNaNs3(T op1, T op2, T op3) {
5218    if (IsSignallingNaN(op1)) {
5219      return FPProcessNaN(op1);
5220    } else if (IsSignallingNaN(op2)) {
5221      return FPProcessNaN(op2);
5222    } else if (IsSignallingNaN(op3)) {
5223      return FPProcessNaN(op3);
5224    } else if (IsNaN(op1)) {
5225      VIXL_ASSERT(IsQuietNaN(op1));
5226      return FPProcessNaN(op1);
5227    } else if (IsNaN(op2)) {
5228      VIXL_ASSERT(IsQuietNaN(op2));
5229      return FPProcessNaN(op2);
5230    } else if (IsNaN(op3)) {
5231      VIXL_ASSERT(IsQuietNaN(op3));
5232      return FPProcessNaN(op3);
5233    } else {
5234      return 0.0;
5235    }
5236  }
5237
5238  // Construct a SimVRegister from a SimPRegister, where each byte-sized lane of
5239  // the destination is set to all true (0xff) when the corresponding
5240  // predicate flag is set, and false (0x00) otherwise.
5241  SimVRegister ExpandToSimVRegister(const SimPRegister& preg);
5242
5243  // Set each predicate flag in pd where the corresponding assigned-sized lane
5244  // in vreg is non-zero. Clear the flag, otherwise. This is almost the opposite
5245  // operation to ExpandToSimVRegister(), except that any non-zero lane is
5246  // interpreted as true.
5247  void ExtractFromSimVRegister(VectorFormat vform,
5248                               SimPRegister& pd,  // NOLINT(runtime/references)
5249                               SimVRegister vreg);
5250  AllocatorWrapper allocator_;
5251
5252  bool coloured_trace_;
5253
5254  // A set of TraceParameters flags.
5255  int trace_parameters_;
5256
5257  // Indicates whether the exclusive-access warning has been printed.
5258  bool print_exclusive_access_warning_;
5259  void PrintExclusiveAccessWarning();
5260
5261  CPUFeaturesAuditor cpu_features_auditor_;
5262#ifndef PANDA_BUILD
5263  std::vector<CPUFeatures> saved_cpu_features_;
5264#else
5265  Vector<CPUFeatures>saved_cpu_features_;
5266#endif
5267
5268  // State for *rand48 functions, used to simulate randomness with repeatable
5269  // behaviour (so that tests are deterministic). This is used to simulate RNDR
5270  // and RNDRRS, as well as to simulate a source of entropy for architecturally
5271  // undefined behaviour.
5272  uint16_t rand_state_[3];
5273
5274  // A configurable size of SVE vector registers.
5275  unsigned vector_length_;
5276
5277  // Representation of memory attributes such as MTE tagging and BTI page
5278  // protection in addition to branch interceptions.
5279  MetaDataDepot meta_data_;
5280
5281  // True if the debugger is enabled and might get entered.
5282  bool debugger_enabled_;
5283
5284  // Debugger for the simulator.
5285#ifndef PANDA_BUILD
5286  std::unique_ptr<Debugger> debugger_;
5287#else
5288  Debugger* debugger_{nullptr};
5289#endif
5290};
5291
5292#if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
5293// Base case of the recursive template used to emulate C++14
5294// `std::index_sequence`.
5295template <size_t... I>
5296struct Simulator::emulated_make_index_sequence_helper<0, I...>
5297    : Simulator::emulated_index_sequence<I...> {};
5298#endif
5299
5300template <typename R, typename... P>
5301void MetaDataDepot::BranchInterception<R, P...>::operator()(
5302    Simulator* simulator) const {
5303  if (callback_ == nullptr) {
5304    Simulator::RuntimeCallStructHelper<R, P...>::
5305        Wrapper(simulator, reinterpret_cast<uint64_t>(function_));
5306  } else {
5307    callback_(reinterpret_cast<uint64_t>(function_));
5308  }
5309}
5310
5311}  // namespace aarch64
5312}  // namespace vixl
5313
5314#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
5315
5316#endif  // VIXL_AARCH64_SIMULATOR_AARCH64_H_
5317