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