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