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