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