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