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