• 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 <vector>
31 
32 #include "../globals-vixl.h"
33 #include "../utils-vixl.h"
34 
35 #include "cpu-features.h"
36 #include "abi-aarch64.h"
37 #include "cpu-features-auditor-aarch64.h"
38 #include "disasm-aarch64.h"
39 #include "instructions-aarch64.h"
40 #include "instrument-aarch64.h"
41 #include "simulator-constants-aarch64.h"
42 
43 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
44 
45 // These are only used for the ABI feature, and depend on checks performed for
46 // it.
47 #ifdef VIXL_HAS_ABI_SUPPORT
48 #include <tuple>
49 #if __cplusplus >= 201402L
50 // Required for `std::index_sequence`
51 #include <utility>
52 #endif
53 #endif
54 
55 namespace vixl {
56 namespace aarch64 {
57 
58 // Representation of memory, with typed getters and setters for access.
59 class Memory {
60  public:
61   template <typename T>
AddressUntag(T address)62   static T AddressUntag(T address) {
63     // Cast the address using a C-style cast. A reinterpret_cast would be
64     // appropriate, but it can't cast one integral type to another.
65     uint64_t bits = (uint64_t)address;
66     return (T)(bits & ~kAddressTagMask);
67   }
68 
69   template <typename T, typename A>
Read(A address)70   static T Read(A address) {
71     T value;
72     address = AddressUntag(address);
73     VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
74                 (sizeof(value) == 4) || (sizeof(value) == 8) ||
75                 (sizeof(value) == 16));
76     memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
77     return value;
78   }
79 
80   template <typename T, typename A>
Write(A address,T value)81   static void Write(A address, T value) {
82     address = AddressUntag(address);
83     VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
84                 (sizeof(value) == 4) || (sizeof(value) == 8) ||
85                 (sizeof(value) == 16));
86     memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
87   }
88 };
89 
90 // Represent a register (r0-r31, v0-v31).
91 template <int kSizeInBytes>
92 class SimRegisterBase {
93  public:
SimRegisterBase()94   SimRegisterBase() : written_since_last_log_(false) {}
95 
96   // Write the specified value. The value is zero-extended if necessary.
97   template <typename T>
Write(T new_value)98   void Write(T new_value) {
99     if (sizeof(new_value) < kSizeInBytes) {
100       // All AArch64 registers are zero-extending.
101       memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value));
102     }
103     WriteLane(new_value, 0);
104     NotifyRegisterWrite();
105   }
106   template <typename T>
Set(T new_value)107   VIXL_DEPRECATED("Write", void Set(T new_value)) {
108     Write(new_value);
109   }
110 
111   // Insert a typed value into a register, leaving the rest of the register
112   // unchanged. The lane parameter indicates where in the register the value
113   // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
114   // 0 represents the least significant bits.
115   template <typename T>
Insert(int lane,T new_value)116   void Insert(int lane, T new_value) {
117     WriteLane(new_value, lane);
118     NotifyRegisterWrite();
119   }
120 
121   // Get the value as the specified type. The value is truncated if necessary.
122   template <typename T>
Get()123   T Get() const {
124     return GetLane<T>(0);
125   }
126 
127   // Get the lane value as the specified type. The value is truncated if
128   // necessary.
129   template <typename T>
GetLane(int lane)130   T GetLane(int lane) const {
131     T result;
132     ReadLane(&result, lane);
133     return result;
134   }
135   template <typename T>
136   VIXL_DEPRECATED("GetLane", T Get(int lane) const) {
137     return GetLane(lane);
138   }
139 
140   // TODO: Make this return a map of updated bytes, so that we can highlight
141   // updated lanes for load-and-insert. (That never happens for scalar code, but
142   // NEON has some instructions that can update individual lanes.)
WrittenSinceLastLog()143   bool WrittenSinceLastLog() const { return written_since_last_log_; }
144 
NotifyRegisterLogged()145   void NotifyRegisterLogged() { written_since_last_log_ = false; }
146 
147  protected:
148   uint8_t value_[kSizeInBytes];
149 
150   // Helpers to aid with register tracing.
151   bool written_since_last_log_;
152 
NotifyRegisterWrite()153   void NotifyRegisterWrite() { written_since_last_log_ = true; }
154 
155  private:
156   template <typename T>
ReadLane(T * dst,int lane)157   void ReadLane(T* dst, int lane) const {
158     VIXL_ASSERT(lane >= 0);
159     VIXL_ASSERT((sizeof(*dst) + (lane * sizeof(*dst))) <= kSizeInBytes);
160     memcpy(dst, &value_[lane * sizeof(*dst)], sizeof(*dst));
161   }
162 
163   template <typename T>
WriteLane(T src,int lane)164   void WriteLane(T src, int lane) {
165     VIXL_ASSERT(lane >= 0);
166     VIXL_ASSERT((sizeof(src) + (lane * sizeof(src))) <= kSizeInBytes);
167     memcpy(&value_[lane * sizeof(src)], &src, sizeof(src));
168   }
169 };
170 typedef SimRegisterBase<kXRegSizeInBytes> SimRegister;   // r0-r31
171 typedef SimRegisterBase<kQRegSizeInBytes> SimVRegister;  // v0-v31
172 
173 // The default ReadLane and WriteLane methods assume what we are copying is
174 // "trivially copyable" by using memcpy. We have to provide alternative
175 // implementations for SimFloat16 which cannot be copied this way.
176 
177 template <>
178 template <>
ReadLane(vixl::internal::SimFloat16 * dst,int lane)179 inline void SimVRegister::ReadLane(vixl::internal::SimFloat16* dst,
180                                    int lane) const {
181   uint16_t rawbits;
182   ReadLane(&rawbits, lane);
183   *dst = RawbitsToFloat16(rawbits);
184 }
185 
186 template <>
187 template <>
WriteLane(vixl::internal::SimFloat16 src,int lane)188 inline void SimVRegister::WriteLane(vixl::internal::SimFloat16 src, int lane) {
189   WriteLane(Float16ToRawbits(src), lane);
190 }
191 
192 // Representation of a vector register, with typed getters and setters for lanes
193 // and additional information to represent lane state.
194 class LogicVRegister {
195  public:
LogicVRegister(SimVRegister & other)196   inline LogicVRegister(
197       SimVRegister& other)  // NOLINT(runtime/references)(runtime/explicit)
198       : register_(other) {
199     for (size_t i = 0; i < ArrayLength(saturated_); i++) {
200       saturated_[i] = kNotSaturated;
201     }
202     for (size_t i = 0; i < ArrayLength(round_); i++) {
203       round_[i] = 0;
204     }
205   }
206 
Int(VectorFormat vform,int index)207   int64_t Int(VectorFormat vform, int index) const {
208     int64_t element;
209     switch (LaneSizeInBitsFromFormat(vform)) {
210       case 8:
211         element = register_.GetLane<int8_t>(index);
212         break;
213       case 16:
214         element = register_.GetLane<int16_t>(index);
215         break;
216       case 32:
217         element = register_.GetLane<int32_t>(index);
218         break;
219       case 64:
220         element = register_.GetLane<int64_t>(index);
221         break;
222       default:
223         VIXL_UNREACHABLE();
224         return 0;
225     }
226     return element;
227   }
228 
Uint(VectorFormat vform,int index)229   uint64_t Uint(VectorFormat vform, int index) const {
230     uint64_t element;
231     switch (LaneSizeInBitsFromFormat(vform)) {
232       case 8:
233         element = register_.GetLane<uint8_t>(index);
234         break;
235       case 16:
236         element = register_.GetLane<uint16_t>(index);
237         break;
238       case 32:
239         element = register_.GetLane<uint32_t>(index);
240         break;
241       case 64:
242         element = register_.GetLane<uint64_t>(index);
243         break;
244       default:
245         VIXL_UNREACHABLE();
246         return 0;
247     }
248     return element;
249   }
250 
UintLeftJustified(VectorFormat vform,int index)251   uint64_t UintLeftJustified(VectorFormat vform, int index) const {
252     return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
253   }
254 
IntLeftJustified(VectorFormat vform,int index)255   int64_t IntLeftJustified(VectorFormat vform, int index) const {
256     uint64_t value = UintLeftJustified(vform, index);
257     int64_t result;
258     memcpy(&result, &value, sizeof(result));
259     return result;
260   }
261 
SetInt(VectorFormat vform,int index,int64_t value)262   void SetInt(VectorFormat vform, int index, int64_t value) const {
263     switch (LaneSizeInBitsFromFormat(vform)) {
264       case 8:
265         register_.Insert(index, static_cast<int8_t>(value));
266         break;
267       case 16:
268         register_.Insert(index, static_cast<int16_t>(value));
269         break;
270       case 32:
271         register_.Insert(index, static_cast<int32_t>(value));
272         break;
273       case 64:
274         register_.Insert(index, static_cast<int64_t>(value));
275         break;
276       default:
277         VIXL_UNREACHABLE();
278         return;
279     }
280   }
281 
SetIntArray(VectorFormat vform,const int64_t * src)282   void SetIntArray(VectorFormat vform, const int64_t* src) const {
283     ClearForWrite(vform);
284     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
285       SetInt(vform, i, src[i]);
286     }
287   }
288 
SetUint(VectorFormat vform,int index,uint64_t value)289   void SetUint(VectorFormat vform, int index, uint64_t value) const {
290     switch (LaneSizeInBitsFromFormat(vform)) {
291       case 8:
292         register_.Insert(index, static_cast<uint8_t>(value));
293         break;
294       case 16:
295         register_.Insert(index, static_cast<uint16_t>(value));
296         break;
297       case 32:
298         register_.Insert(index, static_cast<uint32_t>(value));
299         break;
300       case 64:
301         register_.Insert(index, static_cast<uint64_t>(value));
302         break;
303       default:
304         VIXL_UNREACHABLE();
305         return;
306     }
307   }
308 
SetUintArray(VectorFormat vform,const uint64_t * src)309   void SetUintArray(VectorFormat vform, const uint64_t* src) const {
310     ClearForWrite(vform);
311     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
312       SetUint(vform, i, src[i]);
313     }
314   }
315 
ReadUintFromMem(VectorFormat vform,int index,uint64_t addr)316   void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const {
317     switch (LaneSizeInBitsFromFormat(vform)) {
318       case 8:
319         register_.Insert(index, Memory::Read<uint8_t>(addr));
320         break;
321       case 16:
322         register_.Insert(index, Memory::Read<uint16_t>(addr));
323         break;
324       case 32:
325         register_.Insert(index, Memory::Read<uint32_t>(addr));
326         break;
327       case 64:
328         register_.Insert(index, Memory::Read<uint64_t>(addr));
329         break;
330       default:
331         VIXL_UNREACHABLE();
332         return;
333     }
334   }
335 
WriteUintToMem(VectorFormat vform,int index,uint64_t addr)336   void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const {
337     uint64_t value = Uint(vform, index);
338     switch (LaneSizeInBitsFromFormat(vform)) {
339       case 8:
340         Memory::Write(addr, static_cast<uint8_t>(value));
341         break;
342       case 16:
343         Memory::Write(addr, static_cast<uint16_t>(value));
344         break;
345       case 32:
346         Memory::Write(addr, static_cast<uint32_t>(value));
347         break;
348       case 64:
349         Memory::Write(addr, value);
350         break;
351     }
352   }
353 
354   template <typename T>
Float(int index)355   T Float(int index) const {
356     return register_.GetLane<T>(index);
357   }
358 
359   template <typename T>
SetFloat(int index,T value)360   void SetFloat(int index, T value) const {
361     register_.Insert(index, value);
362   }
363 
364   // When setting a result in a register of size less than Q, the top bits of
365   // the Q register must be cleared.
ClearForWrite(VectorFormat vform)366   void ClearForWrite(VectorFormat vform) const {
367     unsigned size = RegisterSizeInBytesFromFormat(vform);
368     for (unsigned i = size; i < kQRegSizeInBytes; i++) {
369       SetUint(kFormat16B, i, 0);
370     }
371   }
372 
373   // Saturation state for each lane of a vector.
374   enum Saturation {
375     kNotSaturated = 0,
376     kSignedSatPositive = 1 << 0,
377     kSignedSatNegative = 1 << 1,
378     kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
379     kSignedSatUndefined = kSignedSatMask,
380     kUnsignedSatPositive = 1 << 2,
381     kUnsignedSatNegative = 1 << 3,
382     kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
383     kUnsignedSatUndefined = kUnsignedSatMask
384   };
385 
386   // Getters for saturation state.
GetSignedSaturation(int index)387   Saturation GetSignedSaturation(int index) {
388     return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
389   }
390 
GetUnsignedSaturation(int index)391   Saturation GetUnsignedSaturation(int index) {
392     return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
393   }
394 
395   // Setters for saturation state.
ClearSat(int index)396   void ClearSat(int index) { saturated_[index] = kNotSaturated; }
397 
SetSignedSat(int index,bool positive)398   void SetSignedSat(int index, bool positive) {
399     SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
400   }
401 
SetUnsignedSat(int index,bool positive)402   void SetUnsignedSat(int index, bool positive) {
403     SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
404   }
405 
SetSatFlag(int index,Saturation sat)406   void SetSatFlag(int index, Saturation sat) {
407     saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
408     VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined);
409     VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined);
410   }
411 
412   // Saturate lanes of a vector based on saturation state.
SignedSaturate(VectorFormat vform)413   LogicVRegister& SignedSaturate(VectorFormat vform) {
414     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
415       Saturation sat = GetSignedSaturation(i);
416       if (sat == kSignedSatPositive) {
417         SetInt(vform, i, MaxIntFromFormat(vform));
418       } else if (sat == kSignedSatNegative) {
419         SetInt(vform, i, MinIntFromFormat(vform));
420       }
421     }
422     return *this;
423   }
424 
UnsignedSaturate(VectorFormat vform)425   LogicVRegister& UnsignedSaturate(VectorFormat vform) {
426     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
427       Saturation sat = GetUnsignedSaturation(i);
428       if (sat == kUnsignedSatPositive) {
429         SetUint(vform, i, MaxUintFromFormat(vform));
430       } else if (sat == kUnsignedSatNegative) {
431         SetUint(vform, i, 0);
432       }
433     }
434     return *this;
435   }
436 
437   // Getter for rounding state.
GetRounding(int index)438   bool GetRounding(int index) { return round_[index]; }
439 
440   // Setter for rounding state.
SetRounding(int index,bool round)441   void SetRounding(int index, bool round) { round_[index] = round; }
442 
443   // Round lanes of a vector based on rounding state.
Round(VectorFormat vform)444   LogicVRegister& Round(VectorFormat vform) {
445     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
446       SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0));
447     }
448     return *this;
449   }
450 
451   // Unsigned halve lanes of a vector, and use the saturation state to set the
452   // top bit.
Uhalve(VectorFormat vform)453   LogicVRegister& Uhalve(VectorFormat vform) {
454     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
455       uint64_t val = Uint(vform, i);
456       SetRounding(i, (val & 1) == 1);
457       val >>= 1;
458       if (GetUnsignedSaturation(i) != kNotSaturated) {
459         // If the operation causes unsigned saturation, the bit shifted into the
460         // most significant bit must be set.
461         val |= (MaxUintFromFormat(vform) >> 1) + 1;
462       }
463       SetInt(vform, i, val);
464     }
465     return *this;
466   }
467 
468   // Signed halve lanes of a vector, and use the carry state to set the top bit.
Halve(VectorFormat vform)469   LogicVRegister& Halve(VectorFormat vform) {
470     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
471       int64_t val = Int(vform, i);
472       SetRounding(i, (val & 1) == 1);
473       val >>= 1;
474       if (GetSignedSaturation(i) != kNotSaturated) {
475         // If the operation causes signed saturation, the sign bit must be
476         // inverted.
477         val ^= (MaxUintFromFormat(vform) >> 1) + 1;
478       }
479       SetInt(vform, i, val);
480     }
481     return *this;
482   }
483 
484  private:
485   SimVRegister& register_;
486 
487   // Allocate one saturation state entry per lane; largest register is type Q,
488   // and lanes can be a minimum of one byte wide.
489   Saturation saturated_[kQRegSizeInBytes];
490 
491   // Allocate one rounding state entry per lane.
492   bool round_[kQRegSizeInBytes];
493 };
494 
495 // The proper way to initialize a simulated system register (such as NZCV) is as
496 // follows:
497 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
498 class SimSystemRegister {
499  public:
500   // The default constructor represents a register which has no writable bits.
501   // It is not possible to set its value to anything other than 0.
SimSystemRegister()502   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
503 
GetRawValue()504   uint32_t GetRawValue() const { return value_; }
505   VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) {
506     return GetRawValue();
507   }
508 
SetRawValue(uint32_t new_value)509   void SetRawValue(uint32_t new_value) {
510     value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
511   }
512 
ExtractBits(int msb,int lsb)513   uint32_t ExtractBits(int msb, int lsb) const {
514     return ExtractUnsignedBitfield32(msb, lsb, value_);
515   }
516   VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) {
517     return ExtractBits(msb, lsb);
518   }
519 
ExtractSignedBits(int msb,int lsb)520   int32_t ExtractSignedBits(int msb, int lsb) const {
521     return ExtractSignedBitfield32(msb, lsb, value_);
522   }
523   VIXL_DEPRECATED("ExtractSignedBits",
524                   int32_t SignedBits(int msb, int lsb) const) {
525     return ExtractSignedBits(msb, lsb);
526   }
527 
528   void SetBits(int msb, int lsb, uint32_t bits);
529 
530   // Default system register values.
531   static SimSystemRegister DefaultValueFor(SystemRegister id);
532 
533 #define DEFINE_GETTER(Name, HighBit, LowBit, Func)                            \
534   uint32_t Get##Name() const { return this->Func(HighBit, LowBit); }          \
535   VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \
536   void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); }
537 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
538   static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
539 
SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER,DEFINE_WRITE_IGNORE_MASK)540   SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
541 
542 #undef DEFINE_ZERO_BITS
543 #undef DEFINE_GETTER
544 
545  protected:
546   // Most system registers only implement a few of the bits in the word. Other
547   // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
548   // describes the bits which are not modifiable.
549   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
550       : value_(value), write_ignore_mask_(write_ignore_mask) {}
551 
552   uint32_t value_;
553   uint32_t write_ignore_mask_;
554 };
555 
556 
557 class SimExclusiveLocalMonitor {
558  public:
SimExclusiveLocalMonitor()559   SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) {
560     Clear();
561   }
562 
563   // Clear the exclusive monitor (like clrex).
Clear()564   void Clear() {
565     address_ = 0;
566     size_ = 0;
567   }
568 
569   // Clear the exclusive monitor most of the time.
MaybeClear()570   void MaybeClear() {
571     if ((seed_ % kSkipClearProbability) != 0) {
572       Clear();
573     }
574 
575     // Advance seed_ using a simple linear congruential generator.
576     seed_ = (seed_ * 48271) % 2147483647;
577   }
578 
579   // Mark the address range for exclusive access (like load-exclusive).
MarkExclusive(uint64_t address,size_t size)580   void MarkExclusive(uint64_t address, size_t size) {
581     address_ = address;
582     size_ = size;
583   }
584 
585   // Return true if the address range is marked (like store-exclusive).
586   // This helper doesn't implicitly clear the monitor.
IsExclusive(uint64_t address,size_t size)587   bool IsExclusive(uint64_t address, size_t size) {
588     VIXL_ASSERT(size > 0);
589     // Be pedantic: Require both the address and the size to match.
590     return (size == size_) && (address == address_);
591   }
592 
593  private:
594   uint64_t address_;
595   size_t size_;
596 
597   const int kSkipClearProbability;
598   uint32_t seed_;
599 };
600 
601 
602 // We can't accurate simulate the global monitor since it depends on external
603 // influences. Instead, this implementation occasionally causes accesses to
604 // fail, according to kPassProbability.
605 class SimExclusiveGlobalMonitor {
606  public:
SimExclusiveGlobalMonitor()607   SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {}
608 
IsExclusive(uint64_t address,size_t size)609   bool IsExclusive(uint64_t address, size_t size) {
610     USE(address, size);
611 
612     bool pass = (seed_ % kPassProbability) != 0;
613     // Advance seed_ using a simple linear congruential generator.
614     seed_ = (seed_ * 48271) % 2147483647;
615     return pass;
616   }
617 
618  private:
619   const int kPassProbability;
620   uint32_t seed_;
621 };
622 
623 
624 class Simulator : public DecoderVisitor {
625  public:
626   explicit Simulator(Decoder* decoder, FILE* stream = stdout);
627   ~Simulator();
628 
629   void ResetState();
630 
631   // Run the simulator.
632   virtual void Run();
633   void RunFrom(const Instruction* first);
634 
635 
636 #if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
637     (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
638   // Templated `RunFrom` version taking care of passing arguments and returning
639   // the result value.
640   // This allows code like:
641   //    int32_t res = simulator.RunFrom<int32_t, int32_t>(GenerateCode(),
642   //                                                      0x123);
643   // It requires VIXL's ABI features, and C++11 or greater.
644   // Also, the initialisation of tuples is incorrect in GCC before 4.9.1:
645   // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
646   template <typename R, typename... P>
RunFrom(const Instruction * code,P...arguments)647   R RunFrom(const Instruction* code, P... arguments) {
648     return RunFromStructHelper<R, P...>::Wrapper(this, code, arguments...);
649   }
650 
651   template <typename R, typename... P>
652   struct RunFromStructHelper {
WrapperRunFromStructHelper653     static R Wrapper(Simulator* simulator,
654                      const Instruction* code,
655                      P... arguments) {
656       ABI abi;
657       std::tuple<P...> unused_tuple{
658           // TODO: We currently do not support arguments passed on the stack. We
659           // could do so by using `WriteGenericOperand()` here, but may need to
660           // add features to handle situations where the stack is or is not set
661           // up.
662           (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
663                                            .GetCPURegister(),
664                                        arguments),
665            arguments)...};
666       simulator->RunFrom(code);
667       return simulator->ReadGenericOperand<R>(abi.GetReturnGenericOperand<R>());
668     }
669   };
670 
671   // Partial specialization when the return type is `void`.
672   template <typename... P>
673   struct RunFromStructHelper<void, P...> {
674     static void Wrapper(Simulator* simulator,
675                         const Instruction* code,
676                         P... arguments) {
677       ABI abi;
678       std::tuple<P...> unused_tuple{
679           // TODO: We currently do not support arguments passed on the stack. We
680           // could do so by using `WriteGenericOperand()` here, but may need to
681           // add features to handle situations where the stack is or is not set
682           // up.
683           (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
684                                            .GetCPURegister(),
685                                        arguments),
686            arguments)...};
687       simulator->RunFrom(code);
688     }
689   };
690 #endif
691 
692   // Execution ends when the PC hits this address.
693   static const Instruction* kEndOfSimAddress;
694 
695   // Simulation helpers.
696   const Instruction* ReadPc() const { return pc_; }
697   VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
698 
699   enum BranchLogMode { LogBranches, NoBranchLog };
700 
701   void WritePc(const Instruction* new_pc,
702                BranchLogMode log_mode = LogBranches) {
703     if (log_mode == LogBranches) LogTakenBranch(new_pc);
704     pc_ = Memory::AddressUntag(new_pc);
705     pc_modified_ = true;
706   }
707   VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) {
708     return WritePc(new_pc);
709   }
710 
711   void IncrementPc() {
712     if (!pc_modified_) {
713       pc_ = pc_->GetNextInstruction();
714     }
715   }
716   VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); }
717 
718   void ExecuteInstruction() {
719     // The program counter should always be aligned.
720     VIXL_ASSERT(IsWordAligned(pc_));
721     pc_modified_ = false;
722 
723     // decoder_->Decode(...) triggers at least the following visitors:
724     //  1. The CPUFeaturesAuditor (`cpu_features_auditor_`).
725     //  2. The PrintDisassembler (`print_disasm_`), if enabled.
726     //  3. The Simulator (`this`).
727     // User can add additional visitors at any point, but the Simulator requires
728     // that the ordering above is preserved.
729     decoder_->Decode(pc_);
730     IncrementPc();
731     LogAllWrittenRegisters();
732 
733     VIXL_CHECK(cpu_features_auditor_.InstructionIsAvailable());
734   }
735 
736 // Declare all Visitor functions.
737 #define DECLARE(A) \
738   virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE;
739   VISITOR_LIST_THAT_RETURN(DECLARE)
740 #undef DECLARE
741 
742 #define DECLARE(A)                                                     \
743   VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr) \
744       VIXL_OVERRIDE;
745   VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
746 #undef DECLARE
747 
748 
749   // Integer register accessors.
750 
751   // Basic accessor: Read the register as the specified type.
752   template <typename T>
753   T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
754     VIXL_ASSERT(
755         code < kNumberOfRegisters ||
756         ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
757     if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
758       T result;
759       memset(&result, 0, sizeof(result));
760       return result;
761     }
762     if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
763       code = 31;
764     }
765     return registers_[code].Get<T>();
766   }
767   template <typename T>
768   VIXL_DEPRECATED("ReadRegister",
769                   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister)
770                       const) {
771     return ReadRegister<T>(code, r31mode);
772   }
773 
774   // Common specialized accessors for the ReadRegister() template.
775   int32_t ReadWRegister(unsigned code,
776                         Reg31Mode r31mode = Reg31IsZeroRegister) const {
777     return ReadRegister<int32_t>(code, r31mode);
778   }
779   VIXL_DEPRECATED("ReadWRegister",
780                   int32_t wreg(unsigned code,
781                                Reg31Mode r31mode = Reg31IsZeroRegister) const) {
782     return ReadWRegister(code, r31mode);
783   }
784 
785   int64_t ReadXRegister(unsigned code,
786                         Reg31Mode r31mode = Reg31IsZeroRegister) const {
787     return ReadRegister<int64_t>(code, r31mode);
788   }
789   VIXL_DEPRECATED("ReadXRegister",
790                   int64_t xreg(unsigned code,
791                                Reg31Mode r31mode = Reg31IsZeroRegister) const) {
792     return ReadXRegister(code, r31mode);
793   }
794 
795   // As above, with parameterized size and return type. The value is
796   // either zero-extended or truncated to fit, as required.
797   template <typename T>
798   T ReadRegister(unsigned size,
799                  unsigned code,
800                  Reg31Mode r31mode = Reg31IsZeroRegister) const {
801     uint64_t raw;
802     switch (size) {
803       case kWRegSize:
804         raw = ReadRegister<uint32_t>(code, r31mode);
805         break;
806       case kXRegSize:
807         raw = ReadRegister<uint64_t>(code, r31mode);
808         break;
809       default:
810         VIXL_UNREACHABLE();
811         return 0;
812     }
813 
814     T result;
815     VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
816     // Copy the result and truncate to fit. This assumes a little-endian host.
817     memcpy(&result, &raw, sizeof(result));
818     return result;
819   }
820   template <typename T>
821   VIXL_DEPRECATED("ReadRegister",
822                   T reg(unsigned size,
823                         unsigned code,
824                         Reg31Mode r31mode = Reg31IsZeroRegister) const) {
825     return ReadRegister<T>(size, code, r31mode);
826   }
827 
828   // Use int64_t by default if T is not specified.
829   int64_t ReadRegister(unsigned size,
830                        unsigned code,
831                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
832     return ReadRegister<int64_t>(size, code, r31mode);
833   }
834   VIXL_DEPRECATED("ReadRegister",
835                   int64_t reg(unsigned size,
836                               unsigned code,
837                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
838     return ReadRegister(size, code, r31mode);
839   }
840 
841   enum RegLogMode { LogRegWrites, NoRegLog };
842 
843   // Write 'value' into an integer register. The value is zero-extended. This
844   // behaviour matches AArch64 register writes.
845   template <typename T>
846   void WriteRegister(unsigned code,
847                      T value,
848                      RegLogMode log_mode = LogRegWrites,
849                      Reg31Mode r31mode = Reg31IsZeroRegister) {
850     if (sizeof(T) < kWRegSizeInBytes) {
851       // We use a C-style cast on purpose here.
852       // Since we do not have access to 'constepxr if', the casts in this `if`
853       // must be valid even if we know the code will never be executed, in
854       // particular when `T` is a pointer type.
855       int64_t tmp_64bit = (int64_t)value;
856       int32_t tmp_32bit = static_cast<int32_t>(tmp_64bit);
857       WriteRegister<int32_t>(code, tmp_32bit, log_mode, r31mode);
858       return;
859     }
860 
861     VIXL_ASSERT((sizeof(T) == kWRegSizeInBytes) ||
862                 (sizeof(T) == kXRegSizeInBytes));
863     VIXL_ASSERT(
864         code < kNumberOfRegisters ||
865         ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
866 
867     if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
868       return;
869     }
870 
871     if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
872       code = 31;
873     }
874 
875     registers_[code].Write(value);
876 
877     if (log_mode == LogRegWrites) LogRegister(code, r31mode);
878   }
879   template <typename T>
880   VIXL_DEPRECATED("WriteRegister",
881                   void set_reg(unsigned code,
882                                T value,
883                                RegLogMode log_mode = LogRegWrites,
884                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
885     WriteRegister<T>(code, value, log_mode, r31mode);
886   }
887 
888   // Common specialized accessors for the set_reg() template.
889   void WriteWRegister(unsigned code,
890                       int32_t value,
891                       RegLogMode log_mode = LogRegWrites,
892                       Reg31Mode r31mode = Reg31IsZeroRegister) {
893     WriteRegister(code, value, log_mode, r31mode);
894   }
895   VIXL_DEPRECATED("WriteWRegister",
896                   void set_wreg(unsigned code,
897                                 int32_t value,
898                                 RegLogMode log_mode = LogRegWrites,
899                                 Reg31Mode r31mode = Reg31IsZeroRegister)) {
900     WriteWRegister(code, value, log_mode, r31mode);
901   }
902 
903   void WriteXRegister(unsigned code,
904                       int64_t value,
905                       RegLogMode log_mode = LogRegWrites,
906                       Reg31Mode r31mode = Reg31IsZeroRegister) {
907     WriteRegister(code, value, log_mode, r31mode);
908   }
909   VIXL_DEPRECATED("WriteXRegister",
910                   void set_xreg(unsigned code,
911                                 int64_t value,
912                                 RegLogMode log_mode = LogRegWrites,
913                                 Reg31Mode r31mode = Reg31IsZeroRegister)) {
914     WriteXRegister(code, value, log_mode, r31mode);
915   }
916 
917   // As above, with parameterized size and type. The value is either
918   // zero-extended or truncated to fit, as required.
919   template <typename T>
920   void WriteRegister(unsigned size,
921                      unsigned code,
922                      T value,
923                      RegLogMode log_mode = LogRegWrites,
924                      Reg31Mode r31mode = Reg31IsZeroRegister) {
925     // Zero-extend the input.
926     uint64_t raw = 0;
927     VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw));
928     memcpy(&raw, &value, sizeof(value));
929 
930     // Write (and possibly truncate) the value.
931     switch (size) {
932       case kWRegSize:
933         WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode);
934         break;
935       case kXRegSize:
936         WriteRegister(code, raw, log_mode, r31mode);
937         break;
938       default:
939         VIXL_UNREACHABLE();
940         return;
941     }
942   }
943   template <typename T>
944   VIXL_DEPRECATED("WriteRegister",
945                   void set_reg(unsigned size,
946                                unsigned code,
947                                T value,
948                                RegLogMode log_mode = LogRegWrites,
949                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
950     WriteRegister(size, code, value, log_mode, r31mode);
951   }
952 
953   // Common specialized accessors for the set_reg() template.
954 
955   // Commonly-used special cases.
956   template <typename T>
957   void WriteLr(T value) {
958     WriteRegister(kLinkRegCode, value);
959   }
960   template <typename T>
961   VIXL_DEPRECATED("WriteLr", void set_lr(T value)) {
962     WriteLr(value);
963   }
964 
965   template <typename T>
966   void WriteSp(T value) {
967     WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer);
968   }
969   template <typename T>
970   VIXL_DEPRECATED("WriteSp", void set_sp(T value)) {
971     WriteSp(value);
972   }
973 
974   // Vector register accessors.
975   // These are equivalent to the integer register accessors, but for vector
976   // registers.
977 
978   // A structure for representing a 128-bit Q register.
979   struct qreg_t {
980     uint8_t val[kQRegSizeInBytes];
981   };
982 
983   // Basic accessor: read the register as the specified type.
984   template <typename T>
985   T ReadVRegister(unsigned code) const {
986     VIXL_STATIC_ASSERT(
987         (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) ||
988         (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) ||
989         (sizeof(T) == kQRegSizeInBytes));
990     VIXL_ASSERT(code < kNumberOfVRegisters);
991 
992     return vregisters_[code].Get<T>();
993   }
994   template <typename T>
995   VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) {
996     return ReadVRegister<T>(code);
997   }
998 
999   // Common specialized accessors for the vreg() template.
1000   int8_t ReadBRegister(unsigned code) const {
1001     return ReadVRegister<int8_t>(code);
1002   }
1003   VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) {
1004     return ReadBRegister(code);
1005   }
1006 
1007   vixl::internal::SimFloat16 ReadHRegister(unsigned code) const {
1008     return RawbitsToFloat16(ReadHRegisterBits(code));
1009   }
1010   VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) {
1011     return Float16ToRawbits(ReadHRegister(code));
1012   }
1013 
1014   uint16_t ReadHRegisterBits(unsigned code) const {
1015     return ReadVRegister<uint16_t>(code);
1016   }
1017 
1018   float ReadSRegister(unsigned code) const {
1019     return ReadVRegister<float>(code);
1020   }
1021   VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) {
1022     return ReadSRegister(code);
1023   }
1024 
1025   uint32_t ReadSRegisterBits(unsigned code) const {
1026     return ReadVRegister<uint32_t>(code);
1027   }
1028   VIXL_DEPRECATED("ReadSRegisterBits",
1029                   uint32_t sreg_bits(unsigned code) const) {
1030     return ReadSRegisterBits(code);
1031   }
1032 
1033   double ReadDRegister(unsigned code) const {
1034     return ReadVRegister<double>(code);
1035   }
1036   VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) {
1037     return ReadDRegister(code);
1038   }
1039 
1040   uint64_t ReadDRegisterBits(unsigned code) const {
1041     return ReadVRegister<uint64_t>(code);
1042   }
1043   VIXL_DEPRECATED("ReadDRegisterBits",
1044                   uint64_t dreg_bits(unsigned code) const) {
1045     return ReadDRegisterBits(code);
1046   }
1047 
1048   qreg_t ReadQRegister(unsigned code) const {
1049     return ReadVRegister<qreg_t>(code);
1050   }
1051   VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) {
1052     return ReadQRegister(code);
1053   }
1054 
1055   // As above, with parameterized size and return type. The value is
1056   // either zero-extended or truncated to fit, as required.
1057   template <typename T>
1058   T ReadVRegister(unsigned size, unsigned code) const {
1059     uint64_t raw = 0;
1060     T result;
1061 
1062     switch (size) {
1063       case kSRegSize:
1064         raw = ReadVRegister<uint32_t>(code);
1065         break;
1066       case kDRegSize:
1067         raw = ReadVRegister<uint64_t>(code);
1068         break;
1069       default:
1070         VIXL_UNREACHABLE();
1071         break;
1072     }
1073 
1074     VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
1075     // Copy the result and truncate to fit. This assumes a little-endian host.
1076     memcpy(&result, &raw, sizeof(result));
1077     return result;
1078   }
1079   template <typename T>
1080   VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) {
1081     return ReadVRegister<T>(size, code);
1082   }
1083 
1084   SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; }
1085   VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) {
1086     return ReadVRegister(code);
1087   }
1088 
1089   // Basic accessor: Write the specified value.
1090   template <typename T>
1091   void WriteVRegister(unsigned code,
1092                       T value,
1093                       RegLogMode log_mode = LogRegWrites) {
1094     VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) ||
1095                        (sizeof(value) == kHRegSizeInBytes) ||
1096                        (sizeof(value) == kSRegSizeInBytes) ||
1097                        (sizeof(value) == kDRegSizeInBytes) ||
1098                        (sizeof(value) == kQRegSizeInBytes));
1099     VIXL_ASSERT(code < kNumberOfVRegisters);
1100     vregisters_[code].Write(value);
1101 
1102     if (log_mode == LogRegWrites) {
1103       LogVRegister(code, GetPrintRegisterFormat(value));
1104     }
1105   }
1106   template <typename T>
1107   VIXL_DEPRECATED("WriteVRegister",
1108                   void set_vreg(unsigned code,
1109                                 T value,
1110                                 RegLogMode log_mode = LogRegWrites)) {
1111     WriteVRegister(code, value, log_mode);
1112   }
1113 
1114   // Common specialized accessors for the WriteVRegister() template.
1115   void WriteBRegister(unsigned code,
1116                       int8_t value,
1117                       RegLogMode log_mode = LogRegWrites) {
1118     WriteVRegister(code, value, log_mode);
1119   }
1120   VIXL_DEPRECATED("WriteBRegister",
1121                   void set_breg(unsigned code,
1122                                 int8_t value,
1123                                 RegLogMode log_mode = LogRegWrites)) {
1124     return WriteBRegister(code, value, log_mode);
1125   }
1126 
1127   void WriteHRegister(unsigned code,
1128                       vixl::internal::SimFloat16 value,
1129                       RegLogMode log_mode = LogRegWrites) {
1130     WriteVRegister(code, Float16ToRawbits(value), log_mode);
1131   }
1132 
1133   void WriteHRegister(unsigned code,
1134                       int16_t value,
1135                       RegLogMode log_mode = LogRegWrites) {
1136     WriteVRegister(code, value, log_mode);
1137   }
1138   VIXL_DEPRECATED("WriteHRegister",
1139                   void set_hreg(unsigned code,
1140                                 int16_t value,
1141                                 RegLogMode log_mode = LogRegWrites)) {
1142     return WriteHRegister(code, value, log_mode);
1143   }
1144 
1145   void WriteSRegister(unsigned code,
1146                       float value,
1147                       RegLogMode log_mode = LogRegWrites) {
1148     WriteVRegister(code, value, log_mode);
1149   }
1150   VIXL_DEPRECATED("WriteSRegister",
1151                   void set_sreg(unsigned code,
1152                                 float value,
1153                                 RegLogMode log_mode = LogRegWrites)) {
1154     WriteSRegister(code, value, log_mode);
1155   }
1156 
1157   void WriteSRegisterBits(unsigned code,
1158                           uint32_t value,
1159                           RegLogMode log_mode = LogRegWrites) {
1160     WriteVRegister(code, value, log_mode);
1161   }
1162   VIXL_DEPRECATED("WriteSRegisterBits",
1163                   void set_sreg_bits(unsigned code,
1164                                      uint32_t value,
1165                                      RegLogMode log_mode = LogRegWrites)) {
1166     WriteSRegisterBits(code, value, log_mode);
1167   }
1168 
1169   void WriteDRegister(unsigned code,
1170                       double value,
1171                       RegLogMode log_mode = LogRegWrites) {
1172     WriteVRegister(code, value, log_mode);
1173   }
1174   VIXL_DEPRECATED("WriteDRegister",
1175                   void set_dreg(unsigned code,
1176                                 double value,
1177                                 RegLogMode log_mode = LogRegWrites)) {
1178     WriteDRegister(code, value, log_mode);
1179   }
1180 
1181   void WriteDRegisterBits(unsigned code,
1182                           uint64_t value,
1183                           RegLogMode log_mode = LogRegWrites) {
1184     WriteVRegister(code, value, log_mode);
1185   }
1186   VIXL_DEPRECATED("WriteDRegisterBits",
1187                   void set_dreg_bits(unsigned code,
1188                                      uint64_t value,
1189                                      RegLogMode log_mode = LogRegWrites)) {
1190     WriteDRegisterBits(code, value, log_mode);
1191   }
1192 
1193   void WriteQRegister(unsigned code,
1194                       qreg_t value,
1195                       RegLogMode log_mode = LogRegWrites) {
1196     WriteVRegister(code, value, log_mode);
1197   }
1198   VIXL_DEPRECATED("WriteQRegister",
1199                   void set_qreg(unsigned code,
1200                                 qreg_t value,
1201                                 RegLogMode log_mode = LogRegWrites)) {
1202     WriteQRegister(code, value, log_mode);
1203   }
1204 
1205   template <typename T>
1206   T ReadRegister(Register reg) const {
1207     return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister);
1208   }
1209 
1210   template <typename T>
1211   void WriteRegister(Register reg,
1212                      T value,
1213                      RegLogMode log_mode = LogRegWrites) {
1214     WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister);
1215   }
1216 
1217   template <typename T>
1218   T ReadVRegister(VRegister vreg) const {
1219     return ReadVRegister<T>(vreg.GetCode());
1220   }
1221 
1222   template <typename T>
1223   void WriteVRegister(VRegister vreg,
1224                       T value,
1225                       RegLogMode log_mode = LogRegWrites) {
1226     WriteVRegister<T>(vreg.GetCode(), value, log_mode);
1227   }
1228 
1229   template <typename T>
1230   T ReadCPURegister(CPURegister reg) const {
1231     if (reg.IsVRegister()) {
1232       return ReadVRegister<T>(VRegister(reg));
1233     } else {
1234       return ReadRegister<T>(Register(reg));
1235     }
1236   }
1237 
1238   template <typename T>
1239   void WriteCPURegister(CPURegister reg,
1240                         T value,
1241                         RegLogMode log_mode = LogRegWrites) {
1242     if (reg.IsVRegister()) {
1243       WriteVRegister<T>(VRegister(reg), value, log_mode);
1244     } else {
1245       WriteRegister<T>(Register(reg), value, log_mode);
1246     }
1247   }
1248 
1249   uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
1250 
1251   template <typename T>
1252   T ReadGenericOperand(GenericOperand operand) const {
1253     if (operand.IsCPURegister()) {
1254       return ReadCPURegister<T>(operand.GetCPURegister());
1255     } else {
1256       VIXL_ASSERT(operand.IsMemOperand());
1257       return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
1258     }
1259   }
1260 
1261   template <typename T>
1262   void WriteGenericOperand(GenericOperand operand,
1263                            T value,
1264                            RegLogMode log_mode = LogRegWrites) {
1265     if (operand.IsCPURegister()) {
1266       WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode);
1267     } else {
1268       VIXL_ASSERT(operand.IsMemOperand());
1269       Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value);
1270     }
1271   }
1272 
1273   bool ReadN() const { return nzcv_.GetN() != 0; }
1274   VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); }
1275 
1276   bool ReadZ() const { return nzcv_.GetZ() != 0; }
1277   VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); }
1278 
1279   bool ReadC() const { return nzcv_.GetC() != 0; }
1280   VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); }
1281 
1282   bool ReadV() const { return nzcv_.GetV() != 0; }
1283   VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); }
1284 
1285   SimSystemRegister& ReadNzcv() { return nzcv_; }
1286   VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); }
1287 
1288   // TODO: Find a way to make the fpcr_ members return the proper types, so
1289   // these accessors are not necessary.
1290   FPRounding ReadRMode() const {
1291     return static_cast<FPRounding>(fpcr_.GetRMode());
1292   }
1293   VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); }
1294 
1295   UseDefaultNaN ReadDN() const {
1296     return fpcr_.GetDN() != 0 ? kUseDefaultNaN : kIgnoreDefaultNaN;
1297   }
1298 
1299   VIXL_DEPRECATED("ReadDN", bool DN()) {
1300     return ReadDN() == kUseDefaultNaN ? true : false;
1301   }
1302 
1303   SimSystemRegister& ReadFpcr() { return fpcr_; }
1304   VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); }
1305 
1306   // Specify relevant register formats for Print(V)Register and related helpers.
1307   enum PrintRegisterFormat {
1308     // The lane size.
1309     kPrintRegLaneSizeB = 0 << 0,
1310     kPrintRegLaneSizeH = 1 << 0,
1311     kPrintRegLaneSizeS = 2 << 0,
1312     kPrintRegLaneSizeW = kPrintRegLaneSizeS,
1313     kPrintRegLaneSizeD = 3 << 0,
1314     kPrintRegLaneSizeX = kPrintRegLaneSizeD,
1315     kPrintRegLaneSizeQ = 4 << 0,
1316 
1317     kPrintRegLaneSizeOffset = 0,
1318     kPrintRegLaneSizeMask = 7 << 0,
1319 
1320     // The lane count.
1321     kPrintRegAsScalar = 0,
1322     kPrintRegAsDVector = 1 << 3,
1323     kPrintRegAsQVector = 2 << 3,
1324 
1325     kPrintRegAsVectorMask = 3 << 3,
1326 
1327     // Indicate floating-point format lanes. (This flag is only supported for
1328     // S-, H-, and D-sized lanes.)
1329     kPrintRegAsFP = 1 << 5,
1330 
1331     // Supported combinations.
1332 
1333     kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
1334     kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
1335     kPrintHReg = kPrintRegLaneSizeH | kPrintRegAsScalar | kPrintRegAsFP,
1336     kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1337     kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1338 
1339     kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
1340     kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
1341     kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
1342     kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
1343     kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
1344     kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
1345     kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
1346     kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
1347     kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
1348     kPrintReg1HFP = kPrintRegLaneSizeH | kPrintRegAsScalar | kPrintRegAsFP,
1349     kPrintReg4HFP = kPrintRegLaneSizeH | kPrintRegAsDVector | kPrintRegAsFP,
1350     kPrintReg8HFP = kPrintRegLaneSizeH | kPrintRegAsQVector | kPrintRegAsFP,
1351     kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1352     kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
1353     kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
1354     kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
1355     kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
1356     kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1357     kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
1358     kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
1359   };
1360 
1361   unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
1362     return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
1363   }
1364 
1365   unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
1366     return 1 << GetPrintRegLaneSizeInBytesLog2(format);
1367   }
1368 
1369   unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
1370     if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2;
1371     if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2;
1372 
1373     // Scalar types.
1374     return GetPrintRegLaneSizeInBytesLog2(format);
1375   }
1376 
1377   unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
1378     return 1 << GetPrintRegSizeInBytesLog2(format);
1379   }
1380 
1381   unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
1382     unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
1383     unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
1384     VIXL_ASSERT(reg_size_log2 >= lane_size_log2);
1385     return 1 << (reg_size_log2 - lane_size_log2);
1386   }
1387 
1388   PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size,
1389                                                     unsigned lane_size);
1390 
1391   PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) {
1392     return GetPrintRegisterFormatForSize(size, size);
1393   }
1394 
1395   PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) {
1396     switch (size) {
1397       default:
1398         VIXL_UNREACHABLE();
1399         return kPrintDReg;
1400       case kDRegSizeInBytes:
1401         return kPrintDReg;
1402       case kSRegSizeInBytes:
1403         return kPrintSReg;
1404       case kHRegSizeInBytes:
1405         return kPrintHReg;
1406     }
1407   }
1408 
1409   PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
1410     if ((GetPrintRegLaneSizeInBytes(format) == kHRegSizeInBytes) ||
1411         (GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) ||
1412         (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) {
1413       return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
1414     }
1415     return format;
1416   }
1417 
1418   template <typename T>
1419   PrintRegisterFormat GetPrintRegisterFormat(T value) {
1420     return GetPrintRegisterFormatForSize(sizeof(value));
1421   }
1422 
1423   PrintRegisterFormat GetPrintRegisterFormat(double value) {
1424     VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes);
1425     return GetPrintRegisterFormatForSizeFP(sizeof(value));
1426   }
1427 
1428   PrintRegisterFormat GetPrintRegisterFormat(float value) {
1429     VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes);
1430     return GetPrintRegisterFormatForSizeFP(sizeof(value));
1431   }
1432 
1433   PrintRegisterFormat GetPrintRegisterFormat(Float16 value) {
1434     VIXL_STATIC_ASSERT(sizeof(Float16ToRawbits(value)) == kHRegSizeInBytes);
1435     return GetPrintRegisterFormatForSizeFP(sizeof(Float16ToRawbits(value)));
1436   }
1437 
1438   PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
1439   PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
1440 
1441   // Print all registers of the specified types.
1442   void PrintRegisters();
1443   void PrintVRegisters();
1444   void PrintSystemRegisters();
1445 
1446   // As above, but only print the registers that have been updated.
1447   void PrintWrittenRegisters();
1448   void PrintWrittenVRegisters();
1449 
1450   // As above, but respect LOG_REG and LOG_VREG.
1451   void LogWrittenRegisters() {
1452     if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters();
1453   }
1454   void LogWrittenVRegisters() {
1455     if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters();
1456   }
1457   void LogAllWrittenRegisters() {
1458     LogWrittenRegisters();
1459     LogWrittenVRegisters();
1460   }
1461 
1462   // Print individual register values (after update).
1463   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
1464   void PrintVRegister(unsigned code, PrintRegisterFormat format);
1465   void PrintSystemRegister(SystemRegister id);
1466   void PrintTakenBranch(const Instruction* target);
1467 
1468   // Like Print* (above), but respect GetTraceParameters().
1469   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
1470     if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode);
1471   }
1472   void LogVRegister(unsigned code, PrintRegisterFormat format) {
1473     if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format);
1474   }
1475   void LogSystemRegister(SystemRegister id) {
1476     if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id);
1477   }
1478   void LogTakenBranch(const Instruction* target) {
1479     if (GetTraceParameters() & LOG_BRANCH) PrintTakenBranch(target);
1480   }
1481 
1482   // Print memory accesses.
1483   void PrintRead(uintptr_t address,
1484                  unsigned reg_code,
1485                  PrintRegisterFormat format);
1486   void PrintWrite(uintptr_t address,
1487                   unsigned reg_code,
1488                   PrintRegisterFormat format);
1489   void PrintVRead(uintptr_t address,
1490                   unsigned reg_code,
1491                   PrintRegisterFormat format,
1492                   unsigned lane);
1493   void PrintVWrite(uintptr_t address,
1494                    unsigned reg_code,
1495                    PrintRegisterFormat format,
1496                    unsigned lane);
1497 
1498   // Like Print* (above), but respect GetTraceParameters().
1499   void LogRead(uintptr_t address,
1500                unsigned reg_code,
1501                PrintRegisterFormat format) {
1502     if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format);
1503   }
1504   void LogWrite(uintptr_t address,
1505                 unsigned reg_code,
1506                 PrintRegisterFormat format) {
1507     if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
1508   }
1509   void LogVRead(uintptr_t address,
1510                 unsigned reg_code,
1511                 PrintRegisterFormat format,
1512                 unsigned lane = 0) {
1513     if (GetTraceParameters() & LOG_VREGS) {
1514       PrintVRead(address, reg_code, format, lane);
1515     }
1516   }
1517   void LogVWrite(uintptr_t address,
1518                  unsigned reg_code,
1519                  PrintRegisterFormat format,
1520                  unsigned lane = 0) {
1521     if (GetTraceParameters() & LOG_WRITE) {
1522       PrintVWrite(address, reg_code, format, lane);
1523     }
1524   }
1525 
1526   // Helper functions for register tracing.
1527   void PrintRegisterRawHelper(unsigned code,
1528                               Reg31Mode r31mode,
1529                               int size_in_bytes = kXRegSizeInBytes);
1530   void PrintVRegisterRawHelper(unsigned code,
1531                                int bytes = kQRegSizeInBytes,
1532                                int lsb = 0);
1533   void PrintVRegisterFPHelper(unsigned code,
1534                               unsigned lane_size_in_bytes,
1535                               int lane_count = 1,
1536                               int rightmost_lane = 0);
1537 
1538   VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
1539   void DoTrace(const Instruction* instr);
1540   void DoLog(const Instruction* instr);
1541 
1542   static const char* WRegNameForCode(unsigned code,
1543                                      Reg31Mode mode = Reg31IsZeroRegister);
1544   static const char* XRegNameForCode(unsigned code,
1545                                      Reg31Mode mode = Reg31IsZeroRegister);
1546   static const char* HRegNameForCode(unsigned code);
1547   static const char* SRegNameForCode(unsigned code);
1548   static const char* DRegNameForCode(unsigned code);
1549   static const char* VRegNameForCode(unsigned code);
1550 
1551   bool IsColouredTrace() const { return coloured_trace_; }
1552   VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) {
1553     return IsColouredTrace();
1554   }
1555 
1556   void SetColouredTrace(bool value);
1557   VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) {
1558     SetColouredTrace(value);
1559   }
1560 
1561   // Values for traces parameters defined in simulator-constants-aarch64.h in
1562   // enum TraceParameters.
1563   int GetTraceParameters() const { return trace_parameters_; }
1564   VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) {
1565     return GetTraceParameters();
1566   }
1567 
1568   void SetTraceParameters(int parameters);
1569   VIXL_DEPRECATED("SetTraceParameters",
1570                   void set_trace_parameters(int parameters)) {
1571     SetTraceParameters(parameters);
1572   }
1573 
1574   void SetInstructionStats(bool value);
1575   VIXL_DEPRECATED("SetInstructionStats",
1576                   void set_instruction_stats(bool value)) {
1577     SetInstructionStats(value);
1578   }
1579 
1580   // Clear the simulated local monitor to force the next store-exclusive
1581   // instruction to fail.
1582   void ClearLocalMonitor() { local_monitor_.Clear(); }
1583 
1584   void SilenceExclusiveAccessWarning() {
1585     print_exclusive_access_warning_ = false;
1586   }
1587 
1588   enum PointerType { kDataPointer, kInstructionPointer };
1589 
1590   struct PACKey {
1591     uint64_t high;
1592     uint64_t low;
1593     int number;
1594   };
1595 
1596   // Current implementation is that all pointers are tagged.
1597   bool HasTBI(uint64_t ptr, PointerType type) {
1598     USE(ptr, type);
1599     return true;
1600   }
1601 
1602   // Current implementation uses 48-bit virtual addresses.
1603   int GetBottomPACBit(uint64_t ptr, int ttbr) {
1604     USE(ptr, ttbr);
1605     VIXL_ASSERT((ttbr == 0) || (ttbr == 1));
1606     return 48;
1607   }
1608 
1609   // The top PAC bit is 55 for the purposes of relative bit fields with TBI,
1610   // however bit 55 is the TTBR bit regardless of TBI so isn't part of the PAC
1611   // codes in pointers.
1612   int GetTopPACBit(uint64_t ptr, PointerType type) {
1613     return HasTBI(ptr, type) ? 55 : 63;
1614   }
1615 
1616   // Armv8.3 Pointer authentication helpers.
1617   uint64_t CalculatePACMask(uint64_t ptr, PointerType type, int ext_bit);
1618   uint64_t ComputePAC(uint64_t data, uint64_t context, PACKey key);
1619   uint64_t AuthPAC(uint64_t ptr,
1620                    uint64_t context,
1621                    PACKey key,
1622                    PointerType type);
1623   uint64_t AddPAC(uint64_t ptr, uint64_t context, PACKey key, PointerType type);
1624   uint64_t StripPAC(uint64_t ptr, PointerType type);
1625 
1626   // The common CPUFeatures interface with the set of available features.
1627 
1628   CPUFeatures* GetCPUFeatures() {
1629     return cpu_features_auditor_.GetCPUFeatures();
1630   }
1631 
1632   void SetCPUFeatures(const CPUFeatures& cpu_features) {
1633     cpu_features_auditor_.SetCPUFeatures(cpu_features);
1634   }
1635 
1636   // The set of features that the simulator has encountered.
1637   const CPUFeatures& GetSeenFeatures() {
1638     return cpu_features_auditor_.GetSeenFeatures();
1639   }
1640   void ResetSeenFeatures() { cpu_features_auditor_.ResetSeenFeatures(); }
1641 
1642 // Runtime call emulation support.
1643 // It requires VIXL's ABI features, and C++11 or greater.
1644 // Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
1645 // in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
1646 #if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
1647     (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
1648 
1649 #define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
1650 
1651 // The implementation of the runtime call helpers require the functionality
1652 // provided by `std::index_sequence`. It is only available from C++14, but
1653 // we want runtime call simulation to work from C++11, so we emulate if
1654 // necessary.
1655 #if __cplusplus >= 201402L
1656   template <std::size_t... I>
1657   using local_index_sequence = std::index_sequence<I...>;
1658   template <typename... P>
1659   using __local_index_sequence_for = std::index_sequence_for<P...>;
1660 #else
1661   // Emulate the behaviour of `std::index_sequence` and
1662   // `std::index_sequence_for`.
1663   // Naming follow the `std` names, prefixed with `emulated_`.
1664   template <size_t... I>
1665   struct emulated_index_sequence {};
1666 
1667   // A recursive template to create a sequence of indexes.
1668   // The base case (for `N == 0`) is declared outside of the class scope, as
1669   // required by C++.
1670   template <std::size_t N, size_t... I>
1671   struct emulated_make_index_sequence_helper
1672       : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
1673 
1674   template <std::size_t N>
1675   struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
1676   };
1677 
1678   template <typename... P>
1679   struct emulated_index_sequence_for
1680       : emulated_make_index_sequence<sizeof...(P)> {};
1681 
1682   template <std::size_t... I>
1683   using local_index_sequence = emulated_index_sequence<I...>;
1684   template <typename... P>
1685   using __local_index_sequence_for = emulated_index_sequence_for<P...>;
1686 #endif
1687 
1688   // Expand the argument tuple and perform the call.
1689   template <typename R, typename... P, std::size_t... I>
1690   R DoRuntimeCall(R (*function)(P...),
1691                   std::tuple<P...> arguments,
1692                   local_index_sequence<I...>) {
1693     return function(std::get<I>(arguments)...);
1694   }
1695 
1696   template <typename R, typename... P>
1697   void RuntimeCallNonVoid(R (*function)(P...)) {
1698     ABI abi;
1699     std::tuple<P...> argument_operands{
1700         ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1701     R return_value = DoRuntimeCall(function,
1702                                    argument_operands,
1703                                    __local_index_sequence_for<P...>{});
1704     WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
1705   }
1706 
1707   template <typename R, typename... P>
1708   void RuntimeCallVoid(R (*function)(P...)) {
1709     ABI abi;
1710     std::tuple<P...> argument_operands{
1711         ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1712     DoRuntimeCall(function,
1713                   argument_operands,
1714                   __local_index_sequence_for<P...>{});
1715   }
1716 
1717   // We use `struct` for `void` return type specialisation.
1718   template <typename R, typename... P>
1719   struct RuntimeCallStructHelper {
1720     static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1721       R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
1722       simulator->RuntimeCallNonVoid(function);
1723     }
1724   };
1725 
1726   // Partial specialization when the return type is `void`.
1727   template <typename... P>
1728   struct RuntimeCallStructHelper<void, P...> {
1729     static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1730       void (*function)(P...) =
1731           reinterpret_cast<void (*)(P...)>(function_pointer);
1732       simulator->RuntimeCallVoid(function);
1733     }
1734   };
1735 #endif
1736 
1737  protected:
1738   const char* clr_normal;
1739   const char* clr_flag_name;
1740   const char* clr_flag_value;
1741   const char* clr_reg_name;
1742   const char* clr_reg_value;
1743   const char* clr_vreg_name;
1744   const char* clr_vreg_value;
1745   const char* clr_memory_address;
1746   const char* clr_warning;
1747   const char* clr_warning_message;
1748   const char* clr_printf;
1749   const char* clr_branch_marker;
1750 
1751   // Simulation helpers ------------------------------------
1752   bool ConditionPassed(Condition cond) {
1753     switch (cond) {
1754       case eq:
1755         return ReadZ();
1756       case ne:
1757         return !ReadZ();
1758       case hs:
1759         return ReadC();
1760       case lo:
1761         return !ReadC();
1762       case mi:
1763         return ReadN();
1764       case pl:
1765         return !ReadN();
1766       case vs:
1767         return ReadV();
1768       case vc:
1769         return !ReadV();
1770       case hi:
1771         return ReadC() && !ReadZ();
1772       case ls:
1773         return !(ReadC() && !ReadZ());
1774       case ge:
1775         return ReadN() == ReadV();
1776       case lt:
1777         return ReadN() != ReadV();
1778       case gt:
1779         return !ReadZ() && (ReadN() == ReadV());
1780       case le:
1781         return !(!ReadZ() && (ReadN() == ReadV()));
1782       case nv:
1783         VIXL_FALLTHROUGH();
1784       case al:
1785         return true;
1786       default:
1787         VIXL_UNREACHABLE();
1788         return false;
1789     }
1790   }
1791 
1792   bool ConditionPassed(Instr cond) {
1793     return ConditionPassed(static_cast<Condition>(cond));
1794   }
1795 
1796   bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1797 
1798   void AddSubHelper(const Instruction* instr, int64_t op2);
1799   uint64_t AddWithCarry(unsigned reg_size,
1800                         bool set_flags,
1801                         uint64_t left,
1802                         uint64_t right,
1803                         int carry_in = 0);
1804   void LogicalHelper(const Instruction* instr, int64_t op2);
1805   void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
1806   void LoadStoreHelper(const Instruction* instr,
1807                        int64_t offset,
1808                        AddrMode addrmode);
1809   void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
1810   template <typename T>
1811   void CompareAndSwapHelper(const Instruction* instr);
1812   template <typename T>
1813   void CompareAndSwapPairHelper(const Instruction* instr);
1814   template <typename T>
1815   void AtomicMemorySimpleHelper(const Instruction* instr);
1816   template <typename T>
1817   void AtomicMemorySwapHelper(const Instruction* instr);
1818   template <typename T>
1819   void LoadAcquireRCpcHelper(const Instruction* instr);
1820   uintptr_t AddressModeHelper(unsigned addr_reg,
1821                               int64_t offset,
1822                               AddrMode addrmode);
1823   void NEONLoadStoreMultiStructHelper(const Instruction* instr,
1824                                       AddrMode addr_mode);
1825   void NEONLoadStoreSingleStructHelper(const Instruction* instr,
1826                                        AddrMode addr_mode);
1827 
1828   uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; }
1829 
1830   template <typename T>
1831   T* AddressUntag(T* address) {
1832     uintptr_t address_raw = reinterpret_cast<uintptr_t>(address);
1833     return reinterpret_cast<T*>(AddressUntag(address_raw));
1834   }
1835 
1836   int64_t ShiftOperand(unsigned reg_size,
1837                        int64_t value,
1838                        Shift shift_type,
1839                        unsigned amount) const;
1840   int64_t ExtendValue(unsigned reg_width,
1841                       int64_t value,
1842                       Extend extend_type,
1843                       unsigned left_shift = 0) const;
1844   uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const;
1845 
1846   void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1847   void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
1848   void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1849   void ld2(VectorFormat vform,
1850            LogicVRegister dst1,
1851            LogicVRegister dst2,
1852            uint64_t addr);
1853   void ld2(VectorFormat vform,
1854            LogicVRegister dst1,
1855            LogicVRegister dst2,
1856            int index,
1857            uint64_t addr);
1858   void ld2r(VectorFormat vform,
1859             LogicVRegister dst1,
1860             LogicVRegister dst2,
1861             uint64_t addr);
1862   void ld3(VectorFormat vform,
1863            LogicVRegister dst1,
1864            LogicVRegister dst2,
1865            LogicVRegister dst3,
1866            uint64_t addr);
1867   void ld3(VectorFormat vform,
1868            LogicVRegister dst1,
1869            LogicVRegister dst2,
1870            LogicVRegister dst3,
1871            int index,
1872            uint64_t addr);
1873   void ld3r(VectorFormat vform,
1874             LogicVRegister dst1,
1875             LogicVRegister dst2,
1876             LogicVRegister dst3,
1877             uint64_t addr);
1878   void ld4(VectorFormat vform,
1879            LogicVRegister dst1,
1880            LogicVRegister dst2,
1881            LogicVRegister dst3,
1882            LogicVRegister dst4,
1883            uint64_t addr);
1884   void ld4(VectorFormat vform,
1885            LogicVRegister dst1,
1886            LogicVRegister dst2,
1887            LogicVRegister dst3,
1888            LogicVRegister dst4,
1889            int index,
1890            uint64_t addr);
1891   void ld4r(VectorFormat vform,
1892             LogicVRegister dst1,
1893             LogicVRegister dst2,
1894             LogicVRegister dst3,
1895             LogicVRegister dst4,
1896             uint64_t addr);
1897   void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
1898   void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
1899   void st2(VectorFormat vform,
1900            LogicVRegister src,
1901            LogicVRegister src2,
1902            uint64_t addr);
1903   void st2(VectorFormat vform,
1904            LogicVRegister src,
1905            LogicVRegister src2,
1906            int index,
1907            uint64_t addr);
1908   void st3(VectorFormat vform,
1909            LogicVRegister src,
1910            LogicVRegister src2,
1911            LogicVRegister src3,
1912            uint64_t addr);
1913   void st3(VectorFormat vform,
1914            LogicVRegister src,
1915            LogicVRegister src2,
1916            LogicVRegister src3,
1917            int index,
1918            uint64_t addr);
1919   void st4(VectorFormat vform,
1920            LogicVRegister src,
1921            LogicVRegister src2,
1922            LogicVRegister src3,
1923            LogicVRegister src4,
1924            uint64_t addr);
1925   void st4(VectorFormat vform,
1926            LogicVRegister src,
1927            LogicVRegister src2,
1928            LogicVRegister src3,
1929            LogicVRegister src4,
1930            int index,
1931            uint64_t addr);
1932   LogicVRegister cmp(VectorFormat vform,
1933                      LogicVRegister dst,
1934                      const LogicVRegister& src1,
1935                      const LogicVRegister& src2,
1936                      Condition cond);
1937   LogicVRegister cmp(VectorFormat vform,
1938                      LogicVRegister dst,
1939                      const LogicVRegister& src1,
1940                      int imm,
1941                      Condition cond);
1942   LogicVRegister cmptst(VectorFormat vform,
1943                         LogicVRegister dst,
1944                         const LogicVRegister& src1,
1945                         const LogicVRegister& src2);
1946   LogicVRegister add(VectorFormat vform,
1947                      LogicVRegister dst,
1948                      const LogicVRegister& src1,
1949                      const LogicVRegister& src2);
1950   LogicVRegister addp(VectorFormat vform,
1951                       LogicVRegister dst,
1952                       const LogicVRegister& src1,
1953                       const LogicVRegister& src2);
1954   LogicVRegister mla(VectorFormat vform,
1955                      LogicVRegister dst,
1956                      const LogicVRegister& src1,
1957                      const LogicVRegister& src2);
1958   LogicVRegister mls(VectorFormat vform,
1959                      LogicVRegister dst,
1960                      const LogicVRegister& src1,
1961                      const LogicVRegister& src2);
1962   LogicVRegister mul(VectorFormat vform,
1963                      LogicVRegister dst,
1964                      const LogicVRegister& src1,
1965                      const LogicVRegister& src2);
1966   LogicVRegister mul(VectorFormat vform,
1967                      LogicVRegister dst,
1968                      const LogicVRegister& src1,
1969                      const LogicVRegister& src2,
1970                      int index);
1971   LogicVRegister mla(VectorFormat vform,
1972                      LogicVRegister dst,
1973                      const LogicVRegister& src1,
1974                      const LogicVRegister& src2,
1975                      int index);
1976   LogicVRegister mls(VectorFormat vform,
1977                      LogicVRegister dst,
1978                      const LogicVRegister& src1,
1979                      const LogicVRegister& src2,
1980                      int index);
1981   LogicVRegister pmul(VectorFormat vform,
1982                       LogicVRegister dst,
1983                       const LogicVRegister& src1,
1984                       const LogicVRegister& src2);
1985 
1986   typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
1987                                                    LogicVRegister dst,
1988                                                    const LogicVRegister& src1,
1989                                                    const LogicVRegister& src2,
1990                                                    int index);
1991   LogicVRegister fmul(VectorFormat vform,
1992                       LogicVRegister dst,
1993                       const LogicVRegister& src1,
1994                       const LogicVRegister& src2,
1995                       int index);
1996   LogicVRegister fmla(VectorFormat vform,
1997                       LogicVRegister dst,
1998                       const LogicVRegister& src1,
1999                       const LogicVRegister& src2,
2000                       int index);
2001   LogicVRegister fmls(VectorFormat vform,
2002                       LogicVRegister dst,
2003                       const LogicVRegister& src1,
2004                       const LogicVRegister& src2,
2005                       int index);
2006   LogicVRegister fmulx(VectorFormat vform,
2007                        LogicVRegister dst,
2008                        const LogicVRegister& src1,
2009                        const LogicVRegister& src2,
2010                        int index);
2011   LogicVRegister smull(VectorFormat vform,
2012                        LogicVRegister dst,
2013                        const LogicVRegister& src1,
2014                        const LogicVRegister& src2,
2015                        int index);
2016   LogicVRegister smull2(VectorFormat vform,
2017                         LogicVRegister dst,
2018                         const LogicVRegister& src1,
2019                         const LogicVRegister& src2,
2020                         int index);
2021   LogicVRegister umull(VectorFormat vform,
2022                        LogicVRegister dst,
2023                        const LogicVRegister& src1,
2024                        const LogicVRegister& src2,
2025                        int index);
2026   LogicVRegister umull2(VectorFormat vform,
2027                         LogicVRegister dst,
2028                         const LogicVRegister& src1,
2029                         const LogicVRegister& src2,
2030                         int index);
2031   LogicVRegister smlal(VectorFormat vform,
2032                        LogicVRegister dst,
2033                        const LogicVRegister& src1,
2034                        const LogicVRegister& src2,
2035                        int index);
2036   LogicVRegister smlal2(VectorFormat vform,
2037                         LogicVRegister dst,
2038                         const LogicVRegister& src1,
2039                         const LogicVRegister& src2,
2040                         int index);
2041   LogicVRegister umlal(VectorFormat vform,
2042                        LogicVRegister dst,
2043                        const LogicVRegister& src1,
2044                        const LogicVRegister& src2,
2045                        int index);
2046   LogicVRegister umlal2(VectorFormat vform,
2047                         LogicVRegister dst,
2048                         const LogicVRegister& src1,
2049                         const LogicVRegister& src2,
2050                         int index);
2051   LogicVRegister smlsl(VectorFormat vform,
2052                        LogicVRegister dst,
2053                        const LogicVRegister& src1,
2054                        const LogicVRegister& src2,
2055                        int index);
2056   LogicVRegister smlsl2(VectorFormat vform,
2057                         LogicVRegister dst,
2058                         const LogicVRegister& src1,
2059                         const LogicVRegister& src2,
2060                         int index);
2061   LogicVRegister umlsl(VectorFormat vform,
2062                        LogicVRegister dst,
2063                        const LogicVRegister& src1,
2064                        const LogicVRegister& src2,
2065                        int index);
2066   LogicVRegister umlsl2(VectorFormat vform,
2067                         LogicVRegister dst,
2068                         const LogicVRegister& src1,
2069                         const LogicVRegister& src2,
2070                         int index);
2071   LogicVRegister sqdmull(VectorFormat vform,
2072                          LogicVRegister dst,
2073                          const LogicVRegister& src1,
2074                          const LogicVRegister& src2,
2075                          int index);
2076   LogicVRegister sqdmull2(VectorFormat vform,
2077                           LogicVRegister dst,
2078                           const LogicVRegister& src1,
2079                           const LogicVRegister& src2,
2080                           int index);
2081   LogicVRegister sqdmlal(VectorFormat vform,
2082                          LogicVRegister dst,
2083                          const LogicVRegister& src1,
2084                          const LogicVRegister& src2,
2085                          int index);
2086   LogicVRegister sqdmlal2(VectorFormat vform,
2087                           LogicVRegister dst,
2088                           const LogicVRegister& src1,
2089                           const LogicVRegister& src2,
2090                           int index);
2091   LogicVRegister sqdmlsl(VectorFormat vform,
2092                          LogicVRegister dst,
2093                          const LogicVRegister& src1,
2094                          const LogicVRegister& src2,
2095                          int index);
2096   LogicVRegister sqdmlsl2(VectorFormat vform,
2097                           LogicVRegister dst,
2098                           const LogicVRegister& src1,
2099                           const LogicVRegister& src2,
2100                           int index);
2101   LogicVRegister sqdmulh(VectorFormat vform,
2102                          LogicVRegister dst,
2103                          const LogicVRegister& src1,
2104                          const LogicVRegister& src2,
2105                          int index);
2106   LogicVRegister sqrdmulh(VectorFormat vform,
2107                           LogicVRegister dst,
2108                           const LogicVRegister& src1,
2109                           const LogicVRegister& src2,
2110                           int index);
2111   LogicVRegister sdot(VectorFormat vform,
2112                       LogicVRegister dst,
2113                       const LogicVRegister& src1,
2114                       const LogicVRegister& src2,
2115                       int index);
2116   LogicVRegister sqrdmlah(VectorFormat vform,
2117                           LogicVRegister dst,
2118                           const LogicVRegister& src1,
2119                           const LogicVRegister& src2,
2120                           int index);
2121   LogicVRegister udot(VectorFormat vform,
2122                       LogicVRegister dst,
2123                       const LogicVRegister& src1,
2124                       const LogicVRegister& src2,
2125                       int index);
2126   LogicVRegister sqrdmlsh(VectorFormat vform,
2127                           LogicVRegister dst,
2128                           const LogicVRegister& src1,
2129                           const LogicVRegister& src2,
2130                           int index);
2131   LogicVRegister sub(VectorFormat vform,
2132                      LogicVRegister dst,
2133                      const LogicVRegister& src1,
2134                      const LogicVRegister& src2);
2135   LogicVRegister and_(VectorFormat vform,
2136                       LogicVRegister dst,
2137                       const LogicVRegister& src1,
2138                       const LogicVRegister& src2);
2139   LogicVRegister orr(VectorFormat vform,
2140                      LogicVRegister dst,
2141                      const LogicVRegister& src1,
2142                      const LogicVRegister& src2);
2143   LogicVRegister orn(VectorFormat vform,
2144                      LogicVRegister dst,
2145                      const LogicVRegister& src1,
2146                      const LogicVRegister& src2);
2147   LogicVRegister eor(VectorFormat vform,
2148                      LogicVRegister dst,
2149                      const LogicVRegister& src1,
2150                      const LogicVRegister& src2);
2151   LogicVRegister bic(VectorFormat vform,
2152                      LogicVRegister dst,
2153                      const LogicVRegister& src1,
2154                      const LogicVRegister& src2);
2155   LogicVRegister bic(VectorFormat vform,
2156                      LogicVRegister dst,
2157                      const LogicVRegister& src,
2158                      uint64_t imm);
2159   LogicVRegister bif(VectorFormat vform,
2160                      LogicVRegister dst,
2161                      const LogicVRegister& src1,
2162                      const LogicVRegister& src2);
2163   LogicVRegister bit(VectorFormat vform,
2164                      LogicVRegister dst,
2165                      const LogicVRegister& src1,
2166                      const LogicVRegister& src2);
2167   LogicVRegister bsl(VectorFormat vform,
2168                      LogicVRegister dst,
2169                      const LogicVRegister& src1,
2170                      const LogicVRegister& src2);
2171   LogicVRegister cls(VectorFormat vform,
2172                      LogicVRegister dst,
2173                      const LogicVRegister& src);
2174   LogicVRegister clz(VectorFormat vform,
2175                      LogicVRegister dst,
2176                      const LogicVRegister& src);
2177   LogicVRegister cnt(VectorFormat vform,
2178                      LogicVRegister dst,
2179                      const LogicVRegister& src);
2180   LogicVRegister not_(VectorFormat vform,
2181                       LogicVRegister dst,
2182                       const LogicVRegister& src);
2183   LogicVRegister rbit(VectorFormat vform,
2184                       LogicVRegister dst,
2185                       const LogicVRegister& src);
2186   LogicVRegister rev(VectorFormat vform,
2187                      LogicVRegister dst,
2188                      const LogicVRegister& src,
2189                      int revSize);
2190   LogicVRegister rev16(VectorFormat vform,
2191                        LogicVRegister dst,
2192                        const LogicVRegister& src);
2193   LogicVRegister rev32(VectorFormat vform,
2194                        LogicVRegister dst,
2195                        const LogicVRegister& src);
2196   LogicVRegister rev64(VectorFormat vform,
2197                        LogicVRegister dst,
2198                        const LogicVRegister& src);
2199   LogicVRegister addlp(VectorFormat vform,
2200                        LogicVRegister dst,
2201                        const LogicVRegister& src,
2202                        bool is_signed,
2203                        bool do_accumulate);
2204   LogicVRegister saddlp(VectorFormat vform,
2205                         LogicVRegister dst,
2206                         const LogicVRegister& src);
2207   LogicVRegister uaddlp(VectorFormat vform,
2208                         LogicVRegister dst,
2209                         const LogicVRegister& src);
2210   LogicVRegister sadalp(VectorFormat vform,
2211                         LogicVRegister dst,
2212                         const LogicVRegister& src);
2213   LogicVRegister uadalp(VectorFormat vform,
2214                         LogicVRegister dst,
2215                         const LogicVRegister& src);
2216   LogicVRegister ext(VectorFormat vform,
2217                      LogicVRegister dst,
2218                      const LogicVRegister& src1,
2219                      const LogicVRegister& src2,
2220                      int index);
2221   template <typename T>
2222   LogicVRegister fcadd(VectorFormat vform,
2223                        LogicVRegister dst,
2224                        const LogicVRegister& src1,
2225                        const LogicVRegister& src2,
2226                        int rot);
2227   LogicVRegister fcadd(VectorFormat vform,
2228                        LogicVRegister dst,
2229                        const LogicVRegister& src1,
2230                        const LogicVRegister& src2,
2231                        int rot);
2232   template <typename T>
2233   LogicVRegister fcmla(VectorFormat vform,
2234                        LogicVRegister dst,
2235                        const LogicVRegister& src1,
2236                        const LogicVRegister& src2,
2237                        int index,
2238                        int rot);
2239   LogicVRegister fcmla(VectorFormat vform,
2240                        LogicVRegister dst,
2241                        const LogicVRegister& src1,
2242                        const LogicVRegister& src2,
2243                        int index,
2244                        int rot);
2245   template <typename T>
2246   LogicVRegister fcmla(VectorFormat vform,
2247                        LogicVRegister dst,
2248                        const LogicVRegister& src1,
2249                        const LogicVRegister& src2,
2250                        int rot);
2251   LogicVRegister fcmla(VectorFormat vform,
2252                        LogicVRegister dst,
2253                        const LogicVRegister& src1,
2254                        const LogicVRegister& src2,
2255                        int rot);
2256   LogicVRegister ins_element(VectorFormat vform,
2257                              LogicVRegister dst,
2258                              int dst_index,
2259                              const LogicVRegister& src,
2260                              int src_index);
2261   LogicVRegister ins_immediate(VectorFormat vform,
2262                                LogicVRegister dst,
2263                                int dst_index,
2264                                uint64_t imm);
2265   LogicVRegister dup_element(VectorFormat vform,
2266                              LogicVRegister dst,
2267                              const LogicVRegister& src,
2268                              int src_index);
2269   LogicVRegister dup_immediate(VectorFormat vform,
2270                                LogicVRegister dst,
2271                                uint64_t imm);
2272   LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2273   LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
2274   LogicVRegister orr(VectorFormat vform,
2275                      LogicVRegister dst,
2276                      const LogicVRegister& src,
2277                      uint64_t imm);
2278   LogicVRegister sshl(VectorFormat vform,
2279                       LogicVRegister dst,
2280                       const LogicVRegister& src1,
2281                       const LogicVRegister& src2);
2282   LogicVRegister ushl(VectorFormat vform,
2283                       LogicVRegister dst,
2284                       const LogicVRegister& src1,
2285                       const LogicVRegister& src2);
2286   LogicVRegister sminmax(VectorFormat vform,
2287                          LogicVRegister dst,
2288                          const LogicVRegister& src1,
2289                          const LogicVRegister& src2,
2290                          bool max);
2291   LogicVRegister smax(VectorFormat vform,
2292                       LogicVRegister dst,
2293                       const LogicVRegister& src1,
2294                       const LogicVRegister& src2);
2295   LogicVRegister smin(VectorFormat vform,
2296                       LogicVRegister dst,
2297                       const LogicVRegister& src1,
2298                       const LogicVRegister& src2);
2299   LogicVRegister sminmaxp(VectorFormat vform,
2300                           LogicVRegister dst,
2301                           const LogicVRegister& src1,
2302                           const LogicVRegister& src2,
2303                           bool max);
2304   LogicVRegister smaxp(VectorFormat vform,
2305                        LogicVRegister dst,
2306                        const LogicVRegister& src1,
2307                        const LogicVRegister& src2);
2308   LogicVRegister sminp(VectorFormat vform,
2309                        LogicVRegister dst,
2310                        const LogicVRegister& src1,
2311                        const LogicVRegister& src2);
2312   LogicVRegister addp(VectorFormat vform,
2313                       LogicVRegister dst,
2314                       const LogicVRegister& src);
2315   LogicVRegister addv(VectorFormat vform,
2316                       LogicVRegister dst,
2317                       const LogicVRegister& src);
2318   LogicVRegister uaddlv(VectorFormat vform,
2319                         LogicVRegister dst,
2320                         const LogicVRegister& src);
2321   LogicVRegister saddlv(VectorFormat vform,
2322                         LogicVRegister dst,
2323                         const LogicVRegister& src);
2324   LogicVRegister sminmaxv(VectorFormat vform,
2325                           LogicVRegister dst,
2326                           const LogicVRegister& src,
2327                           bool max);
2328   LogicVRegister smaxv(VectorFormat vform,
2329                        LogicVRegister dst,
2330                        const LogicVRegister& src);
2331   LogicVRegister sminv(VectorFormat vform,
2332                        LogicVRegister dst,
2333                        const LogicVRegister& src);
2334   LogicVRegister uxtl(VectorFormat vform,
2335                       LogicVRegister dst,
2336                       const LogicVRegister& src);
2337   LogicVRegister uxtl2(VectorFormat vform,
2338                        LogicVRegister dst,
2339                        const LogicVRegister& src);
2340   LogicVRegister sxtl(VectorFormat vform,
2341                       LogicVRegister dst,
2342                       const LogicVRegister& src);
2343   LogicVRegister sxtl2(VectorFormat vform,
2344                        LogicVRegister dst,
2345                        const LogicVRegister& src);
2346   LogicVRegister tbl(VectorFormat vform,
2347                      LogicVRegister dst,
2348                      const LogicVRegister& tab,
2349                      const LogicVRegister& ind);
2350   LogicVRegister tbl(VectorFormat vform,
2351                      LogicVRegister dst,
2352                      const LogicVRegister& tab,
2353                      const LogicVRegister& tab2,
2354                      const LogicVRegister& ind);
2355   LogicVRegister tbl(VectorFormat vform,
2356                      LogicVRegister dst,
2357                      const LogicVRegister& tab,
2358                      const LogicVRegister& tab2,
2359                      const LogicVRegister& tab3,
2360                      const LogicVRegister& ind);
2361   LogicVRegister tbl(VectorFormat vform,
2362                      LogicVRegister dst,
2363                      const LogicVRegister& tab,
2364                      const LogicVRegister& tab2,
2365                      const LogicVRegister& tab3,
2366                      const LogicVRegister& tab4,
2367                      const LogicVRegister& ind);
2368   LogicVRegister Table(VectorFormat vform,
2369                        LogicVRegister dst,
2370                        const LogicVRegister& ind,
2371                        bool zero_out_of_bounds,
2372                        const LogicVRegister* tab1,
2373                        const LogicVRegister* tab2 = NULL,
2374                        const LogicVRegister* tab3 = NULL,
2375                        const LogicVRegister* tab4 = NULL);
2376   LogicVRegister tbx(VectorFormat vform,
2377                      LogicVRegister dst,
2378                      const LogicVRegister& tab,
2379                      const LogicVRegister& ind);
2380   LogicVRegister tbx(VectorFormat vform,
2381                      LogicVRegister dst,
2382                      const LogicVRegister& tab,
2383                      const LogicVRegister& tab2,
2384                      const LogicVRegister& ind);
2385   LogicVRegister tbx(VectorFormat vform,
2386                      LogicVRegister dst,
2387                      const LogicVRegister& tab,
2388                      const LogicVRegister& tab2,
2389                      const LogicVRegister& tab3,
2390                      const LogicVRegister& ind);
2391   LogicVRegister tbx(VectorFormat vform,
2392                      LogicVRegister dst,
2393                      const LogicVRegister& tab,
2394                      const LogicVRegister& tab2,
2395                      const LogicVRegister& tab3,
2396                      const LogicVRegister& tab4,
2397                      const LogicVRegister& ind);
2398   LogicVRegister uaddl(VectorFormat vform,
2399                        LogicVRegister dst,
2400                        const LogicVRegister& src1,
2401                        const LogicVRegister& src2);
2402   LogicVRegister uaddl2(VectorFormat vform,
2403                         LogicVRegister dst,
2404                         const LogicVRegister& src1,
2405                         const LogicVRegister& src2);
2406   LogicVRegister uaddw(VectorFormat vform,
2407                        LogicVRegister dst,
2408                        const LogicVRegister& src1,
2409                        const LogicVRegister& src2);
2410   LogicVRegister uaddw2(VectorFormat vform,
2411                         LogicVRegister dst,
2412                         const LogicVRegister& src1,
2413                         const LogicVRegister& src2);
2414   LogicVRegister saddl(VectorFormat vform,
2415                        LogicVRegister dst,
2416                        const LogicVRegister& src1,
2417                        const LogicVRegister& src2);
2418   LogicVRegister saddl2(VectorFormat vform,
2419                         LogicVRegister dst,
2420                         const LogicVRegister& src1,
2421                         const LogicVRegister& src2);
2422   LogicVRegister saddw(VectorFormat vform,
2423                        LogicVRegister dst,
2424                        const LogicVRegister& src1,
2425                        const LogicVRegister& src2);
2426   LogicVRegister saddw2(VectorFormat vform,
2427                         LogicVRegister dst,
2428                         const LogicVRegister& src1,
2429                         const LogicVRegister& src2);
2430   LogicVRegister usubl(VectorFormat vform,
2431                        LogicVRegister dst,
2432                        const LogicVRegister& src1,
2433                        const LogicVRegister& src2);
2434   LogicVRegister usubl2(VectorFormat vform,
2435                         LogicVRegister dst,
2436                         const LogicVRegister& src1,
2437                         const LogicVRegister& src2);
2438   LogicVRegister usubw(VectorFormat vform,
2439                        LogicVRegister dst,
2440                        const LogicVRegister& src1,
2441                        const LogicVRegister& src2);
2442   LogicVRegister usubw2(VectorFormat vform,
2443                         LogicVRegister dst,
2444                         const LogicVRegister& src1,
2445                         const LogicVRegister& src2);
2446   LogicVRegister ssubl(VectorFormat vform,
2447                        LogicVRegister dst,
2448                        const LogicVRegister& src1,
2449                        const LogicVRegister& src2);
2450   LogicVRegister ssubl2(VectorFormat vform,
2451                         LogicVRegister dst,
2452                         const LogicVRegister& src1,
2453                         const LogicVRegister& src2);
2454   LogicVRegister ssubw(VectorFormat vform,
2455                        LogicVRegister dst,
2456                        const LogicVRegister& src1,
2457                        const LogicVRegister& src2);
2458   LogicVRegister ssubw2(VectorFormat vform,
2459                         LogicVRegister dst,
2460                         const LogicVRegister& src1,
2461                         const LogicVRegister& src2);
2462   LogicVRegister uminmax(VectorFormat vform,
2463                          LogicVRegister dst,
2464                          const LogicVRegister& src1,
2465                          const LogicVRegister& src2,
2466                          bool max);
2467   LogicVRegister umax(VectorFormat vform,
2468                       LogicVRegister dst,
2469                       const LogicVRegister& src1,
2470                       const LogicVRegister& src2);
2471   LogicVRegister umin(VectorFormat vform,
2472                       LogicVRegister dst,
2473                       const LogicVRegister& src1,
2474                       const LogicVRegister& src2);
2475   LogicVRegister uminmaxp(VectorFormat vform,
2476                           LogicVRegister dst,
2477                           const LogicVRegister& src1,
2478                           const LogicVRegister& src2,
2479                           bool max);
2480   LogicVRegister umaxp(VectorFormat vform,
2481                        LogicVRegister dst,
2482                        const LogicVRegister& src1,
2483                        const LogicVRegister& src2);
2484   LogicVRegister uminp(VectorFormat vform,
2485                        LogicVRegister dst,
2486                        const LogicVRegister& src1,
2487                        const LogicVRegister& src2);
2488   LogicVRegister uminmaxv(VectorFormat vform,
2489                           LogicVRegister dst,
2490                           const LogicVRegister& src,
2491                           bool max);
2492   LogicVRegister umaxv(VectorFormat vform,
2493                        LogicVRegister dst,
2494                        const LogicVRegister& src);
2495   LogicVRegister uminv(VectorFormat vform,
2496                        LogicVRegister dst,
2497                        const LogicVRegister& src);
2498   LogicVRegister trn1(VectorFormat vform,
2499                       LogicVRegister dst,
2500                       const LogicVRegister& src1,
2501                       const LogicVRegister& src2);
2502   LogicVRegister trn2(VectorFormat vform,
2503                       LogicVRegister dst,
2504                       const LogicVRegister& src1,
2505                       const LogicVRegister& src2);
2506   LogicVRegister zip1(VectorFormat vform,
2507                       LogicVRegister dst,
2508                       const LogicVRegister& src1,
2509                       const LogicVRegister& src2);
2510   LogicVRegister zip2(VectorFormat vform,
2511                       LogicVRegister dst,
2512                       const LogicVRegister& src1,
2513                       const LogicVRegister& src2);
2514   LogicVRegister uzp1(VectorFormat vform,
2515                       LogicVRegister dst,
2516                       const LogicVRegister& src1,
2517                       const LogicVRegister& src2);
2518   LogicVRegister uzp2(VectorFormat vform,
2519                       LogicVRegister dst,
2520                       const LogicVRegister& src1,
2521                       const LogicVRegister& src2);
2522   LogicVRegister shl(VectorFormat vform,
2523                      LogicVRegister dst,
2524                      const LogicVRegister& src,
2525                      int shift);
2526   LogicVRegister scvtf(VectorFormat vform,
2527                        LogicVRegister dst,
2528                        const LogicVRegister& src,
2529                        int fbits,
2530                        FPRounding rounding_mode);
2531   LogicVRegister ucvtf(VectorFormat vform,
2532                        LogicVRegister dst,
2533                        const LogicVRegister& src,
2534                        int fbits,
2535                        FPRounding rounding_mode);
2536   LogicVRegister sshll(VectorFormat vform,
2537                        LogicVRegister dst,
2538                        const LogicVRegister& src,
2539                        int shift);
2540   LogicVRegister sshll2(VectorFormat vform,
2541                         LogicVRegister dst,
2542                         const LogicVRegister& src,
2543                         int shift);
2544   LogicVRegister shll(VectorFormat vform,
2545                       LogicVRegister dst,
2546                       const LogicVRegister& src);
2547   LogicVRegister shll2(VectorFormat vform,
2548                        LogicVRegister dst,
2549                        const LogicVRegister& src);
2550   LogicVRegister ushll(VectorFormat vform,
2551                        LogicVRegister dst,
2552                        const LogicVRegister& src,
2553                        int shift);
2554   LogicVRegister ushll2(VectorFormat vform,
2555                         LogicVRegister dst,
2556                         const LogicVRegister& src,
2557                         int shift);
2558   LogicVRegister sli(VectorFormat vform,
2559                      LogicVRegister dst,
2560                      const LogicVRegister& src,
2561                      int shift);
2562   LogicVRegister sri(VectorFormat vform,
2563                      LogicVRegister dst,
2564                      const LogicVRegister& src,
2565                      int shift);
2566   LogicVRegister sshr(VectorFormat vform,
2567                       LogicVRegister dst,
2568                       const LogicVRegister& src,
2569                       int shift);
2570   LogicVRegister ushr(VectorFormat vform,
2571                       LogicVRegister dst,
2572                       const LogicVRegister& src,
2573                       int shift);
2574   LogicVRegister ssra(VectorFormat vform,
2575                       LogicVRegister dst,
2576                       const LogicVRegister& src,
2577                       int shift);
2578   LogicVRegister usra(VectorFormat vform,
2579                       LogicVRegister dst,
2580                       const LogicVRegister& src,
2581                       int shift);
2582   LogicVRegister srsra(VectorFormat vform,
2583                        LogicVRegister dst,
2584                        const LogicVRegister& src,
2585                        int shift);
2586   LogicVRegister ursra(VectorFormat vform,
2587                        LogicVRegister dst,
2588                        const LogicVRegister& src,
2589                        int shift);
2590   LogicVRegister suqadd(VectorFormat vform,
2591                         LogicVRegister dst,
2592                         const LogicVRegister& src);
2593   LogicVRegister usqadd(VectorFormat vform,
2594                         LogicVRegister dst,
2595                         const LogicVRegister& src);
2596   LogicVRegister sqshl(VectorFormat vform,
2597                        LogicVRegister dst,
2598                        const LogicVRegister& src,
2599                        int shift);
2600   LogicVRegister uqshl(VectorFormat vform,
2601                        LogicVRegister dst,
2602                        const LogicVRegister& src,
2603                        int shift);
2604   LogicVRegister sqshlu(VectorFormat vform,
2605                         LogicVRegister dst,
2606                         const LogicVRegister& src,
2607                         int shift);
2608   LogicVRegister abs(VectorFormat vform,
2609                      LogicVRegister dst,
2610                      const LogicVRegister& src);
2611   LogicVRegister neg(VectorFormat vform,
2612                      LogicVRegister dst,
2613                      const LogicVRegister& src);
2614   LogicVRegister extractnarrow(VectorFormat vform,
2615                                LogicVRegister dst,
2616                                bool dstIsSigned,
2617                                const LogicVRegister& src,
2618                                bool srcIsSigned);
2619   LogicVRegister xtn(VectorFormat vform,
2620                      LogicVRegister dst,
2621                      const LogicVRegister& src);
2622   LogicVRegister sqxtn(VectorFormat vform,
2623                        LogicVRegister dst,
2624                        const LogicVRegister& src);
2625   LogicVRegister uqxtn(VectorFormat vform,
2626                        LogicVRegister dst,
2627                        const LogicVRegister& src);
2628   LogicVRegister sqxtun(VectorFormat vform,
2629                         LogicVRegister dst,
2630                         const LogicVRegister& src);
2631   LogicVRegister absdiff(VectorFormat vform,
2632                          LogicVRegister dst,
2633                          const LogicVRegister& src1,
2634                          const LogicVRegister& src2,
2635                          bool issigned);
2636   LogicVRegister saba(VectorFormat vform,
2637                       LogicVRegister dst,
2638                       const LogicVRegister& src1,
2639                       const LogicVRegister& src2);
2640   LogicVRegister uaba(VectorFormat vform,
2641                       LogicVRegister dst,
2642                       const LogicVRegister& src1,
2643                       const LogicVRegister& src2);
2644   LogicVRegister shrn(VectorFormat vform,
2645                       LogicVRegister dst,
2646                       const LogicVRegister& src,
2647                       int shift);
2648   LogicVRegister shrn2(VectorFormat vform,
2649                        LogicVRegister dst,
2650                        const LogicVRegister& src,
2651                        int shift);
2652   LogicVRegister rshrn(VectorFormat vform,
2653                        LogicVRegister dst,
2654                        const LogicVRegister& src,
2655                        int shift);
2656   LogicVRegister rshrn2(VectorFormat vform,
2657                         LogicVRegister dst,
2658                         const LogicVRegister& src,
2659                         int shift);
2660   LogicVRegister uqshrn(VectorFormat vform,
2661                         LogicVRegister dst,
2662                         const LogicVRegister& src,
2663                         int shift);
2664   LogicVRegister uqshrn2(VectorFormat vform,
2665                          LogicVRegister dst,
2666                          const LogicVRegister& src,
2667                          int shift);
2668   LogicVRegister uqrshrn(VectorFormat vform,
2669                          LogicVRegister dst,
2670                          const LogicVRegister& src,
2671                          int shift);
2672   LogicVRegister uqrshrn2(VectorFormat vform,
2673                           LogicVRegister dst,
2674                           const LogicVRegister& src,
2675                           int shift);
2676   LogicVRegister sqshrn(VectorFormat vform,
2677                         LogicVRegister dst,
2678                         const LogicVRegister& src,
2679                         int shift);
2680   LogicVRegister sqshrn2(VectorFormat vform,
2681                          LogicVRegister dst,
2682                          const LogicVRegister& src,
2683                          int shift);
2684   LogicVRegister sqrshrn(VectorFormat vform,
2685                          LogicVRegister dst,
2686                          const LogicVRegister& src,
2687                          int shift);
2688   LogicVRegister sqrshrn2(VectorFormat vform,
2689                           LogicVRegister dst,
2690                           const LogicVRegister& src,
2691                           int shift);
2692   LogicVRegister sqshrun(VectorFormat vform,
2693                          LogicVRegister dst,
2694                          const LogicVRegister& src,
2695                          int shift);
2696   LogicVRegister sqshrun2(VectorFormat vform,
2697                           LogicVRegister dst,
2698                           const LogicVRegister& src,
2699                           int shift);
2700   LogicVRegister sqrshrun(VectorFormat vform,
2701                           LogicVRegister dst,
2702                           const LogicVRegister& src,
2703                           int shift);
2704   LogicVRegister sqrshrun2(VectorFormat vform,
2705                            LogicVRegister dst,
2706                            const LogicVRegister& src,
2707                            int shift);
2708   LogicVRegister sqrdmulh(VectorFormat vform,
2709                           LogicVRegister dst,
2710                           const LogicVRegister& src1,
2711                           const LogicVRegister& src2,
2712                           bool round = true);
2713   LogicVRegister dot(VectorFormat vform,
2714                      LogicVRegister dst,
2715                      const LogicVRegister& src1,
2716                      const LogicVRegister& src2,
2717                      bool is_signed);
2718   LogicVRegister sdot(VectorFormat vform,
2719                       LogicVRegister dst,
2720                       const LogicVRegister& src1,
2721                       const LogicVRegister& src2);
2722   LogicVRegister udot(VectorFormat vform,
2723                       LogicVRegister dst,
2724                       const LogicVRegister& src1,
2725                       const LogicVRegister& src2);
2726   LogicVRegister sqrdmlash(VectorFormat vform,
2727                            LogicVRegister dst,
2728                            const LogicVRegister& src1,
2729                            const LogicVRegister& src2,
2730                            bool round = true,
2731                            bool sub_op = false);
2732   LogicVRegister sqrdmlah(VectorFormat vform,
2733                           LogicVRegister dst,
2734                           const LogicVRegister& src1,
2735                           const LogicVRegister& src2,
2736                           bool round = true);
2737   LogicVRegister sqrdmlsh(VectorFormat vform,
2738                           LogicVRegister dst,
2739                           const LogicVRegister& src1,
2740                           const LogicVRegister& src2,
2741                           bool round = true);
2742   LogicVRegister sqdmulh(VectorFormat vform,
2743                          LogicVRegister dst,
2744                          const LogicVRegister& src1,
2745                          const LogicVRegister& src2);
2746 #define NEON_3VREG_LOGIC_LIST(V) \
2747   V(addhn)                       \
2748   V(addhn2)                      \
2749   V(raddhn)                      \
2750   V(raddhn2)                     \
2751   V(subhn)                       \
2752   V(subhn2)                      \
2753   V(rsubhn)                      \
2754   V(rsubhn2)                     \
2755   V(pmull)                       \
2756   V(pmull2)                      \
2757   V(sabal)                       \
2758   V(sabal2)                      \
2759   V(uabal)                       \
2760   V(uabal2)                      \
2761   V(sabdl)                       \
2762   V(sabdl2)                      \
2763   V(uabdl)                       \
2764   V(uabdl2)                      \
2765   V(smull)                       \
2766   V(smull2)                      \
2767   V(umull)                       \
2768   V(umull2)                      \
2769   V(smlal)                       \
2770   V(smlal2)                      \
2771   V(umlal)                       \
2772   V(umlal2)                      \
2773   V(smlsl)                       \
2774   V(smlsl2)                      \
2775   V(umlsl)                       \
2776   V(umlsl2)                      \
2777   V(sqdmlal)                     \
2778   V(sqdmlal2)                    \
2779   V(sqdmlsl)                     \
2780   V(sqdmlsl2)                    \
2781   V(sqdmull)                     \
2782   V(sqdmull2)
2783 
2784 #define DEFINE_LOGIC_FUNC(FXN)                   \
2785   LogicVRegister FXN(VectorFormat vform,         \
2786                      LogicVRegister dst,         \
2787                      const LogicVRegister& src1, \
2788                      const LogicVRegister& src2);
2789   NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
2790 #undef DEFINE_LOGIC_FUNC
2791 
2792 #define NEON_FP3SAME_LIST(V) \
2793   V(fadd, FPAdd, false)      \
2794   V(fsub, FPSub, true)       \
2795   V(fmul, FPMul, true)       \
2796   V(fmulx, FPMulx, true)     \
2797   V(fdiv, FPDiv, true)       \
2798   V(fmax, FPMax, false)      \
2799   V(fmin, FPMin, false)      \
2800   V(fmaxnm, FPMaxNM, false)  \
2801   V(fminnm, FPMinNM, false)
2802 
2803 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
2804   template <typename T>                            \
2805   LogicVRegister FN(VectorFormat vform,            \
2806                     LogicVRegister dst,            \
2807                     const LogicVRegister& src1,    \
2808                     const LogicVRegister& src2);   \
2809   LogicVRegister FN(VectorFormat vform,            \
2810                     LogicVRegister dst,            \
2811                     const LogicVRegister& src1,    \
2812                     const LogicVRegister& src2);
2813   NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
2814 #undef DECLARE_NEON_FP_VECTOR_OP
2815 
2816 #define NEON_FPPAIRWISE_LIST(V) \
2817   V(faddp, fadd, FPAdd)         \
2818   V(fmaxp, fmax, FPMax)         \
2819   V(fmaxnmp, fmaxnm, FPMaxNM)   \
2820   V(fminp, fmin, FPMin)         \
2821   V(fminnmp, fminnm, FPMinNM)
2822 
2823 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)      \
2824   LogicVRegister FNP(VectorFormat vform,          \
2825                      LogicVRegister dst,          \
2826                      const LogicVRegister& src1,  \
2827                      const LogicVRegister& src2); \
2828   LogicVRegister FNP(VectorFormat vform,          \
2829                      LogicVRegister dst,          \
2830                      const LogicVRegister& src);
2831   NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
2832 #undef DECLARE_NEON_FP_PAIR_OP
2833 
2834   template <typename T>
2835   LogicVRegister frecps(VectorFormat vform,
2836                         LogicVRegister dst,
2837                         const LogicVRegister& src1,
2838                         const LogicVRegister& src2);
2839   LogicVRegister frecps(VectorFormat vform,
2840                         LogicVRegister dst,
2841                         const LogicVRegister& src1,
2842                         const LogicVRegister& src2);
2843   template <typename T>
2844   LogicVRegister frsqrts(VectorFormat vform,
2845                          LogicVRegister dst,
2846                          const LogicVRegister& src1,
2847                          const LogicVRegister& src2);
2848   LogicVRegister frsqrts(VectorFormat vform,
2849                          LogicVRegister dst,
2850                          const LogicVRegister& src1,
2851                          const LogicVRegister& src2);
2852   template <typename T>
2853   LogicVRegister fmla(VectorFormat vform,
2854                       LogicVRegister dst,
2855                       const LogicVRegister& src1,
2856                       const LogicVRegister& src2);
2857   LogicVRegister fmla(VectorFormat vform,
2858                       LogicVRegister dst,
2859                       const LogicVRegister& src1,
2860                       const LogicVRegister& src2);
2861   template <typename T>
2862   LogicVRegister fmls(VectorFormat vform,
2863                       LogicVRegister dst,
2864                       const LogicVRegister& src1,
2865                       const LogicVRegister& src2);
2866   LogicVRegister fmls(VectorFormat vform,
2867                       LogicVRegister dst,
2868                       const LogicVRegister& src1,
2869                       const LogicVRegister& src2);
2870   LogicVRegister fnmul(VectorFormat vform,
2871                        LogicVRegister dst,
2872                        const LogicVRegister& src1,
2873                        const LogicVRegister& src2);
2874 
2875   template <typename T>
2876   LogicVRegister fcmp(VectorFormat vform,
2877                       LogicVRegister dst,
2878                       const LogicVRegister& src1,
2879                       const LogicVRegister& src2,
2880                       Condition cond);
2881   LogicVRegister fcmp(VectorFormat vform,
2882                       LogicVRegister dst,
2883                       const LogicVRegister& src1,
2884                       const LogicVRegister& src2,
2885                       Condition cond);
2886   LogicVRegister fabscmp(VectorFormat vform,
2887                          LogicVRegister dst,
2888                          const LogicVRegister& src1,
2889                          const LogicVRegister& src2,
2890                          Condition cond);
2891   LogicVRegister fcmp_zero(VectorFormat vform,
2892                            LogicVRegister dst,
2893                            const LogicVRegister& src,
2894                            Condition cond);
2895 
2896   template <typename T>
2897   LogicVRegister fneg(VectorFormat vform,
2898                       LogicVRegister dst,
2899                       const LogicVRegister& src);
2900   LogicVRegister fneg(VectorFormat vform,
2901                       LogicVRegister dst,
2902                       const LogicVRegister& src);
2903   template <typename T>
2904   LogicVRegister frecpx(VectorFormat vform,
2905                         LogicVRegister dst,
2906                         const LogicVRegister& src);
2907   LogicVRegister frecpx(VectorFormat vform,
2908                         LogicVRegister dst,
2909                         const LogicVRegister& src);
2910   template <typename T>
2911   LogicVRegister fabs_(VectorFormat vform,
2912                        LogicVRegister dst,
2913                        const LogicVRegister& src);
2914   LogicVRegister fabs_(VectorFormat vform,
2915                        LogicVRegister dst,
2916                        const LogicVRegister& src);
2917   LogicVRegister fabd(VectorFormat vform,
2918                       LogicVRegister dst,
2919                       const LogicVRegister& src1,
2920                       const LogicVRegister& src2);
2921   LogicVRegister frint(VectorFormat vform,
2922                        LogicVRegister dst,
2923                        const LogicVRegister& src,
2924                        FPRounding rounding_mode,
2925                        bool inexact_exception = false);
2926   LogicVRegister fcvts(VectorFormat vform,
2927                        LogicVRegister dst,
2928                        const LogicVRegister& src,
2929                        FPRounding rounding_mode,
2930                        int fbits = 0);
2931   LogicVRegister fcvtu(VectorFormat vform,
2932                        LogicVRegister dst,
2933                        const LogicVRegister& src,
2934                        FPRounding rounding_mode,
2935                        int fbits = 0);
2936   LogicVRegister fcvtl(VectorFormat vform,
2937                        LogicVRegister dst,
2938                        const LogicVRegister& src);
2939   LogicVRegister fcvtl2(VectorFormat vform,
2940                         LogicVRegister dst,
2941                         const LogicVRegister& src);
2942   LogicVRegister fcvtn(VectorFormat vform,
2943                        LogicVRegister dst,
2944                        const LogicVRegister& src);
2945   LogicVRegister fcvtn2(VectorFormat vform,
2946                         LogicVRegister dst,
2947                         const LogicVRegister& src);
2948   LogicVRegister fcvtxn(VectorFormat vform,
2949                         LogicVRegister dst,
2950                         const LogicVRegister& src);
2951   LogicVRegister fcvtxn2(VectorFormat vform,
2952                          LogicVRegister dst,
2953                          const LogicVRegister& src);
2954   LogicVRegister fsqrt(VectorFormat vform,
2955                        LogicVRegister dst,
2956                        const LogicVRegister& src);
2957   LogicVRegister frsqrte(VectorFormat vform,
2958                          LogicVRegister dst,
2959                          const LogicVRegister& src);
2960   LogicVRegister frecpe(VectorFormat vform,
2961                         LogicVRegister dst,
2962                         const LogicVRegister& src,
2963                         FPRounding rounding);
2964   LogicVRegister ursqrte(VectorFormat vform,
2965                          LogicVRegister dst,
2966                          const LogicVRegister& src);
2967   LogicVRegister urecpe(VectorFormat vform,
2968                         LogicVRegister dst,
2969                         const LogicVRegister& src);
2970 
2971   template <typename T>
2972   struct TFPMinMaxOp {
2973     typedef T (Simulator::*type)(T a, T b);
2974   };
2975 
2976   template <typename T>
2977   LogicVRegister fminmaxv(VectorFormat vform,
2978                           LogicVRegister dst,
2979                           const LogicVRegister& src,
2980                           typename TFPMinMaxOp<T>::type Op);
2981 
2982   LogicVRegister fminv(VectorFormat vform,
2983                        LogicVRegister dst,
2984                        const LogicVRegister& src);
2985   LogicVRegister fmaxv(VectorFormat vform,
2986                        LogicVRegister dst,
2987                        const LogicVRegister& src);
2988   LogicVRegister fminnmv(VectorFormat vform,
2989                          LogicVRegister dst,
2990                          const LogicVRegister& src);
2991   LogicVRegister fmaxnmv(VectorFormat vform,
2992                          LogicVRegister dst,
2993                          const LogicVRegister& src);
2994 
2995   static const uint32_t CRC32_POLY = 0x04C11DB7;
2996   static const uint32_t CRC32C_POLY = 0x1EDC6F41;
2997   uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
2998   template <typename T>
2999   uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
3000   uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
3001 
3002   void SysOp_W(int op, int64_t val);
3003 
3004   template <typename T>
3005   T FPRecipSqrtEstimate(T op);
3006   template <typename T>
3007   T FPRecipEstimate(T op, FPRounding rounding);
3008   template <typename T, typename R>
3009   R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
3010 
3011   void FPCompare(double val0, double val1, FPTrapFlags trap);
3012   double FPRoundInt(double value, FPRounding round_mode);
3013   double recip_sqrt_estimate(double a);
3014   double recip_estimate(double a);
3015   double FPRecipSqrtEstimate(double a);
3016   double FPRecipEstimate(double a);
3017   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
3018   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
3019   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
3020   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
3021   ::vixl::internal::SimFloat16 FixedToFloat16(int64_t src,
3022                                               int fbits,
3023                                               FPRounding round_mode);
3024   ::vixl::internal::SimFloat16 UFixedToFloat16(uint64_t src,
3025                                                int fbits,
3026                                                FPRounding round_mode);
3027   int16_t FPToInt16(double value, FPRounding rmode);
3028   int32_t FPToInt32(double value, FPRounding rmode);
3029   int64_t FPToInt64(double value, FPRounding rmode);
3030   uint16_t FPToUInt16(double value, FPRounding rmode);
3031   uint32_t FPToUInt32(double value, FPRounding rmode);
3032   uint64_t FPToUInt64(double value, FPRounding rmode);
3033   int32_t FPToFixedJS(double value);
3034 
3035   template <typename T>
3036   T FPAdd(T op1, T op2);
3037 
3038   template <typename T>
3039   T FPNeg(T op);
3040 
3041   template <typename T>
3042   T FPDiv(T op1, T op2);
3043 
3044   template <typename T>
3045   T FPMax(T a, T b);
3046 
3047   template <typename T>
3048   T FPMaxNM(T a, T b);
3049 
3050   template <typename T>
3051   T FPMin(T a, T b);
3052 
3053   template <typename T>
3054   T FPMinNM(T a, T b);
3055 
3056   template <typename T>
3057   T FPMul(T op1, T op2);
3058 
3059   template <typename T>
3060   T FPMulx(T op1, T op2);
3061 
3062   template <typename T>
3063   T FPMulAdd(T a, T op1, T op2);
3064 
3065   template <typename T>
3066   T FPSqrt(T op);
3067 
3068   template <typename T>
3069   T FPSub(T op1, T op2);
3070 
3071   template <typename T>
3072   T FPRecipStepFused(T op1, T op2);
3073 
3074   template <typename T>
3075   T FPRSqrtStepFused(T op1, T op2);
3076 
3077   // This doesn't do anything at the moment. We'll need it if we want support
3078   // for cumulative exception bits or floating-point exceptions.
3079   void FPProcessException() {}
3080 
3081   bool FPProcessNaNs(const Instruction* instr);
3082 
3083   // Pseudo Printf instruction
3084   void DoPrintf(const Instruction* instr);
3085 
3086   // Pseudo-instructions to configure CPU features dynamically.
3087   void DoConfigureCPUFeatures(const Instruction* instr);
3088 
3089   void DoSaveCPUFeatures(const Instruction* instr);
3090   void DoRestoreCPUFeatures(const Instruction* instr);
3091 
3092 // Simulate a runtime call.
3093 #ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
3094   VIXL_NO_RETURN_IN_DEBUG_MODE
3095 #endif
3096   void DoRuntimeCall(const Instruction* instr);
3097 
3098   // Processor state ---------------------------------------
3099 
3100   // Simulated monitors for exclusive access instructions.
3101   SimExclusiveLocalMonitor local_monitor_;
3102   SimExclusiveGlobalMonitor global_monitor_;
3103 
3104   // Output stream.
3105   FILE* stream_;
3106   PrintDisassembler* print_disasm_;
3107 
3108   // Instruction statistics instrumentation.
3109   Instrument* instrumentation_;
3110 
3111   // General purpose registers. Register 31 is the stack pointer.
3112   SimRegister registers_[kNumberOfRegisters];
3113 
3114   // Vector registers
3115   SimVRegister vregisters_[kNumberOfVRegisters];
3116 
3117   // Program Status Register.
3118   // bits[31, 27]: Condition flags N, Z, C, and V.
3119   //               (Negative, Zero, Carry, Overflow)
3120   SimSystemRegister nzcv_;
3121 
3122   // Floating-Point Control Register
3123   SimSystemRegister fpcr_;
3124 
3125   // Only a subset of FPCR features are supported by the simulator. This helper
3126   // checks that the FPCR settings are supported.
3127   //
3128   // This is checked when floating-point instructions are executed, not when
3129   // FPCR is set. This allows generated code to modify FPCR for external
3130   // functions, or to save and restore it when entering and leaving generated
3131   // code.
3132   void AssertSupportedFPCR() {
3133     // No flush-to-zero support.
3134     VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
3135     // Ties-to-even rounding only.
3136     VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
3137 
3138     // The simulator does not support half-precision operations so
3139     // GetFpcr().AHP() is irrelevant, and is not checked here.
3140   }
3141 
3142   static int CalcNFlag(uint64_t result, unsigned reg_size) {
3143     return (result >> (reg_size - 1)) & 1;
3144   }
3145 
3146   static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
3147 
3148   static const uint32_t kConditionFlagsMask = 0xf0000000;
3149 
3150   // Stack
3151   byte* stack_;
3152   static const int stack_protection_size_ = 256;
3153   // 2 KB stack.
3154   static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
3155   byte* stack_limit_;
3156 
3157   Decoder* decoder_;
3158   // Indicates if the pc has been modified by the instruction and should not be
3159   // automatically incremented.
3160   bool pc_modified_;
3161   const Instruction* pc_;
3162 
3163   static const char* xreg_names[];
3164   static const char* wreg_names[];
3165   static const char* hreg_names[];
3166   static const char* sreg_names[];
3167   static const char* dreg_names[];
3168   static const char* vreg_names[];
3169 
3170  private:
3171   static const PACKey kPACKeyIA;
3172   static const PACKey kPACKeyIB;
3173   static const PACKey kPACKeyDA;
3174   static const PACKey kPACKeyDB;
3175   static const PACKey kPACKeyGA;
3176 
3177   template <typename T>
3178   static T FPDefaultNaN();
3179 
3180   // Standard NaN processing.
3181   template <typename T>
3182   T FPProcessNaN(T op) {
3183     VIXL_ASSERT(IsNaN(op));
3184     if (IsSignallingNaN(op)) {
3185       FPProcessException();
3186     }
3187     return (ReadDN() == kUseDefaultNaN) ? FPDefaultNaN<T>() : ToQuietNaN(op);
3188   }
3189 
3190   template <typename T>
3191   T FPProcessNaNs(T op1, T op2) {
3192     if (IsSignallingNaN(op1)) {
3193       return FPProcessNaN(op1);
3194     } else if (IsSignallingNaN(op2)) {
3195       return FPProcessNaN(op2);
3196     } else if (IsNaN(op1)) {
3197       VIXL_ASSERT(IsQuietNaN(op1));
3198       return FPProcessNaN(op1);
3199     } else if (IsNaN(op2)) {
3200       VIXL_ASSERT(IsQuietNaN(op2));
3201       return FPProcessNaN(op2);
3202     } else {
3203       return 0.0;
3204     }
3205   }
3206 
3207   template <typename T>
3208   T FPProcessNaNs3(T op1, T op2, T op3) {
3209     if (IsSignallingNaN(op1)) {
3210       return FPProcessNaN(op1);
3211     } else if (IsSignallingNaN(op2)) {
3212       return FPProcessNaN(op2);
3213     } else if (IsSignallingNaN(op3)) {
3214       return FPProcessNaN(op3);
3215     } else if (IsNaN(op1)) {
3216       VIXL_ASSERT(IsQuietNaN(op1));
3217       return FPProcessNaN(op1);
3218     } else if (IsNaN(op2)) {
3219       VIXL_ASSERT(IsQuietNaN(op2));
3220       return FPProcessNaN(op2);
3221     } else if (IsNaN(op3)) {
3222       VIXL_ASSERT(IsQuietNaN(op3));
3223       return FPProcessNaN(op3);
3224     } else {
3225       return 0.0;
3226     }
3227   }
3228 
3229   bool coloured_trace_;
3230 
3231   // A set of TraceParameters flags.
3232   int trace_parameters_;
3233 
3234   // Indicates whether the instruction instrumentation is active.
3235   bool instruction_stats_;
3236 
3237   // Indicates whether the exclusive-access warning has been printed.
3238   bool print_exclusive_access_warning_;
3239   void PrintExclusiveAccessWarning();
3240 
3241   CPUFeaturesAuditor cpu_features_auditor_;
3242   std::vector<CPUFeatures> saved_cpu_features_;
3243 };
3244 
3245 #if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
3246 // Base case of the recursive template used to emulate C++14
3247 // `std::index_sequence`.
3248 template <size_t... I>
3249 struct Simulator::emulated_make_index_sequence_helper<0, I...>
3250     : Simulator::emulated_index_sequence<I...> {};
3251 #endif
3252 
3253 }  // namespace aarch64
3254 }  // namespace vixl
3255 
3256 #endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
3257 
3258 #endif  // VIXL_AARCH64_SIMULATOR_AARCH64_H_
3259