• 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_EXECUTION_ARM64_SIMULATOR_ARM64_H_
6 #define V8_EXECUTION_ARM64_SIMULATOR_ARM64_H_
7 
8 // globals.h defines USE_SIMULATOR.
9 #include "src/common/globals.h"
10 
11 #if defined(USE_SIMULATOR)
12 
13 #include <stdarg.h>
14 
15 #include <vector>
16 
17 #include "src/base/compiler-specific.h"
18 #include "src/base/platform/wrappers.h"
19 #include "src/codegen/arm64/assembler-arm64.h"
20 #include "src/codegen/arm64/decoder-arm64.h"
21 #include "src/codegen/assembler.h"
22 #include "src/diagnostics/arm64/disasm-arm64.h"
23 #include "src/execution/simulator-base.h"
24 #include "src/utils/allocation.h"
25 #include "src/utils/utils.h"
26 
27 namespace v8 {
28 namespace internal {
29 
30 // Assemble the specified IEEE-754 components into the target type and apply
31 // appropriate rounding.
32 //  sign:     0 = positive, 1 = negative
33 //  exponent: Unbiased IEEE-754 exponent.
34 //  mantissa: The mantissa of the input. The top bit (which is not encoded for
35 //            normal IEEE-754 values) must not be omitted. This bit has the
36 //            value 'pow(2, exponent)'.
37 //
38 // The input value is assumed to be a normalized value. That is, the input may
39 // not be infinity or NaN. If the source value is subnormal, it must be
40 // normalized before calling this function such that the highest set bit in the
41 // mantissa has the value 'pow(2, exponent)'.
42 //
43 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
44 // calling a templated FPRound.
45 template <class T, int ebits, int mbits>
FPRound(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)46 T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa,
47           FPRounding round_mode) {
48   static_assert((sizeof(T) * 8) >= (1 + ebits + mbits),
49                 "destination type T not large enough");
50   static_assert(sizeof(T) <= sizeof(uint64_t),
51                 "maximum size of destination type T is 64 bits");
52   static_assert(std::is_unsigned<T>::value,
53                 "destination type T must be unsigned");
54 
55   DCHECK((sign == 0) || (sign == 1));
56 
57   // Only FPTieEven and FPRoundOdd rounding modes are implemented.
58   DCHECK((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
59 
60   // Rounding can promote subnormals to normals, and normals to infinities. For
61   // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
62   // encodable as a float, but rounding based on the low-order mantissa bits
63   // could make it overflow. With ties-to-even rounding, this value would become
64   // an infinity.
65 
66   // ---- Rounding Method ----
67   //
68   // The exponent is irrelevant in the rounding operation, so we treat the
69   // lowest-order bit that will fit into the result ('onebit') as having
70   // the value '1'. Similarly, the highest-order bit that won't fit into
71   // the result ('halfbit') has the value '0.5'. The 'point' sits between
72   // 'onebit' and 'halfbit':
73   //
74   //            These bits fit into the result.
75   //               |---------------------|
76   //  mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
77   //                                     ||
78   //                                    / |
79   //                                   /  halfbit
80   //                               onebit
81   //
82   // For subnormal outputs, the range of representable bits is smaller and
83   // the position of onebit and halfbit depends on the exponent of the
84   // input, but the method is otherwise similar.
85   //
86   //   onebit(frac)
87   //     |
88   //     | halfbit(frac)          halfbit(adjusted)
89   //     | /                      /
90   //     | |                      |
91   //  0b00.0 (exact)      -> 0b00.0 (exact)                    -> 0b00
92   //  0b00.0...           -> 0b00.0...                         -> 0b00
93   //  0b00.1 (exact)      -> 0b00.0111..111                    -> 0b00
94   //  0b00.1...           -> 0b00.1...                         -> 0b01
95   //  0b01.0 (exact)      -> 0b01.0 (exact)                    -> 0b01
96   //  0b01.0...           -> 0b01.0...                         -> 0b01
97   //  0b01.1 (exact)      -> 0b01.1 (exact)                    -> 0b10
98   //  0b01.1...           -> 0b01.1...                         -> 0b10
99   //  0b10.0 (exact)      -> 0b10.0 (exact)                    -> 0b10
100   //  0b10.0...           -> 0b10.0...                         -> 0b10
101   //  0b10.1 (exact)      -> 0b10.0111..111                    -> 0b10
102   //  0b10.1...           -> 0b10.1...                         -> 0b11
103   //  0b11.0 (exact)      -> 0b11.0 (exact)                    -> 0b11
104   //  ...                   /             |                      /   |
105   //                       /              |                     /    |
106   //                                                           /     |
107   // adjusted = frac - (halfbit(mantissa) & ~onebit(frac));   /      |
108   //
109   //                   mantissa = (mantissa >> shift) + halfbit(adjusted);
110 
111   const int mantissa_offset = 0;
112   const int exponent_offset = mantissa_offset + mbits;
113   const int sign_offset = exponent_offset + ebits;
114   DCHECK_EQ(sign_offset, static_cast<int>(sizeof(T) * 8 - 1));
115 
116   // Bail out early for zero inputs.
117   if (mantissa == 0) {
118     return static_cast<T>(sign << sign_offset);
119   }
120 
121   // If all bits in the exponent are set, the value is infinite or NaN.
122   // This is true for all binary IEEE-754 formats.
123   const int infinite_exponent = (1 << ebits) - 1;
124   const int max_normal_exponent = infinite_exponent - 1;
125 
126   // Apply the exponent bias to encode it for the result. Doing this early makes
127   // it easy to detect values that will be infinite or subnormal.
128   exponent += max_normal_exponent >> 1;
129 
130   if (exponent > max_normal_exponent) {
131     // Overflow: the input is too large for the result type to represent.
132     if (round_mode == FPTieEven) {
133       // FPTieEven rounding mode handles overflows using infinities.
134       exponent = infinite_exponent;
135       mantissa = 0;
136     } else {
137       DCHECK_EQ(round_mode, FPRoundOdd);
138       // FPRoundOdd rounding mode handles overflows using the largest magnitude
139       // normal number.
140       exponent = max_normal_exponent;
141       mantissa = (UINT64_C(1) << exponent_offset) - 1;
142     }
143     return static_cast<T>((sign << sign_offset) |
144                           (exponent << exponent_offset) |
145                           (mantissa << mantissa_offset));
146   }
147 
148   // Calculate the shift required to move the top mantissa bit to the proper
149   // place in the destination type.
150   const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64);
151   int shift = highest_significant_bit - mbits;
152 
153   if (exponent <= 0) {
154     // The output will be subnormal (before rounding).
155     // For subnormal outputs, the shift must be adjusted by the exponent. The +1
156     // is necessary because the exponent of a subnormal value (encoded as 0) is
157     // the same as the exponent of the smallest normal value (encoded as 1).
158     shift += -exponent + 1;
159 
160     // Handle inputs that would produce a zero output.
161     //
162     // Shifts higher than highest_significant_bit+1 will always produce a zero
163     // result. A shift of exactly highest_significant_bit+1 might produce a
164     // non-zero result after rounding.
165     if (shift > (highest_significant_bit + 1)) {
166       if (round_mode == FPTieEven) {
167         // The result will always be +/-0.0.
168         return static_cast<T>(sign << sign_offset);
169       } else {
170         DCHECK_EQ(round_mode, FPRoundOdd);
171         DCHECK_NE(mantissa, 0U);
172         // For FPRoundOdd, if the mantissa is too small to represent and
173         // non-zero return the next "odd" value.
174         return static_cast<T>((sign << sign_offset) | 1);
175       }
176     }
177 
178     // Properly encode the exponent for a subnormal output.
179     exponent = 0;
180   } else {
181     // Clear the topmost mantissa bit, since this is not encoded in IEEE-754
182     // normal values.
183     mantissa &= ~(UINT64_C(1) << highest_significant_bit);
184   }
185 
186   if (shift > 0) {
187     if (round_mode == FPTieEven) {
188       // We have to shift the mantissa to the right. Some precision is lost, so
189       // we need to apply rounding.
190       uint64_t onebit_mantissa = (mantissa >> (shift)) & 1;
191       uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1;
192       uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa);
193       uint64_t adjusted = mantissa - adjustment;
194       T halfbit_adjusted = (adjusted >> (shift - 1)) & 1;
195 
196       T result =
197           static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) |
198                          ((mantissa >> shift) << mantissa_offset));
199 
200       // A very large mantissa can overflow during rounding. If this happens,
201       // the exponent should be incremented and the mantissa set to 1.0
202       // (encoded as 0). Applying halfbit_adjusted after assembling the float
203       // has the nice side-effect that this case is handled for free.
204       //
205       // This also handles cases where a very large finite value overflows to
206       // infinity, or where a very large subnormal value overflows to become
207       // normal.
208       return result + halfbit_adjusted;
209     } else {
210       DCHECK_EQ(round_mode, FPRoundOdd);
211       // If any bits at position halfbit or below are set, onebit (ie. the
212       // bottom bit of the resulting mantissa) must be set.
213       uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1);
214       if (fractional_bits != 0) {
215         mantissa |= UINT64_C(1) << shift;
216       }
217 
218       return static_cast<T>((sign << sign_offset) |
219                             (exponent << exponent_offset) |
220                             ((mantissa >> shift) << mantissa_offset));
221     }
222   } else {
223     // We have to shift the mantissa to the left (or not at all). The input
224     // mantissa is exactly representable in the output mantissa, so apply no
225     // rounding correction.
226     return static_cast<T>((sign << sign_offset) |
227                           (exponent << exponent_offset) |
228                           ((mantissa << -shift) << mantissa_offset));
229   }
230 }
231 
232 class CachePage {
233   // TODO(all): Simulate instruction cache.
234 };
235 
236 // Representation of memory, with typed getters and setters for access.
237 class SimMemory {
238  public:
239   template <typename T>
AddressUntag(T address)240   static T AddressUntag(T address) {
241     // Cast the address using a C-style cast. A reinterpret_cast would be
242     // appropriate, but it can't cast one integral type to another.
243     uint64_t bits = (uint64_t)address;
244     return (T)(bits & ~kAddressTagMask);
245   }
246 
247   template <typename T, typename A>
Read(A address)248   static T Read(A address) {
249     T value;
250     address = AddressUntag(address);
251     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) ||
252            (sizeof(value) == 4) || (sizeof(value) == 8) ||
253            (sizeof(value) == 16));
254     memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
255     return value;
256   }
257 
258   template <typename T, typename A>
Write(A address,T value)259   static void Write(A address, T value) {
260     address = AddressUntag(address);
261     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) ||
262            (sizeof(value) == 4) || (sizeof(value) == 8) ||
263            (sizeof(value) == 16));
264     memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
265   }
266 };
267 
268 // The proper way to initialize a simulated system register (such as NZCV) is as
269 // follows:
270 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
271 class SimSystemRegister {
272  public:
273   // The default constructor represents a register which has no writable bits.
274   // It is not possible to set its value to anything other than 0.
SimSystemRegister()275   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
276 
RawValue()277   uint32_t RawValue() const { return value_; }
278 
SetRawValue(uint32_t new_value)279   void SetRawValue(uint32_t new_value) {
280     value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
281   }
282 
Bits(int msb,int lsb)283   uint32_t Bits(int msb, int lsb) const {
284     return unsigned_bitextract_32(msb, lsb, value_);
285   }
286 
SignedBits(int msb,int lsb)287   int32_t SignedBits(int msb, int lsb) const {
288     return signed_bitextract_32(msb, lsb, value_);
289   }
290 
291   void SetBits(int msb, int lsb, uint32_t bits);
292 
293   // Default system register values.
294   static SimSystemRegister DefaultValueFor(SystemRegister id);
295 
296 #define DEFINE_GETTER(Name, HighBit, LowBit, Func, Type)                 \
297   Type Name() const { return static_cast<Type>(Func(HighBit, LowBit)); } \
298   void Set##Name(Type bits) {                                            \
299     SetBits(HighBit, LowBit, static_cast<Type>(bits));                   \
300   }
301 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
302   static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER,DEFINE_WRITE_IGNORE_MASK)303   SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
304 #undef DEFINE_ZERO_BITS
305 #undef DEFINE_GETTER
306 
307  protected:
308   // Most system registers only implement a few of the bits in the word. Other
309   // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
310   // describes the bits which are not modifiable.
311   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
312       : value_(value), write_ignore_mask_(write_ignore_mask) {}
313 
314   uint32_t value_;
315   uint32_t write_ignore_mask_;
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 using SimRegister = SimRegisterBase<kXRegSize>;   // r0-r31
374 using SimVRegister = SimRegisterBase<kQRegSize>;  // 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   V8_EXPORT_PRIVATE explicit Simulator(
658       Decoder<DispatchingDecoderVisitor>* decoder, Isolate* isolate = nullptr,
659       FILE* stream = stderr);
660   Simulator();
661   V8_EXPORT_PRIVATE ~Simulator();
662 
663   // System functions.
664 
665   V8_EXPORT_PRIVATE static Simulator* current(v8::internal::Isolate* isolate);
666 
667   // A wrapper class that stores an argument for one of the above Call
668   // functions.
669   //
670   // Only arguments up to 64 bits in size are supported.
671   class CallArgument {
672    public:
673     template <typename T>
CallArgument(T argument)674     explicit CallArgument(T argument) {
675       bits_ = 0;
676       DCHECK(sizeof(argument) <= sizeof(bits_));
677       memcpy(&bits_, &argument, sizeof(argument));
678       type_ = X_ARG;
679     }
680 
CallArgument(double argument)681     explicit CallArgument(double argument) {
682       DCHECK(sizeof(argument) == sizeof(bits_));
683       memcpy(&bits_, &argument, sizeof(argument));
684       type_ = D_ARG;
685     }
686 
CallArgument(float argument)687     explicit CallArgument(float argument) {
688       // TODO(all): CallArgument(float) is untested, remove this check once
689       //            tested.
690       UNIMPLEMENTED();
691       // Make the D register a NaN to try to trap errors if the callee expects a
692       // double. If it expects a float, the callee should ignore the top word.
693       DCHECK(sizeof(kFP64SignallingNaN) == sizeof(bits_));
694       memcpy(&bits_, &kFP64SignallingNaN, sizeof(kFP64SignallingNaN));
695       // Write the float payload to the S register.
696       DCHECK(sizeof(argument) <= sizeof(bits_));
697       memcpy(&bits_, &argument, sizeof(argument));
698       type_ = D_ARG;
699     }
700 
701     // This indicates the end of the arguments list, so that CallArgument
702     // objects can be passed into varargs functions.
End()703     static CallArgument End() { return CallArgument(); }
704 
bits()705     int64_t bits() const { return bits_; }
IsEnd()706     bool IsEnd() const { return type_ == NO_ARG; }
IsX()707     bool IsX() const { return type_ == X_ARG; }
IsD()708     bool IsD() const { return type_ == D_ARG; }
709 
710    private:
711     enum CallArgumentType { X_ARG, D_ARG, NO_ARG };
712 
713     // All arguments are aligned to at least 64 bits and we don't support
714     // passing bigger arguments, so the payload size can be fixed at 64 bits.
715     int64_t bits_;
716     CallArgumentType type_;
717 
CallArgument()718     CallArgument() { type_ = NO_ARG; }
719   };
720 
721   // Call an arbitrary function taking an arbitrary number of arguments.
722   template <typename Return, typename... Args>
Call(Address entry,Args...args)723   Return Call(Address entry, Args... args) {
724     // Convert all arguments to CallArgument.
725     CallArgument call_args[] = {CallArgument(args)..., CallArgument::End()};
726     CallImpl(entry, call_args);
727     return ReadReturn<Return>();
728   }
729 
730   // Start the debugging command line.
731   void Debug();
732 
733   // Executes a single debug command. Takes ownership of the command (so that it
734   // can store it for repeat executions), and returns true if the debugger
735   // should resume execution after this command completes.
736   bool ExecDebugCommand(ArrayUniquePtr<char> command);
737 
738   bool GetValue(const char* desc, int64_t* value);
739 
740   bool PrintValue(const char* desc);
741 
742   // Push an address onto the JS stack.
743   uintptr_t PushAddress(uintptr_t address);
744 
745   // Pop an address from the JS stack.
746   uintptr_t PopAddress();
747 
748   // Accessor to the internal simulator stack area.
749   uintptr_t StackLimit(uintptr_t c_limit) const;
750 
751   V8_EXPORT_PRIVATE void ResetState();
752 
753   void DoRuntimeCall(Instruction* instr);
754 
755   // Run the simulator.
756   static const Instruction* kEndOfSimAddress;
757   void DecodeInstruction();
758   void Run();
759   V8_EXPORT_PRIVATE void RunFrom(Instruction* start);
760 
761   // Simulation helpers.
762   template <typename T>
set_pc(T new_pc)763   void set_pc(T new_pc) {
764     STATIC_ASSERT(sizeof(T) == sizeof(pc_));
765     memcpy(&pc_, &new_pc, sizeof(T));
766     pc_modified_ = true;
767   }
pc()768   Instruction* pc() { return pc_; }
769 
increment_pc()770   void increment_pc() {
771     if (!pc_modified_) {
772       pc_ = pc_->following();
773     }
774 
775     pc_modified_ = false;
776   }
777 
Decode(Instruction * instr)778   virtual void Decode(Instruction* instr) { decoder_->Decode(instr); }
779 
780   // Branch Target Identification (BTI)
781   //
782   // Executing an instruction updates PSTATE.BTYPE, as described in the table
783   // below. Execution of an instruction on a guarded page is allowed if either:
784   // * PSTATE.BTYPE is 00, or
785   // * it is a BTI or PACI[AB]SP instruction that accepts the current value of
786   //   PSTATE.BTYPE (as described in the table below), or
787   // * it is BRK or HLT instruction that causes some higher-priority exception.
788   //
789   //  --------------------------------------------------------------------------
790   //  | Last-executed instruction    | Sets     | Accepted by                  |
791   //  |                              | BTYPE to | BTI | BTI j | BTI c | BTI jc |
792   //  --------------------------------------------------------------------------
793   //  | - BR from an unguarded page. |          |     |       |       |        |
794   //  | - BR from guarded page,      |          |     |       |       |        |
795   //  |   to x16 or x17.             |    01    |     |   X   |   X   |   X    |
796   //  --------------------------------------------------------------------------
797   //  | BR from guarded page,        |          |     |       |       |        |
798   //  | not to x16 or x17.           |    11    |     |   X   |       |   X    |
799   //  --------------------------------------------------------------------------
800   //  | BLR                          |    10    |     |       |   X   |   X    |
801   //  --------------------------------------------------------------------------
802   //  | Any other instruction        |          |     |       |       |        |
803   //  |(including RET).              |    00    |  X  |   X   |   X   |   X    |
804   //  --------------------------------------------------------------------------
805   //
806   // PACI[AB]SP is treated either like "BTI c" or "BTI jc", according to the
807   // value of SCTLR_EL1.BT0. Details available in ARM DDI 0487E.a, D5-2580.
808 
809   enum BType {
810     // Set when executing any instruction, except those cases listed below.
811     DefaultBType = 0,
812 
813     // Set when an indirect branch is taken from an unguarded page, or from a
814     // guarded page to ip0 or ip1 (x16 or x17), eg "br ip0".
815     BranchFromUnguardedOrToIP = 1,
816 
817     // Set when an indirect branch and link (call) is taken, eg. "blr x0".
818     BranchAndLink = 2,
819 
820     // Set when an indirect branch is taken from a guarded page to a register
821     // that is not ip0 or ip1 (x16 or x17), eg, "br x0".
822     BranchFromGuardedNotToIP = 3
823   };
824 
btype()825   BType btype() const { return btype_; }
ResetBType()826   void ResetBType() { btype_ = DefaultBType; }
set_btype(BType btype)827   void set_btype(BType btype) { btype_ = btype; }
828 
829   // Helper function to determine BType for branches.
830   BType GetBTypeFromInstruction(const Instruction* instr) const;
831 
PcIsInGuardedPage()832   bool PcIsInGuardedPage() const { return guard_pages_; }
SetGuardedPages(bool guard_pages)833   void SetGuardedPages(bool guard_pages) { guard_pages_ = guard_pages; }
834 
CheckBTypeForPAuth()835   void CheckBTypeForPAuth() {
836     DCHECK(pc_->IsPAuth());
837     Instr instr = pc_->Mask(SystemPAuthMask);
838     // Only PACI[AB]SP allowed here, and we only support PACIBSP.
839     CHECK(instr == PACIBSP);
840     // Check BType allows PACI[AB]SP instructions.
841     switch (btype()) {
842       case BranchFromGuardedNotToIP:
843         // This case depends on the value of SCTLR_EL1.BT0, which we assume
844         // here to be set. This makes PACI[AB]SP behave like "BTI c",
845         // disallowing its execution when BTYPE is BranchFromGuardedNotToIP
846         // (0b11).
847         FATAL("Executing PACIBSP with wrong BType.");
848       case BranchFromUnguardedOrToIP:
849       case BranchAndLink:
850         break;
851       case DefaultBType:
852         UNREACHABLE();
853     }
854   }
855 
CheckBTypeForBti()856   void CheckBTypeForBti() {
857     DCHECK(pc_->IsBti());
858     switch (pc_->ImmHint()) {
859       case BTI_jc:
860         break;
861       case BTI: {
862         DCHECK(btype() != DefaultBType);
863         FATAL("Executing BTI with wrong BType (expected 0, got %d).", btype());
864         break;
865       }
866       case BTI_c:
867         if (btype() == BranchFromGuardedNotToIP) {
868           FATAL("Executing BTI c with wrong BType (3).");
869         }
870         break;
871       case BTI_j:
872         if (btype() == BranchAndLink) {
873           FATAL("Executing BTI j with wrong BType (2).");
874         }
875         break;
876       default:
877         UNIMPLEMENTED();
878     }
879   }
880 
CheckBType()881   void CheckBType() {
882     // On guarded pages, if BType is not zero, take an exception on any
883     // instruction other than BTI, PACI[AB]SP, HLT or BRK.
884     if (PcIsInGuardedPage() && (btype() != DefaultBType)) {
885       if (pc_->IsPAuth()) {
886         CheckBTypeForPAuth();
887       } else if (pc_->IsBti()) {
888         CheckBTypeForBti();
889       } else if (!pc_->IsException()) {
890         FATAL("Executing non-BTI instruction with wrong BType.");
891       }
892     }
893   }
894 
ExecuteInstruction()895   void ExecuteInstruction() {
896     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstrSize));
897     CheckBType();
898     ResetBType();
899     CheckBreakNext();
900     Decode(pc_);
901     increment_pc();
902     LogAllWrittenRegisters();
903     CheckBreakpoints();
904   }
905 
906 // Declare all Visitor functions.
907 #define DECLARE(A) void Visit##A(Instruction* instr);
VISITOR_LIST(DECLARE)908   VISITOR_LIST(DECLARE)
909 #undef DECLARE
910 
911   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const {
912     return ((code == 31) && (r31mode == Reg31IsZeroRegister));
913   }
914 
915   // Register accessors.
916   // Return 'size' bits of the value of an integer register, as the specified
917   // type. The value is zero-extended to fill the result.
918   //
919   template <typename T>
920   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
921     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters));
922     if (IsZeroRegister(code, r31mode)) {
923       return 0;
924     }
925     return registers_[code].Get<T>();
926   }
927 
928   // Common specialized accessors for the reg() template.
929   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
930     return reg<int32_t>(code, r31mode);
931   }
932 
933   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
934     return reg<int64_t>(code, r31mode);
935   }
936 
937   enum RegLogMode { LogRegWrites, NoRegLog };
938 
939   // Write 'value' into an integer register. The value is zero-extended. This
940   // behaviour matches AArch64 register writes.
941   template <typename T>
942   void set_reg(unsigned code, T value,
943                Reg31Mode r31mode = Reg31IsZeroRegister) {
944     set_reg_no_log(code, value, r31mode);
945     LogRegister(code, r31mode);
946   }
947 
948   // Common specialized accessors for the set_reg() template.
949   void set_wreg(unsigned code, int32_t value,
950                 Reg31Mode r31mode = Reg31IsZeroRegister) {
951     set_reg(code, value, r31mode);
952   }
953 
954   void set_xreg(unsigned code, int64_t value,
955                 Reg31Mode r31mode = Reg31IsZeroRegister) {
956     set_reg(code, value, r31mode);
957   }
958 
959   // As above, but don't automatically log the register update.
960   template <typename T>
961   void set_reg_no_log(unsigned code, T value,
962                       Reg31Mode r31mode = Reg31IsZeroRegister) {
963     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters));
964     if (!IsZeroRegister(code, r31mode)) {
965       registers_[code].Set(value);
966     }
967   }
968 
969   void set_wreg_no_log(unsigned code, int32_t value,
970                        Reg31Mode r31mode = Reg31IsZeroRegister) {
971     set_reg_no_log(code, value, r31mode);
972   }
973 
974   void set_xreg_no_log(unsigned code, int64_t value,
975                        Reg31Mode r31mode = Reg31IsZeroRegister) {
976     set_reg_no_log(code, value, r31mode);
977   }
978 
979   // Commonly-used special cases.
980   template <typename T>
set_lr(T value)981   void set_lr(T value) {
982     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kSystemPointerSize));
983     set_reg(kLinkRegCode, value);
984   }
985 
986   template <typename T>
set_sp(T value)987   void set_sp(T value) {
988     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kSystemPointerSize));
989     set_reg(31, value, Reg31IsStackPointer);
990   }
991 
992   // Vector register accessors.
993   // These are equivalent to the integer register accessors, but for vector
994   // registers.
995 
996   // A structure for representing a 128-bit Q register.
997   struct qreg_t {
998     uint8_t val[kQRegSize];
999   };
1000 
1001   // Basic accessor: read the register as the specified type.
1002   template <typename T>
vreg(unsigned code)1003   T vreg(unsigned code) const {
1004     static_assert((sizeof(T) == kBRegSize) || (sizeof(T) == kHRegSize) ||
1005                       (sizeof(T) == kSRegSize) || (sizeof(T) == kDRegSize) ||
1006                       (sizeof(T) == kQRegSize),
1007                   "Template type must match size of register.");
1008     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
1009 
1010     return vregisters_[code].Get<T>();
1011   }
1012 
vreg(unsigned code)1013   inline SimVRegister& vreg(unsigned code) { return vregisters_[code]; }
1014 
sp()1015   int64_t sp() { return xreg(31, Reg31IsStackPointer); }
fp()1016   int64_t fp() { return xreg(kFramePointerRegCode, Reg31IsStackPointer); }
lr()1017   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); }
1018 
get_sp()1019   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); }
1020 
1021   // Common specialized accessors for the vreg() template.
breg(unsigned code)1022   uint8_t breg(unsigned code) const { return vreg<uint8_t>(code); }
1023 
hreg(unsigned code)1024   float hreg(unsigned code) const { return vreg<uint16_t>(code); }
1025 
sreg(unsigned code)1026   float sreg(unsigned code) const { return vreg<float>(code); }
1027 
sreg_bits(unsigned code)1028   uint32_t sreg_bits(unsigned code) const { return vreg<uint32_t>(code); }
1029 
dreg(unsigned code)1030   double dreg(unsigned code) const { return vreg<double>(code); }
1031 
dreg_bits(unsigned code)1032   uint64_t dreg_bits(unsigned code) const { return vreg<uint64_t>(code); }
1033 
qreg(unsigned code)1034   qreg_t qreg(unsigned code) const { return vreg<qreg_t>(code); }
1035 
1036   // As above, with parameterized size and return type. The value is
1037   // either zero-extended or truncated to fit, as required.
1038   template <typename T>
vreg(unsigned size,unsigned code)1039   T vreg(unsigned size, unsigned code) const {
1040     uint64_t raw = 0;
1041     T result;
1042 
1043     switch (size) {
1044       case kSRegSize:
1045         raw = vreg<uint32_t>(code);
1046         break;
1047       case kDRegSize:
1048         raw = vreg<uint64_t>(code);
1049         break;
1050       default:
1051         UNREACHABLE();
1052     }
1053 
1054     static_assert(sizeof(result) <= sizeof(raw),
1055                   "Template type must be <= 64 bits.");
1056     // Copy the result and truncate to fit. This assumes a little-endian host.
1057     memcpy(&result, &raw, sizeof(result));
1058     return result;
1059   }
1060 
1061   // Write 'value' into a floating-point register. The value is zero-extended.
1062   // This behaviour matches AArch64 register writes.
1063   template <typename T>
1064   void set_vreg(unsigned code, T value, RegLogMode log_mode = LogRegWrites) {
1065     static_assert(
1066         (sizeof(value) == kBRegSize) || (sizeof(value) == kHRegSize) ||
1067             (sizeof(value) == kSRegSize) || (sizeof(value) == kDRegSize) ||
1068             (sizeof(value) == kQRegSize),
1069         "Template type must match size of register.");
1070     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
1071     vregisters_[code].Set(value);
1072 
1073     if (log_mode == LogRegWrites) {
1074       LogVRegister(code, GetPrintRegisterFormat(value));
1075     }
1076   }
1077 
1078   // Common specialized accessors for the set_vreg() template.
1079   void set_breg(unsigned code, int8_t value,
1080                 RegLogMode log_mode = LogRegWrites) {
1081     set_vreg(code, value, log_mode);
1082   }
1083 
1084   void set_hreg(unsigned code, int16_t value,
1085                 RegLogMode log_mode = LogRegWrites) {
1086     set_vreg(code, value, log_mode);
1087   }
1088 
1089   void set_sreg(unsigned code, float value,
1090                 RegLogMode log_mode = LogRegWrites) {
1091     set_vreg(code, value, log_mode);
1092   }
1093 
1094   void set_sreg_bits(unsigned code, uint32_t value,
1095                      RegLogMode log_mode = LogRegWrites) {
1096     set_vreg(code, value, log_mode);
1097   }
1098 
1099   void set_dreg(unsigned code, double value,
1100                 RegLogMode log_mode = LogRegWrites) {
1101     set_vreg(code, value, log_mode);
1102   }
1103 
1104   void set_dreg_bits(unsigned code, uint64_t value,
1105                      RegLogMode log_mode = LogRegWrites) {
1106     set_vreg(code, value, log_mode);
1107   }
1108 
1109   void set_qreg(unsigned code, qreg_t value,
1110                 RegLogMode log_mode = LogRegWrites) {
1111     set_vreg(code, value, log_mode);
1112   }
1113 
1114   // As above, but don't automatically log the register update.
1115   template <typename T>
set_vreg_no_log(unsigned code,T value)1116   void set_vreg_no_log(unsigned code, T value) {
1117     STATIC_ASSERT((sizeof(value) == kBRegSize) ||
1118                   (sizeof(value) == kHRegSize) ||
1119                   (sizeof(value) == kSRegSize) ||
1120                   (sizeof(value) == kDRegSize) || (sizeof(value) == kQRegSize));
1121     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters));
1122     vregisters_[code].Set(value);
1123   }
1124 
set_breg_no_log(unsigned code,uint8_t value)1125   void set_breg_no_log(unsigned code, uint8_t value) {
1126     set_vreg_no_log(code, value);
1127   }
1128 
set_hreg_no_log(unsigned code,uint16_t value)1129   void set_hreg_no_log(unsigned code, uint16_t value) {
1130     set_vreg_no_log(code, value);
1131   }
1132 
set_sreg_no_log(unsigned code,float value)1133   void set_sreg_no_log(unsigned code, float value) {
1134     set_vreg_no_log(code, value);
1135   }
1136 
set_dreg_no_log(unsigned code,double value)1137   void set_dreg_no_log(unsigned code, double value) {
1138     set_vreg_no_log(code, value);
1139   }
1140 
set_qreg_no_log(unsigned code,qreg_t value)1141   void set_qreg_no_log(unsigned code, qreg_t value) {
1142     set_vreg_no_log(code, value);
1143   }
1144 
nzcv()1145   SimSystemRegister& nzcv() { return nzcv_; }
fpcr()1146   SimSystemRegister& fpcr() { return fpcr_; }
RMode()1147   FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); }
DN()1148   bool DN() { return fpcr_.DN() != 0; }
1149 
1150   // Debug helpers
1151 
1152   // Simulator breakpoints.
1153   struct Breakpoint {
1154     Instruction* location;
1155     bool enabled;
1156   };
1157   std::vector<Breakpoint> breakpoints_;
1158   void SetBreakpoint(Instruction* breakpoint);
1159   void ListBreakpoints();
1160   void CheckBreakpoints();
1161 
1162   // Helpers for the 'next' command.
1163   // When this is set, the Simulator will insert a breakpoint after the next BL
1164   // instruction it meets.
1165   bool break_on_next_;
1166   // Check if the Simulator should insert a break after the current instruction
1167   // for the 'next' command.
1168   void CheckBreakNext();
1169 
1170   // Disassemble instruction at the given address.
1171   void PrintInstructionsAt(Instruction* pc, uint64_t count);
1172 
1173   // Print all registers of the specified types.
1174   void PrintRegisters();
1175   void PrintVRegisters();
1176   void PrintSystemRegisters();
1177 
1178   // As above, but only print the registers that have been updated.
1179   void PrintWrittenRegisters();
1180   void PrintWrittenVRegisters();
1181 
1182   // As above, but respect LOG_REG and LOG_VREG.
LogWrittenRegisters()1183   void LogWrittenRegisters() {
1184     if (log_parameters() & LOG_REGS) PrintWrittenRegisters();
1185   }
LogWrittenVRegisters()1186   void LogWrittenVRegisters() {
1187     if (log_parameters() & LOG_VREGS) PrintWrittenVRegisters();
1188   }
LogAllWrittenRegisters()1189   void LogAllWrittenRegisters() {
1190     LogWrittenRegisters();
1191     LogWrittenVRegisters();
1192   }
1193 
1194   // Specify relevant register formats for Print(V)Register and related helpers.
1195   enum PrintRegisterFormat {
1196     // The lane size.
1197     kPrintRegLaneSizeB = 0 << 0,
1198     kPrintRegLaneSizeH = 1 << 0,
1199     kPrintRegLaneSizeS = 2 << 0,
1200     kPrintRegLaneSizeW = kPrintRegLaneSizeS,
1201     kPrintRegLaneSizeD = 3 << 0,
1202     kPrintRegLaneSizeX = kPrintRegLaneSizeD,
1203     kPrintRegLaneSizeQ = 4 << 0,
1204 
1205     kPrintRegLaneSizeOffset = 0,
1206     kPrintRegLaneSizeMask = 7 << 0,
1207 
1208     // The lane count.
1209     kPrintRegAsScalar = 0,
1210     kPrintRegAsDVector = 1 << 3,
1211     kPrintRegAsQVector = 2 << 3,
1212 
1213     kPrintRegAsVectorMask = 3 << 3,
1214 
1215     // Indicate floating-point format lanes. (This flag is only supported for S-
1216     // and D-sized lanes.)
1217     kPrintRegAsFP = 1 << 5,
1218 
1219     // Supported combinations.
1220 
1221     kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
1222     kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
1223     kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1224     kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1225 
1226     kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
1227     kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
1228     kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
1229     kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
1230     kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
1231     kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
1232     kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
1233     kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
1234     kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
1235     kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
1236     kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
1237     kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
1238     kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
1239     kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
1240     kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
1241     kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
1242     kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
1243   };
1244 
GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format)1245   unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
1246     return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
1247   }
1248 
GetPrintRegLaneSizeInBytes(PrintRegisterFormat format)1249   unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
1250     return 1 << GetPrintRegLaneSizeInBytesLog2(format);
1251   }
1252 
GetPrintRegSizeInBytesLog2(PrintRegisterFormat format)1253   unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
1254     if (format & kPrintRegAsDVector) return kDRegSizeLog2;
1255     if (format & kPrintRegAsQVector) return kQRegSizeLog2;
1256 
1257     // Scalar types.
1258     return GetPrintRegLaneSizeInBytesLog2(format);
1259   }
1260 
GetPrintRegSizeInBytes(PrintRegisterFormat format)1261   unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
1262     return 1 << GetPrintRegSizeInBytesLog2(format);
1263   }
1264 
GetPrintRegLaneCount(PrintRegisterFormat format)1265   unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
1266     unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
1267     unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
1268     DCHECK_GE(reg_size_log2, lane_size_log2);
1269     return 1 << (reg_size_log2 - lane_size_log2);
1270   }
1271 
1272   template <typename T>
GetPrintRegisterFormat(T value)1273   PrintRegisterFormat GetPrintRegisterFormat(T value) {
1274     return GetPrintRegisterFormatForSize(sizeof(value));
1275   }
1276 
GetPrintRegisterFormat(double value)1277   PrintRegisterFormat GetPrintRegisterFormat(double value) {
1278     static_assert(sizeof(value) == kDRegSize,
1279                   "D register must be size of double.");
1280     return GetPrintRegisterFormatForSizeFP(sizeof(value));
1281   }
1282 
GetPrintRegisterFormat(float value)1283   PrintRegisterFormat GetPrintRegisterFormat(float value) {
1284     static_assert(sizeof(value) == kSRegSize,
1285                   "S register must be size of float.");
1286     return GetPrintRegisterFormatForSizeFP(sizeof(value));
1287   }
1288 
1289   PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
1290   PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
1291 
1292   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t reg_size,
1293                                                     size_t lane_size);
1294 
GetPrintRegisterFormatForSize(size_t size)1295   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t size) {
1296     return GetPrintRegisterFormatForSize(size, size);
1297   }
1298 
GetPrintRegisterFormatForSizeFP(size_t size)1299   PrintRegisterFormat GetPrintRegisterFormatForSizeFP(size_t size) {
1300     switch (size) {
1301       default:
1302         UNREACHABLE();
1303       case kDRegSize:
1304         return kPrintDReg;
1305       case kSRegSize:
1306         return kPrintSReg;
1307     }
1308   }
1309 
GetPrintRegisterFormatTryFP(PrintRegisterFormat format)1310   PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
1311     if ((GetPrintRegLaneSizeInBytes(format) == kSRegSize) ||
1312         (GetPrintRegLaneSizeInBytes(format) == kDRegSize)) {
1313       return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
1314     }
1315     return format;
1316   }
1317 
1318   // Print individual register values (after update).
1319   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
1320   void PrintVRegister(unsigned code, PrintRegisterFormat sizes);
1321   void PrintSystemRegister(SystemRegister id);
1322 
1323   // Like Print* (above), but respect log_parameters().
1324   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
1325     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode);
1326   }
LogVRegister(unsigned code,PrintRegisterFormat format)1327   void LogVRegister(unsigned code, PrintRegisterFormat format) {
1328     if (log_parameters() & LOG_VREGS) PrintVRegister(code, format);
1329   }
LogSystemRegister(SystemRegister id)1330   void LogSystemRegister(SystemRegister id) {
1331     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id);
1332   }
1333 
1334   // Print memory accesses.
1335   void PrintRead(uintptr_t address, unsigned reg_code,
1336                  PrintRegisterFormat format);
1337   void PrintWrite(uintptr_t address, unsigned reg_code,
1338                   PrintRegisterFormat format);
1339   void PrintVRead(uintptr_t address, unsigned reg_code,
1340                   PrintRegisterFormat format, unsigned lane);
1341   void PrintVWrite(uintptr_t address, unsigned reg_code,
1342                    PrintRegisterFormat format, unsigned lane);
1343 
1344   // Like Print* (above), but respect log_parameters().
LogRead(uintptr_t address,unsigned reg_code,PrintRegisterFormat format)1345   void LogRead(uintptr_t address, unsigned reg_code,
1346                PrintRegisterFormat format) {
1347     if (log_parameters() & LOG_REGS) PrintRead(address, reg_code, format);
1348   }
LogWrite(uintptr_t address,unsigned reg_code,PrintRegisterFormat format)1349   void LogWrite(uintptr_t address, unsigned reg_code,
1350                 PrintRegisterFormat format) {
1351     if (log_parameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
1352   }
1353   void LogVRead(uintptr_t address, unsigned reg_code,
1354                 PrintRegisterFormat format, unsigned lane = 0) {
1355     if (log_parameters() & LOG_VREGS) {
1356       PrintVRead(address, reg_code, format, lane);
1357     }
1358   }
1359   void LogVWrite(uintptr_t address, unsigned reg_code,
1360                  PrintRegisterFormat format, unsigned lane = 0) {
1361     if (log_parameters() & LOG_WRITE) {
1362       PrintVWrite(address, reg_code, format, lane);
1363     }
1364   }
1365 
log_parameters()1366   int log_parameters() { return log_parameters_; }
set_log_parameters(int new_parameters)1367   void set_log_parameters(int new_parameters) {
1368     log_parameters_ = new_parameters;
1369     if (!decoder_) {
1370       if (new_parameters & LOG_DISASM) {
1371         PrintF("Run --debug-sim to dynamically turn on disassembler\n");
1372       }
1373       return;
1374     }
1375     if (new_parameters & LOG_DISASM) {
1376       decoder_->InsertVisitorBefore(print_disasm_, this);
1377     } else {
1378       decoder_->RemoveVisitor(print_disasm_);
1379     }
1380   }
1381 
1382   // Helper functions for register tracing.
1383   void PrintRegisterRawHelper(unsigned code, Reg31Mode r31mode,
1384                               int size_in_bytes = kXRegSize);
1385   void PrintVRegisterRawHelper(unsigned code, int bytes = kQRegSize,
1386                                int lsb = 0);
1387   void PrintVRegisterFPHelper(unsigned code, unsigned lane_size_in_bytes,
1388                               int lane_count = 1, int rightmost_lane = 0);
1389 
1390   static inline const char* WRegNameForCode(
1391       unsigned code, Reg31Mode mode = Reg31IsZeroRegister);
1392   static inline const char* XRegNameForCode(
1393       unsigned code, Reg31Mode mode = Reg31IsZeroRegister);
1394   static inline const char* SRegNameForCode(unsigned code);
1395   static inline const char* DRegNameForCode(unsigned code);
1396   static inline const char* VRegNameForCode(unsigned code);
1397   static inline int CodeFromName(const char* name);
1398 
1399   enum PointerType { kDataPointer, kInstructionPointer };
1400 
1401   struct PACKey {
1402     uint64_t high;
1403     uint64_t low;
1404     int number;
1405   };
1406 
1407   static const PACKey kPACKeyIB;
1408 
1409   // Current implementation is that all pointers are tagged.
HasTBI(uint64_t ptr,PointerType type)1410   static bool HasTBI(uint64_t ptr, PointerType type) {
1411     USE(ptr, type);
1412     return true;
1413   }
1414 
1415   // Current implementation uses 48-bit virtual addresses.
GetBottomPACBit(uint64_t ptr,int ttbr)1416   static int GetBottomPACBit(uint64_t ptr, int ttbr) {
1417     USE(ptr, ttbr);
1418     DCHECK((ttbr == 0) || (ttbr == 1));
1419     return 48;
1420   }
1421 
1422   // The top PAC bit is 55 for the purposes of relative bit fields with TBI,
1423   // however bit 55 is the TTBR bit regardless of TBI so isn't part of the PAC
1424   // codes in pointers.
GetTopPACBit(uint64_t ptr,PointerType type)1425   static int GetTopPACBit(uint64_t ptr, PointerType type) {
1426     return HasTBI(ptr, type) ? 55 : 63;
1427   }
1428 
1429   // Armv8.3 Pointer authentication helpers.
1430   V8_EXPORT_PRIVATE static uint64_t CalculatePACMask(uint64_t ptr,
1431                                                      PointerType type,
1432                                                      int ext_bit);
1433   V8_EXPORT_PRIVATE static uint64_t ComputePAC(uint64_t data, uint64_t context,
1434                                                PACKey key);
1435   V8_EXPORT_PRIVATE static uint64_t AuthPAC(uint64_t ptr, uint64_t context,
1436                                             PACKey key, PointerType type);
1437   V8_EXPORT_PRIVATE static uint64_t AddPAC(uint64_t ptr, uint64_t context,
1438                                            PACKey key, PointerType type);
1439   V8_EXPORT_PRIVATE static uint64_t StripPAC(uint64_t ptr, PointerType type);
1440 
1441  protected:
1442   // Simulation helpers ------------------------------------
ConditionPassed(Condition cond)1443   bool ConditionPassed(Condition cond) {
1444     SimSystemRegister& flags = nzcv();
1445     switch (cond) {
1446       case eq:
1447         return flags.Z();
1448       case ne:
1449         return !flags.Z();
1450       case hs:
1451         return flags.C();
1452       case lo:
1453         return !flags.C();
1454       case mi:
1455         return flags.N();
1456       case pl:
1457         return !flags.N();
1458       case vs:
1459         return flags.V();
1460       case vc:
1461         return !flags.V();
1462       case hi:
1463         return flags.C() && !flags.Z();
1464       case ls:
1465         return !(flags.C() && !flags.Z());
1466       case ge:
1467         return flags.N() == flags.V();
1468       case lt:
1469         return flags.N() != flags.V();
1470       case gt:
1471         return !flags.Z() && (flags.N() == flags.V());
1472       case le:
1473         return !(!flags.Z() && (flags.N() == flags.V()));
1474       case nv:  // Fall through.
1475       case al:
1476         return true;
1477       default:
1478         UNREACHABLE();
1479     }
1480   }
1481 
ConditionFailed(Condition cond)1482   bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1483 
1484   template <typename T>
1485   void AddSubHelper(Instruction* instr, T op2);
1486   template <typename T>
1487   T AddWithCarry(bool set_flags, T left, T right, int carry_in = 0);
1488   template <typename T>
1489   void AddSubWithCarry(Instruction* instr);
1490   template <typename T>
1491   void LogicalHelper(Instruction* instr, T op2);
1492   template <typename T>
1493   void ConditionalCompareHelper(Instruction* instr, T op2);
1494   void LoadStoreHelper(Instruction* instr, int64_t offset, AddrMode addrmode);
1495   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode);
1496   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset,
1497                              AddrMode addrmode);
1498   void LoadStoreWriteBack(unsigned addr_reg, int64_t offset, AddrMode addrmode);
1499   void NEONLoadStoreMultiStructHelper(const Instruction* instr,
1500                                       AddrMode addr_mode);
1501   void NEONLoadStoreSingleStructHelper(const Instruction* instr,
1502                                        AddrMode addr_mode);
1503   void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
1504 
1505   // "Probe" if an address range can be read. This is currently implemented
1506   // by doing a 1-byte read of the last accessed byte, since the assumption is
1507   // that if the last byte is accessible, also all lower bytes are accessible
1508   // (which holds true for Wasm).
1509   // Returns true if the access was successful, false if the access raised a
1510   // signal which was then handled by the trap handler (also see
1511   // {trap_handler::ProbeMemory}). If the access raises a signal which is not
1512   // handled by the trap handler (e.g. because the current PC is not registered
1513   // as a protected instruction), the signal will propagate and make the process
1514   // crash. If no trap handler is available, this always returns true.
1515   bool ProbeMemory(uintptr_t address, uintptr_t access_size);
1516 
1517   // Memory read helpers.
1518   template <typename T, typename A>
MemoryRead(A address)1519   T MemoryRead(A address) {
1520     T value;
1521     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
1522                   (sizeof(value) == 4) || (sizeof(value) == 8) ||
1523                   (sizeof(value) == 16));
1524     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
1525     return value;
1526   }
1527 
1528   // Memory write helpers.
1529   template <typename T, typename A>
MemoryWrite(A address,T value)1530   void MemoryWrite(A address, T value) {
1531     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
1532                   (sizeof(value) == 4) || (sizeof(value) == 8) ||
1533                   (sizeof(value) == 16));
1534     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
1535   }
1536 
1537   template <typename T>
1538   T ShiftOperand(T value, Shift shift_type, unsigned amount);
1539   template <typename T>
1540   T ExtendValue(T value, Extend extend_type, unsigned left_shift = 0);
1541   template <typename T>
1542   void Extract(Instruction* instr);
1543   template <typename T>
1544   void DataProcessing2Source(Instruction* instr);
1545   template <typename T>
1546   void BitfieldHelper(Instruction* instr);
1547   uint16_t PolynomialMult(uint8_t op1, uint8_t op2);
1548 
1549   void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1550   void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
1551   void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
1552   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1553            uint64_t addr);
1554   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1555            int index, uint64_t addr);
1556   void ld2r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1557             uint64_t addr);
1558   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1559            LogicVRegister dst3, uint64_t addr);
1560   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1561            LogicVRegister dst3, int index, uint64_t addr);
1562   void ld3r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1563             LogicVRegister dst3, uint64_t addr);
1564   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1565            LogicVRegister dst3, LogicVRegister dst4, uint64_t addr);
1566   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1567            LogicVRegister dst3, LogicVRegister dst4, int index, uint64_t addr);
1568   void ld4r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2,
1569             LogicVRegister dst3, LogicVRegister dst4, uint64_t addr);
1570   void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
1571   void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
1572   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1573            uint64_t addr);
1574   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1575            int index, uint64_t addr);
1576   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1577            LogicVRegister src3, uint64_t addr);
1578   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1579            LogicVRegister src3, int index, uint64_t addr);
1580   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1581            LogicVRegister src3, LogicVRegister src4, uint64_t addr);
1582   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2,
1583            LogicVRegister src3, LogicVRegister src4, int index, uint64_t addr);
1584   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst,
1585                      const LogicVRegister& src1, const LogicVRegister& src2,
1586                      Condition cond);
1587   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst,
1588                      const LogicVRegister& src1, int imm, Condition cond);
1589   LogicVRegister cmptst(VectorFormat vform, LogicVRegister dst,
1590                         const LogicVRegister& src1, const LogicVRegister& src2);
1591   LogicVRegister add(VectorFormat vform, LogicVRegister dst,
1592                      const LogicVRegister& src1, const LogicVRegister& src2);
1593   LogicVRegister addp(VectorFormat vform, LogicVRegister dst,
1594                       const LogicVRegister& src1, const LogicVRegister& src2);
1595   LogicVRegister mla(VectorFormat vform, LogicVRegister dst,
1596                      const LogicVRegister& src1, const LogicVRegister& src2);
1597   LogicVRegister mls(VectorFormat vform, LogicVRegister dst,
1598                      const LogicVRegister& src1, const LogicVRegister& src2);
1599   LogicVRegister mul(VectorFormat vform, LogicVRegister dst,
1600                      const LogicVRegister& src1, const LogicVRegister& src2);
1601   LogicVRegister mul(VectorFormat vform, LogicVRegister dst,
1602                      const LogicVRegister& src1, const LogicVRegister& src2,
1603                      int index);
1604   LogicVRegister mla(VectorFormat vform, LogicVRegister dst,
1605                      const LogicVRegister& src1, const LogicVRegister& src2,
1606                      int index);
1607   LogicVRegister mls(VectorFormat vform, LogicVRegister dst,
1608                      const LogicVRegister& src1, const LogicVRegister& src2,
1609                      int index);
1610   LogicVRegister pmul(VectorFormat vform, LogicVRegister dst,
1611                       const LogicVRegister& src1, const LogicVRegister& src2);
1612 
1613   using ByElementOp = LogicVRegister (Simulator::*)(VectorFormat vform,
1614                                                     LogicVRegister dst,
1615                                                     const LogicVRegister& src1,
1616                                                     const LogicVRegister& src2,
1617                                                     int index);
1618   LogicVRegister fmul(VectorFormat vform, LogicVRegister dst,
1619                       const LogicVRegister& src1, const LogicVRegister& src2,
1620                       int index);
1621   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
1622                       const LogicVRegister& src1, const LogicVRegister& src2,
1623                       int index);
1624   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
1625                       const LogicVRegister& src1, const LogicVRegister& src2,
1626                       int index);
1627   LogicVRegister fmulx(VectorFormat vform, LogicVRegister dst,
1628                        const LogicVRegister& src1, const LogicVRegister& src2,
1629                        int index);
1630   LogicVRegister smull(VectorFormat vform, LogicVRegister dst,
1631                        const LogicVRegister& src1, const LogicVRegister& src2,
1632                        int index);
1633   LogicVRegister smull2(VectorFormat vform, LogicVRegister dst,
1634                         const LogicVRegister& src1, const LogicVRegister& src2,
1635                         int index);
1636   LogicVRegister umull(VectorFormat vform, LogicVRegister dst,
1637                        const LogicVRegister& src1, const LogicVRegister& src2,
1638                        int index);
1639   LogicVRegister umull2(VectorFormat vform, LogicVRegister dst,
1640                         const LogicVRegister& src1, const LogicVRegister& src2,
1641                         int index);
1642   LogicVRegister smlal(VectorFormat vform, LogicVRegister dst,
1643                        const LogicVRegister& src1, const LogicVRegister& src2,
1644                        int index);
1645   LogicVRegister smlal2(VectorFormat vform, LogicVRegister dst,
1646                         const LogicVRegister& src1, const LogicVRegister& src2,
1647                         int index);
1648   LogicVRegister umlal(VectorFormat vform, LogicVRegister dst,
1649                        const LogicVRegister& src1, const LogicVRegister& src2,
1650                        int index);
1651   LogicVRegister umlal2(VectorFormat vform, LogicVRegister dst,
1652                         const LogicVRegister& src1, const LogicVRegister& src2,
1653                         int index);
1654   LogicVRegister smlsl(VectorFormat vform, LogicVRegister dst,
1655                        const LogicVRegister& src1, const LogicVRegister& src2,
1656                        int index);
1657   LogicVRegister smlsl2(VectorFormat vform, LogicVRegister dst,
1658                         const LogicVRegister& src1, const LogicVRegister& src2,
1659                         int index);
1660   LogicVRegister umlsl(VectorFormat vform, LogicVRegister dst,
1661                        const LogicVRegister& src1, const LogicVRegister& src2,
1662                        int index);
1663   LogicVRegister umlsl2(VectorFormat vform, LogicVRegister dst,
1664                         const LogicVRegister& src1, const LogicVRegister& src2,
1665                         int index);
1666   LogicVRegister sqdmull(VectorFormat vform, LogicVRegister dst,
1667                          const LogicVRegister& src1, const LogicVRegister& src2,
1668                          int index);
1669   LogicVRegister sqdmull2(VectorFormat vform, LogicVRegister dst,
1670                           const LogicVRegister& src1,
1671                           const LogicVRegister& src2, int index);
1672   LogicVRegister sqdmlal(VectorFormat vform, LogicVRegister dst,
1673                          const LogicVRegister& src1, const LogicVRegister& src2,
1674                          int index);
1675   LogicVRegister sqdmlal2(VectorFormat vform, LogicVRegister dst,
1676                           const LogicVRegister& src1,
1677                           const LogicVRegister& src2, int index);
1678   LogicVRegister sqdmlsl(VectorFormat vform, LogicVRegister dst,
1679                          const LogicVRegister& src1, const LogicVRegister& src2,
1680                          int index);
1681   LogicVRegister sqdmlsl2(VectorFormat vform, LogicVRegister dst,
1682                           const LogicVRegister& src1,
1683                           const LogicVRegister& src2, int index);
1684   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst,
1685                          const LogicVRegister& src1, const LogicVRegister& src2,
1686                          int index);
1687   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst,
1688                           const LogicVRegister& src1,
1689                           const LogicVRegister& src2, int index);
1690   LogicVRegister sub(VectorFormat vform, LogicVRegister dst,
1691                      const LogicVRegister& src1, const LogicVRegister& src2);
1692   LogicVRegister and_(VectorFormat vform, LogicVRegister dst,
1693                       const LogicVRegister& src1, const LogicVRegister& src2);
1694   LogicVRegister orr(VectorFormat vform, LogicVRegister dst,
1695                      const LogicVRegister& src1, const LogicVRegister& src2);
1696   LogicVRegister orn(VectorFormat vform, LogicVRegister dst,
1697                      const LogicVRegister& src1, const LogicVRegister& src2);
1698   LogicVRegister eor(VectorFormat vform, LogicVRegister dst,
1699                      const LogicVRegister& src1, const LogicVRegister& src2);
1700   LogicVRegister bic(VectorFormat vform, LogicVRegister dst,
1701                      const LogicVRegister& src1, const LogicVRegister& src2);
1702   LogicVRegister bic(VectorFormat vform, LogicVRegister dst,
1703                      const LogicVRegister& src, uint64_t imm);
1704   LogicVRegister bif(VectorFormat vform, LogicVRegister dst,
1705                      const LogicVRegister& src1, const LogicVRegister& src2);
1706   LogicVRegister bit(VectorFormat vform, LogicVRegister dst,
1707                      const LogicVRegister& src1, const LogicVRegister& src2);
1708   LogicVRegister bsl(VectorFormat vform, LogicVRegister dst,
1709                      const LogicVRegister& src1, const LogicVRegister& src2);
1710   LogicVRegister cls(VectorFormat vform, LogicVRegister dst,
1711                      const LogicVRegister& src);
1712   LogicVRegister clz(VectorFormat vform, LogicVRegister dst,
1713                      const LogicVRegister& src);
1714   LogicVRegister cnt(VectorFormat vform, LogicVRegister dst,
1715                      const LogicVRegister& src);
1716   LogicVRegister not_(VectorFormat vform, LogicVRegister dst,
1717                       const LogicVRegister& src);
1718   LogicVRegister rbit(VectorFormat vform, LogicVRegister dst,
1719                       const LogicVRegister& src);
1720   LogicVRegister rev(VectorFormat vform, LogicVRegister dst,
1721                      const LogicVRegister& src, int revSize);
1722   LogicVRegister rev16(VectorFormat vform, LogicVRegister dst,
1723                        const LogicVRegister& src);
1724   LogicVRegister rev32(VectorFormat vform, LogicVRegister dst,
1725                        const LogicVRegister& src);
1726   LogicVRegister rev64(VectorFormat vform, LogicVRegister dst,
1727                        const LogicVRegister& src);
1728   LogicVRegister addlp(VectorFormat vform, LogicVRegister dst,
1729                        const LogicVRegister& src, bool is_signed,
1730                        bool do_accumulate);
1731   LogicVRegister saddlp(VectorFormat vform, LogicVRegister dst,
1732                         const LogicVRegister& src);
1733   LogicVRegister uaddlp(VectorFormat vform, LogicVRegister dst,
1734                         const LogicVRegister& src);
1735   LogicVRegister sadalp(VectorFormat vform, LogicVRegister dst,
1736                         const LogicVRegister& src);
1737   LogicVRegister uadalp(VectorFormat vform, LogicVRegister dst,
1738                         const LogicVRegister& src);
1739   LogicVRegister ext(VectorFormat vform, LogicVRegister dst,
1740                      const LogicVRegister& src1, const LogicVRegister& src2,
1741                      int index);
1742   LogicVRegister ins_element(VectorFormat vform, LogicVRegister dst,
1743                              int dst_index, const LogicVRegister& src,
1744                              int src_index);
1745   LogicVRegister ins_immediate(VectorFormat vform, LogicVRegister dst,
1746                                int dst_index, uint64_t imm);
1747   LogicVRegister dup_element(VectorFormat vform, LogicVRegister dst,
1748                              const LogicVRegister& src, int src_index);
1749   LogicVRegister dup_immediate(VectorFormat vform, LogicVRegister dst,
1750                                uint64_t imm);
1751   LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
1752   LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
1753   LogicVRegister orr(VectorFormat vform, LogicVRegister dst,
1754                      const LogicVRegister& src, uint64_t imm);
1755   LogicVRegister sshl(VectorFormat vform, LogicVRegister dst,
1756                       const LogicVRegister& src1, const LogicVRegister& src2);
1757   LogicVRegister ushl(VectorFormat vform, LogicVRegister dst,
1758                       const LogicVRegister& src1, const LogicVRegister& src2);
1759   LogicVRegister SMinMax(VectorFormat vform, LogicVRegister dst,
1760                          const LogicVRegister& src1, const LogicVRegister& src2,
1761                          bool max);
1762   LogicVRegister smax(VectorFormat vform, LogicVRegister dst,
1763                       const LogicVRegister& src1, const LogicVRegister& src2);
1764   LogicVRegister smin(VectorFormat vform, LogicVRegister dst,
1765                       const LogicVRegister& src1, const LogicVRegister& src2);
1766   LogicVRegister SMinMaxP(VectorFormat vform, LogicVRegister dst,
1767                           const LogicVRegister& src1,
1768                           const LogicVRegister& src2, bool max);
1769   LogicVRegister smaxp(VectorFormat vform, LogicVRegister dst,
1770                        const LogicVRegister& src1, const LogicVRegister& src2);
1771   LogicVRegister sminp(VectorFormat vform, LogicVRegister dst,
1772                        const LogicVRegister& src1, const LogicVRegister& src2);
1773   LogicVRegister addp(VectorFormat vform, LogicVRegister dst,
1774                       const LogicVRegister& src);
1775   LogicVRegister addv(VectorFormat vform, LogicVRegister dst,
1776                       const LogicVRegister& src);
1777   LogicVRegister uaddlv(VectorFormat vform, LogicVRegister dst,
1778                         const LogicVRegister& src);
1779   LogicVRegister saddlv(VectorFormat vform, LogicVRegister dst,
1780                         const LogicVRegister& src);
1781   LogicVRegister SMinMaxV(VectorFormat vform, LogicVRegister dst,
1782                           const LogicVRegister& src, bool max);
1783   LogicVRegister smaxv(VectorFormat vform, LogicVRegister dst,
1784                        const LogicVRegister& src);
1785   LogicVRegister sminv(VectorFormat vform, LogicVRegister dst,
1786                        const LogicVRegister& src);
1787   LogicVRegister uxtl(VectorFormat vform, LogicVRegister dst,
1788                       const LogicVRegister& src);
1789   LogicVRegister uxtl2(VectorFormat vform, LogicVRegister dst,
1790                        const LogicVRegister& src);
1791   LogicVRegister sxtl(VectorFormat vform, LogicVRegister dst,
1792                       const LogicVRegister& src);
1793   LogicVRegister sxtl2(VectorFormat vform, LogicVRegister dst,
1794                        const LogicVRegister& src);
1795   LogicVRegister Table(VectorFormat vform, LogicVRegister dst,
1796                        const LogicVRegister& ind, bool zero_out_of_bounds,
1797                        const LogicVRegister* tab1,
1798                        const LogicVRegister* tab2 = nullptr,
1799                        const LogicVRegister* tab3 = nullptr,
1800                        const LogicVRegister* tab4 = nullptr);
1801   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
1802                      const LogicVRegister& tab, const LogicVRegister& ind);
1803   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
1804                      const LogicVRegister& tab, const LogicVRegister& tab2,
1805                      const LogicVRegister& ind);
1806   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
1807                      const LogicVRegister& tab, const LogicVRegister& tab2,
1808                      const LogicVRegister& tab3, const LogicVRegister& ind);
1809   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst,
1810                      const LogicVRegister& tab, const LogicVRegister& tab2,
1811                      const LogicVRegister& tab3, const LogicVRegister& tab4,
1812                      const LogicVRegister& ind);
1813   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
1814                      const LogicVRegister& tab, const LogicVRegister& ind);
1815   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
1816                      const LogicVRegister& tab, const LogicVRegister& tab2,
1817                      const LogicVRegister& ind);
1818   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
1819                      const LogicVRegister& tab, const LogicVRegister& tab2,
1820                      const LogicVRegister& tab3, const LogicVRegister& ind);
1821   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst,
1822                      const LogicVRegister& tab, const LogicVRegister& tab2,
1823                      const LogicVRegister& tab3, const LogicVRegister& tab4,
1824                      const LogicVRegister& ind);
1825   LogicVRegister uaddl(VectorFormat vform, LogicVRegister dst,
1826                        const LogicVRegister& src1, const LogicVRegister& src2);
1827   LogicVRegister uaddl2(VectorFormat vform, LogicVRegister dst,
1828                         const LogicVRegister& src1, const LogicVRegister& src2);
1829   LogicVRegister uaddw(VectorFormat vform, LogicVRegister dst,
1830                        const LogicVRegister& src1, const LogicVRegister& src2);
1831   LogicVRegister uaddw2(VectorFormat vform, LogicVRegister dst,
1832                         const LogicVRegister& src1, const LogicVRegister& src2);
1833   LogicVRegister saddl(VectorFormat vform, LogicVRegister dst,
1834                        const LogicVRegister& src1, const LogicVRegister& src2);
1835   LogicVRegister saddl2(VectorFormat vform, LogicVRegister dst,
1836                         const LogicVRegister& src1, const LogicVRegister& src2);
1837   LogicVRegister saddw(VectorFormat vform, LogicVRegister dst,
1838                        const LogicVRegister& src1, const LogicVRegister& src2);
1839   LogicVRegister saddw2(VectorFormat vform, LogicVRegister dst,
1840                         const LogicVRegister& src1, const LogicVRegister& src2);
1841   LogicVRegister usubl(VectorFormat vform, LogicVRegister dst,
1842                        const LogicVRegister& src1, const LogicVRegister& src2);
1843   LogicVRegister usubl2(VectorFormat vform, LogicVRegister dst,
1844                         const LogicVRegister& src1, const LogicVRegister& src2);
1845   LogicVRegister usubw(VectorFormat vform, LogicVRegister dst,
1846                        const LogicVRegister& src1, const LogicVRegister& src2);
1847   LogicVRegister usubw2(VectorFormat vform, LogicVRegister dst,
1848                         const LogicVRegister& src1, const LogicVRegister& src2);
1849   LogicVRegister ssubl(VectorFormat vform, LogicVRegister dst,
1850                        const LogicVRegister& src1, const LogicVRegister& src2);
1851   LogicVRegister ssubl2(VectorFormat vform, LogicVRegister dst,
1852                         const LogicVRegister& src1, const LogicVRegister& src2);
1853   LogicVRegister ssubw(VectorFormat vform, LogicVRegister dst,
1854                        const LogicVRegister& src1, const LogicVRegister& src2);
1855   LogicVRegister ssubw2(VectorFormat vform, LogicVRegister dst,
1856                         const LogicVRegister& src1, const LogicVRegister& src2);
1857   LogicVRegister UMinMax(VectorFormat vform, LogicVRegister dst,
1858                          const LogicVRegister& src1, const LogicVRegister& src2,
1859                          bool max);
1860   LogicVRegister umax(VectorFormat vform, LogicVRegister dst,
1861                       const LogicVRegister& src1, const LogicVRegister& src2);
1862   LogicVRegister umin(VectorFormat vform, LogicVRegister dst,
1863                       const LogicVRegister& src1, const LogicVRegister& src2);
1864   LogicVRegister UMinMaxP(VectorFormat vform, LogicVRegister dst,
1865                           const LogicVRegister& src1,
1866                           const LogicVRegister& src2, bool max);
1867   LogicVRegister umaxp(VectorFormat vform, LogicVRegister dst,
1868                        const LogicVRegister& src1, const LogicVRegister& src2);
1869   LogicVRegister uminp(VectorFormat vform, LogicVRegister dst,
1870                        const LogicVRegister& src1, const LogicVRegister& src2);
1871   LogicVRegister UMinMaxV(VectorFormat vform, LogicVRegister dst,
1872                           const LogicVRegister& src, bool max);
1873   LogicVRegister umaxv(VectorFormat vform, LogicVRegister dst,
1874                        const LogicVRegister& src);
1875   LogicVRegister uminv(VectorFormat vform, LogicVRegister dst,
1876                        const LogicVRegister& src);
1877   LogicVRegister trn1(VectorFormat vform, LogicVRegister dst,
1878                       const LogicVRegister& src1, const LogicVRegister& src2);
1879   LogicVRegister trn2(VectorFormat vform, LogicVRegister dst,
1880                       const LogicVRegister& src1, const LogicVRegister& src2);
1881   LogicVRegister zip1(VectorFormat vform, LogicVRegister dst,
1882                       const LogicVRegister& src1, const LogicVRegister& src2);
1883   LogicVRegister zip2(VectorFormat vform, LogicVRegister dst,
1884                       const LogicVRegister& src1, const LogicVRegister& src2);
1885   LogicVRegister uzp1(VectorFormat vform, LogicVRegister dst,
1886                       const LogicVRegister& src1, const LogicVRegister& src2);
1887   LogicVRegister uzp2(VectorFormat vform, LogicVRegister dst,
1888                       const LogicVRegister& src1, const LogicVRegister& src2);
1889   LogicVRegister shl(VectorFormat vform, LogicVRegister dst,
1890                      const LogicVRegister& src, int shift);
1891   LogicVRegister scvtf(VectorFormat vform, LogicVRegister dst,
1892                        const LogicVRegister& src, int fbits,
1893                        FPRounding rounding_mode);
1894   LogicVRegister ucvtf(VectorFormat vform, LogicVRegister dst,
1895                        const LogicVRegister& src, int fbits,
1896                        FPRounding rounding_mode);
1897   LogicVRegister sshll(VectorFormat vform, LogicVRegister dst,
1898                        const LogicVRegister& src, int shift);
1899   LogicVRegister sshll2(VectorFormat vform, LogicVRegister dst,
1900                         const LogicVRegister& src, int shift);
1901   LogicVRegister shll(VectorFormat vform, LogicVRegister dst,
1902                       const LogicVRegister& src);
1903   LogicVRegister shll2(VectorFormat vform, LogicVRegister dst,
1904                        const LogicVRegister& src);
1905   LogicVRegister ushll(VectorFormat vform, LogicVRegister dst,
1906                        const LogicVRegister& src, int shift);
1907   LogicVRegister ushll2(VectorFormat vform, LogicVRegister dst,
1908                         const LogicVRegister& src, int shift);
1909   LogicVRegister sli(VectorFormat vform, LogicVRegister dst,
1910                      const LogicVRegister& src, int shift);
1911   LogicVRegister sri(VectorFormat vform, LogicVRegister dst,
1912                      const LogicVRegister& src, int shift);
1913   LogicVRegister sshr(VectorFormat vform, LogicVRegister dst,
1914                       const LogicVRegister& src, int shift);
1915   LogicVRegister ushr(VectorFormat vform, LogicVRegister dst,
1916                       const LogicVRegister& src, int shift);
1917   LogicVRegister ssra(VectorFormat vform, LogicVRegister dst,
1918                       const LogicVRegister& src, int shift);
1919   LogicVRegister usra(VectorFormat vform, LogicVRegister dst,
1920                       const LogicVRegister& src, int shift);
1921   LogicVRegister srsra(VectorFormat vform, LogicVRegister dst,
1922                        const LogicVRegister& src, int shift);
1923   LogicVRegister ursra(VectorFormat vform, LogicVRegister dst,
1924                        const LogicVRegister& src, int shift);
1925   LogicVRegister suqadd(VectorFormat vform, LogicVRegister dst,
1926                         const LogicVRegister& src);
1927   LogicVRegister usqadd(VectorFormat vform, LogicVRegister dst,
1928                         const LogicVRegister& src);
1929   LogicVRegister sqshl(VectorFormat vform, LogicVRegister dst,
1930                        const LogicVRegister& src, int shift);
1931   LogicVRegister uqshl(VectorFormat vform, LogicVRegister dst,
1932                        const LogicVRegister& src, int shift);
1933   LogicVRegister sqshlu(VectorFormat vform, LogicVRegister dst,
1934                         const LogicVRegister& src, int shift);
1935   LogicVRegister abs(VectorFormat vform, LogicVRegister dst,
1936                      const LogicVRegister& src);
1937   LogicVRegister neg(VectorFormat vform, LogicVRegister dst,
1938                      const LogicVRegister& src);
1939   LogicVRegister ExtractNarrow(VectorFormat vform, LogicVRegister dst,
1940                                bool dstIsSigned, const LogicVRegister& src,
1941                                bool srcIsSigned);
1942   LogicVRegister xtn(VectorFormat vform, LogicVRegister dst,
1943                      const LogicVRegister& src);
1944   LogicVRegister sqxtn(VectorFormat vform, LogicVRegister dst,
1945                        const LogicVRegister& src);
1946   LogicVRegister uqxtn(VectorFormat vform, LogicVRegister dst,
1947                        const LogicVRegister& src);
1948   LogicVRegister sqxtun(VectorFormat vform, LogicVRegister dst,
1949                         const LogicVRegister& src);
1950   LogicVRegister AbsDiff(VectorFormat vform, LogicVRegister dst,
1951                          const LogicVRegister& src1, const LogicVRegister& src2,
1952                          bool issigned);
1953   LogicVRegister saba(VectorFormat vform, LogicVRegister dst,
1954                       const LogicVRegister& src1, const LogicVRegister& src2);
1955   LogicVRegister uaba(VectorFormat vform, LogicVRegister dst,
1956                       const LogicVRegister& src1, const LogicVRegister& src2);
1957   LogicVRegister shrn(VectorFormat vform, LogicVRegister dst,
1958                       const LogicVRegister& src, int shift);
1959   LogicVRegister shrn2(VectorFormat vform, LogicVRegister dst,
1960                        const LogicVRegister& src, int shift);
1961   LogicVRegister rshrn(VectorFormat vform, LogicVRegister dst,
1962                        const LogicVRegister& src, int shift);
1963   LogicVRegister rshrn2(VectorFormat vform, LogicVRegister dst,
1964                         const LogicVRegister& src, int shift);
1965   LogicVRegister uqshrn(VectorFormat vform, LogicVRegister dst,
1966                         const LogicVRegister& src, int shift);
1967   LogicVRegister uqshrn2(VectorFormat vform, LogicVRegister dst,
1968                          const LogicVRegister& src, int shift);
1969   LogicVRegister uqrshrn(VectorFormat vform, LogicVRegister dst,
1970                          const LogicVRegister& src, int shift);
1971   LogicVRegister uqrshrn2(VectorFormat vform, LogicVRegister dst,
1972                           const LogicVRegister& src, int shift);
1973   LogicVRegister sqshrn(VectorFormat vform, LogicVRegister dst,
1974                         const LogicVRegister& src, int shift);
1975   LogicVRegister sqshrn2(VectorFormat vform, LogicVRegister dst,
1976                          const LogicVRegister& src, int shift);
1977   LogicVRegister sqrshrn(VectorFormat vform, LogicVRegister dst,
1978                          const LogicVRegister& src, int shift);
1979   LogicVRegister sqrshrn2(VectorFormat vform, LogicVRegister dst,
1980                           const LogicVRegister& src, int shift);
1981   LogicVRegister sqshrun(VectorFormat vform, LogicVRegister dst,
1982                          const LogicVRegister& src, int shift);
1983   LogicVRegister sqshrun2(VectorFormat vform, LogicVRegister dst,
1984                           const LogicVRegister& src, int shift);
1985   LogicVRegister sqrshrun(VectorFormat vform, LogicVRegister dst,
1986                           const LogicVRegister& src, int shift);
1987   LogicVRegister sqrshrun2(VectorFormat vform, LogicVRegister dst,
1988                            const LogicVRegister& src, int shift);
1989   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst,
1990                           const LogicVRegister& src1,
1991                           const LogicVRegister& src2, bool round = true);
1992   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst,
1993                          const LogicVRegister& src1,
1994                          const LogicVRegister& src2);
1995 #define NEON_3VREG_LOGIC_LIST(V) \
1996   V(addhn)                       \
1997   V(addhn2)                      \
1998   V(raddhn)                      \
1999   V(raddhn2)                     \
2000   V(subhn)                       \
2001   V(subhn2)                      \
2002   V(rsubhn)                      \
2003   V(rsubhn2)                     \
2004   V(pmull)                       \
2005   V(pmull2)                      \
2006   V(sabal)                       \
2007   V(sabal2)                      \
2008   V(uabal)                       \
2009   V(uabal2)                      \
2010   V(sabdl)                       \
2011   V(sabdl2)                      \
2012   V(uabdl)                       \
2013   V(uabdl2)                      \
2014   V(smull)                       \
2015   V(smull2)                      \
2016   V(umull)                       \
2017   V(umull2)                      \
2018   V(smlal)                       \
2019   V(smlal2)                      \
2020   V(umlal)                       \
2021   V(umlal2)                      \
2022   V(smlsl)                       \
2023   V(smlsl2)                      \
2024   V(umlsl)                       \
2025   V(umlsl2)                      \
2026   V(sqdmlal)                     \
2027   V(sqdmlal2)                    \
2028   V(sqdmlsl)                     \
2029   V(sqdmlsl2)                    \
2030   V(sqdmull)                     \
2031   V(sqdmull2)
2032 
2033 #define DEFINE_LOGIC_FUNC(FXN)                               \
2034   LogicVRegister FXN(VectorFormat vform, LogicVRegister dst, \
2035                      const LogicVRegister& src1, const LogicVRegister& src2);
2036   NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
2037 #undef DEFINE_LOGIC_FUNC
2038 
2039 #define NEON_FP3SAME_LIST(V) \
2040   V(fadd, FPAdd, false)      \
2041   V(fsub, FPSub, true)       \
2042   V(fmul, FPMul, true)       \
2043   V(fmulx, FPMulx, true)     \
2044   V(fdiv, FPDiv, true)       \
2045   V(fmax, FPMax, false)      \
2046   V(fmin, FPMin, false)      \
2047   V(fmaxnm, FPMaxNM, false)  \
2048   V(fminnm, FPMinNM, false)
2049 
2050 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                           \
2051   template <typename T>                                                      \
2052   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \
2053                     const LogicVRegister& src1, const LogicVRegister& src2); \
2054   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \
2055                     const LogicVRegister& src1, const LogicVRegister& src2);
2056   NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
2057 #undef DECLARE_NEON_FP_VECTOR_OP
2058 
2059 #define NEON_FPPAIRWISE_LIST(V) \
2060   V(faddp, fadd, FPAdd)         \
2061   V(fmaxp, fmax, FPMax)         \
2062   V(fmaxnmp, fmaxnm, FPMaxNM)   \
2063   V(fminp, fmin, FPMin)         \
2064   V(fminnmp, fminnm, FPMinNM)
2065 
2066 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)                                  \
2067   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \
2068                      const LogicVRegister& src1, const LogicVRegister& src2); \
2069   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \
2070                      const LogicVRegister& src);
2071   NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
2072 #undef DECLARE_NEON_FP_PAIR_OP
2073 
2074   template <typename T>
2075   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst,
2076                         const LogicVRegister& src1, const LogicVRegister& src2);
2077   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst,
2078                         const LogicVRegister& src1, const LogicVRegister& src2);
2079   template <typename T>
2080   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst,
2081                          const LogicVRegister& src1,
2082                          const LogicVRegister& src2);
2083   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst,
2084                          const LogicVRegister& src1,
2085                          const LogicVRegister& src2);
2086   template <typename T>
2087   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
2088                       const LogicVRegister& src1, const LogicVRegister& src2);
2089   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst,
2090                       const LogicVRegister& src1, const LogicVRegister& src2);
2091   template <typename T>
2092   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
2093                       const LogicVRegister& src1, const LogicVRegister& src2);
2094   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst,
2095                       const LogicVRegister& src1, const LogicVRegister& src2);
2096   LogicVRegister fnmul(VectorFormat vform, LogicVRegister dst,
2097                        const LogicVRegister& src1, const LogicVRegister& src2);
2098 
2099   template <typename T>
2100   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst,
2101                       const LogicVRegister& src1, const LogicVRegister& src2,
2102                       Condition cond);
2103   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst,
2104                       const LogicVRegister& src1, const LogicVRegister& src2,
2105                       Condition cond);
2106   LogicVRegister fabscmp(VectorFormat vform, LogicVRegister dst,
2107                          const LogicVRegister& src1, const LogicVRegister& src2,
2108                          Condition cond);
2109   LogicVRegister fcmp_zero(VectorFormat vform, LogicVRegister dst,
2110                            const LogicVRegister& src, Condition cond);
2111 
2112   template <typename T>
2113   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst,
2114                       const LogicVRegister& src);
2115   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst,
2116                       const LogicVRegister& src);
2117   template <typename T>
2118   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst,
2119                         const LogicVRegister& src);
2120   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst,
2121                         const LogicVRegister& src);
2122   template <typename T>
2123   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst,
2124                        const LogicVRegister& src);
2125   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst,
2126                        const LogicVRegister& src);
2127   LogicVRegister fabd(VectorFormat vform, LogicVRegister dst,
2128                       const LogicVRegister& src1, const LogicVRegister& src2);
2129   LogicVRegister frint(VectorFormat vform, LogicVRegister dst,
2130                        const LogicVRegister& src, FPRounding rounding_mode,
2131                        bool inexact_exception = false);
2132   LogicVRegister fcvts(VectorFormat vform, LogicVRegister dst,
2133                        const LogicVRegister& src, FPRounding rounding_mode,
2134                        int fbits = 0);
2135   LogicVRegister fcvtu(VectorFormat vform, LogicVRegister dst,
2136                        const LogicVRegister& src, FPRounding rounding_mode,
2137                        int fbits = 0);
2138   LogicVRegister fcvtl(VectorFormat vform, LogicVRegister dst,
2139                        const LogicVRegister& src);
2140   LogicVRegister fcvtl2(VectorFormat vform, LogicVRegister dst,
2141                         const LogicVRegister& src);
2142   LogicVRegister fcvtn(VectorFormat vform, LogicVRegister dst,
2143                        const LogicVRegister& src);
2144   LogicVRegister fcvtn2(VectorFormat vform, LogicVRegister dst,
2145                         const LogicVRegister& src);
2146   LogicVRegister fcvtxn(VectorFormat vform, LogicVRegister dst,
2147                         const LogicVRegister& src);
2148   LogicVRegister fcvtxn2(VectorFormat vform, LogicVRegister dst,
2149                          const LogicVRegister& src);
2150   LogicVRegister fsqrt(VectorFormat vform, LogicVRegister dst,
2151                        const LogicVRegister& src);
2152   LogicVRegister frsqrte(VectorFormat vform, LogicVRegister dst,
2153                          const LogicVRegister& src);
2154   LogicVRegister frecpe(VectorFormat vform, LogicVRegister dst,
2155                         const LogicVRegister& src, FPRounding rounding);
2156   LogicVRegister ursqrte(VectorFormat vform, LogicVRegister dst,
2157                          const LogicVRegister& src);
2158   LogicVRegister urecpe(VectorFormat vform, LogicVRegister dst,
2159                         const LogicVRegister& src);
2160 
2161   using FPMinMaxOp = float (Simulator::*)(float a, float b);
2162 
2163   LogicVRegister FMinMaxV(VectorFormat vform, LogicVRegister dst,
2164                           const LogicVRegister& src, FPMinMaxOp Op);
2165 
2166   LogicVRegister fminv(VectorFormat vform, LogicVRegister dst,
2167                        const LogicVRegister& src);
2168   LogicVRegister fmaxv(VectorFormat vform, LogicVRegister dst,
2169                        const LogicVRegister& src);
2170   LogicVRegister fminnmv(VectorFormat vform, LogicVRegister dst,
2171                          const LogicVRegister& src);
2172   LogicVRegister fmaxnmv(VectorFormat vform, LogicVRegister dst,
2173                          const LogicVRegister& src);
2174 
2175   template <typename T>
2176   T FPRecipSqrtEstimate(T op);
2177   template <typename T>
2178   T FPRecipEstimate(T op, FPRounding rounding);
2179   template <typename T, typename R>
2180   R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
2181 
2182   void FPCompare(double val0, double val1);
2183   double FPRoundInt(double value, FPRounding round_mode);
2184   double FPToDouble(float value);
2185   float FPToFloat(double value, FPRounding round_mode);
2186   float FPToFloat(float16 value);
2187   float16 FPToFloat16(float value, FPRounding round_mode);
2188   float16 FPToFloat16(double value, FPRounding round_mode);
2189   double recip_sqrt_estimate(double a);
2190   double recip_estimate(double a);
2191   double FPRecipSqrtEstimate(double a);
2192   double FPRecipEstimate(double a);
2193   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
2194   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
2195   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
2196   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
2197   int32_t FPToInt32(double value, FPRounding rmode);
2198   int64_t FPToInt64(double value, FPRounding rmode);
2199   uint32_t FPToUInt32(double value, FPRounding rmode);
2200   uint64_t FPToUInt64(double value, FPRounding rmode);
2201   int32_t FPToFixedJS(double value);
2202 
2203   template <typename T>
2204   T FPAdd(T op1, T op2);
2205 
2206   template <typename T>
2207   T FPDiv(T op1, T op2);
2208 
2209   template <typename T>
2210   T FPMax(T a, T b);
2211 
2212   template <typename T>
2213   T FPMaxNM(T a, T b);
2214 
2215   template <typename T>
2216   T FPMin(T a, T b);
2217 
2218   template <typename T>
2219   T FPMinNM(T a, T b);
2220 
2221   template <typename T>
2222   T FPMul(T op1, T op2);
2223 
2224   template <typename T>
2225   T FPMulx(T op1, T op2);
2226 
2227   template <typename T>
2228   T FPMulAdd(T a, T op1, T op2);
2229 
2230   template <typename T>
2231   T FPSqrt(T op);
2232 
2233   template <typename T>
2234   T FPSub(T op1, T op2);
2235 
2236   template <typename T>
2237   T FPRecipStepFused(T op1, T op2);
2238 
2239   template <typename T>
2240   T FPRSqrtStepFused(T op1, T op2);
2241 
2242   // This doesn't do anything at the moment. We'll need it if we want support
2243   // for cumulative exception bits or floating-point exceptions.
FPProcessException()2244   void FPProcessException() {}
2245 
2246   // Standard NaN processing.
2247   bool FPProcessNaNs(Instruction* instr);
2248 
2249   void CheckStackAlignment();
2250 
2251   inline void CheckPCSComplianceAndRun();
2252 
2253 #ifdef DEBUG
2254   // Corruption values should have their least significant byte cleared to
2255   // allow the code of the register being corrupted to be inserted.
2256   static const uint64_t kCallerSavedRegisterCorruptionValue =
2257       0xca11edc0de000000UL;
2258   // This value is a NaN in both 32-bit and 64-bit FP.
2259   static const uint64_t kCallerSavedVRegisterCorruptionValue =
2260       0x7ff000007f801000UL;
2261   // This value is a mix of 32/64-bits NaN and "verbose" immediate.
2262   static const uint64_t kDefaultCPURegisterCorruptionValue =
2263       0x7ffbad007f8bad00UL;
2264 
2265   void CorruptRegisters(CPURegList* list,
2266                         uint64_t value = kDefaultCPURegisterCorruptionValue);
2267   void CorruptAllCallerSavedCPURegisters();
2268 #endif
2269 
2270   // Pseudo Printf instruction
2271   void DoPrintf(Instruction* instr);
2272 
2273   // Processor state ---------------------------------------
2274 
2275   // Output stream.
2276   FILE* stream_;
2277   PrintDisassembler* print_disasm_;
2278   void PRINTF_FORMAT(2, 3) TraceSim(const char* format, ...);
2279 
2280   // General purpose registers. Register 31 is the stack pointer.
2281   SimRegister registers_[kNumberOfRegisters];
2282 
2283   // Floating point registers
2284   SimVRegister vregisters_[kNumberOfVRegisters];
2285 
2286   // Processor state
2287   // bits[31, 27]: Condition flags N, Z, C, and V.
2288   //               (Negative, Zero, Carry, Overflow)
2289   SimSystemRegister nzcv_;
2290 
2291   // Floating-Point Control Register
2292   SimSystemRegister fpcr_;
2293 
2294   // Only a subset of FPCR features are supported by the simulator. This helper
2295   // checks that the FPCR settings are supported.
2296   //
2297   // This is checked when floating-point instructions are executed, not when
2298   // FPCR is set. This allows generated code to modify FPCR for external
2299   // functions, or to save and restore it when entering and leaving generated
2300   // code.
AssertSupportedFPCR()2301   void AssertSupportedFPCR() {
2302     DCHECK_EQ(fpcr().FZ(), 0);            // No flush-to-zero support.
2303     DCHECK(fpcr().RMode() == FPTieEven);  // Ties-to-even rounding only.
2304 
2305     // The simulator does not support half-precision operations so fpcr().AHP()
2306     // is irrelevant, and is not checked here.
2307   }
2308 
2309   template <typename T>
CalcNFlag(T result)2310   static int CalcNFlag(T result) {
2311     return (result >> (sizeof(T) * 8 - 1)) & 1;
2312   }
2313 
CalcZFlag(uint64_t result)2314   static int CalcZFlag(uint64_t result) { return result == 0; }
2315 
2316   static const uint32_t kConditionFlagsMask = 0xf0000000;
2317 
2318   // Stack
2319   uintptr_t stack_;
2320   static const size_t stack_protection_size_ = KB;
2321   size_t stack_size_;
2322   uintptr_t stack_limit_;
2323 
2324   Decoder<DispatchingDecoderVisitor>* decoder_;
2325   Decoder<DispatchingDecoderVisitor>* disassembler_decoder_;
2326 
2327   // Indicates if the pc has been modified by the instruction and should not be
2328   // automatically incremented.
2329   bool pc_modified_;
2330   Instruction* pc_;
2331 
2332   // Branch type register, used for branch target identification.
2333   BType btype_;
2334 
2335   // Global flag for enabling guarded pages.
2336   // TODO(arm64): implement guarding at page granularity, rather than globally.
2337   bool guard_pages_;
2338 
2339   static const char* xreg_names[];
2340   static const char* wreg_names[];
2341   static const char* sreg_names[];
2342   static const char* dreg_names[];
2343   static const char* vreg_names[];
2344 
2345   // Debugger input.
set_last_debugger_input(ArrayUniquePtr<char> input)2346   void set_last_debugger_input(ArrayUniquePtr<char> input) {
2347     last_debugger_input_ = std::move(input);
2348   }
last_debugger_input()2349   const char* last_debugger_input() { return last_debugger_input_.get(); }
2350   ArrayUniquePtr<char> last_debugger_input_;
2351 
2352   // Synchronization primitives. See ARM DDI 0487A.a, B2.10. Pair types not
2353   // implemented.
2354   enum class MonitorAccess {
2355     Open,
2356     Exclusive,
2357   };
2358 
2359   enum class TransactionSize {
2360     None = 0,
2361     Byte = 1,
2362     HalfWord = 2,
2363     Word = 4,
2364     DoubleWord = 8,
2365   };
2366 
2367   TransactionSize get_transaction_size(unsigned size);
2368 
2369   // The least-significant bits of the address are ignored. The number of bits
2370   // is implementation-defined, between 3 and 11. See ARM DDI 0487A.a, B2.10.3.
2371   static const uintptr_t kExclusiveTaggedAddrMask = ~((1 << 11) - 1);
2372 
2373   class LocalMonitor {
2374    public:
2375     LocalMonitor();
2376 
2377     // These functions manage the state machine for the local monitor, but do
2378     // not actually perform loads and stores. NotifyStoreExcl only returns
2379     // true if the exclusive store is allowed; the global monitor will still
2380     // have to be checked to see whether the memory should be updated.
2381     void NotifyLoad();
2382     void NotifyLoadExcl(uintptr_t addr, TransactionSize size);
2383     void NotifyStore();
2384     bool NotifyStoreExcl(uintptr_t addr, TransactionSize size);
2385 
2386    private:
2387     void Clear();
2388 
2389     MonitorAccess access_state_;
2390     uintptr_t tagged_addr_;
2391     TransactionSize size_;
2392   };
2393 
2394   class GlobalMonitor {
2395    public:
2396     class Processor {
2397      public:
2398       Processor();
2399 
2400      private:
2401       friend class GlobalMonitor;
2402       // These functions manage the state machine for the global monitor, but do
2403       // not actually perform loads and stores.
2404       void Clear_Locked();
2405       void NotifyLoadExcl_Locked(uintptr_t addr);
2406       void NotifyStore_Locked(bool is_requesting_processor);
2407       bool NotifyStoreExcl_Locked(uintptr_t addr, bool is_requesting_processor);
2408 
2409       MonitorAccess access_state_;
2410       uintptr_t tagged_addr_;
2411       Processor* next_;
2412       Processor* prev_;
2413       // A stxr can fail due to background cache evictions. Rather than
2414       // simulating this, we'll just occasionally introduce cases where an
2415       // exclusive store fails. This will happen once after every
2416       // kMaxFailureCounter exclusive stores.
2417       static const int kMaxFailureCounter = 5;
2418       int failure_counter_;
2419     };
2420 
2421     // Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
2422     base::Mutex mutex;
2423 
2424     void NotifyLoadExcl_Locked(uintptr_t addr, Processor* processor);
2425     void NotifyStore_Locked(Processor* processor);
2426     bool NotifyStoreExcl_Locked(uintptr_t addr, Processor* processor);
2427 
2428     // Called when the simulator is destroyed.
2429     void RemoveProcessor(Processor* processor);
2430 
2431     static GlobalMonitor* Get();
2432 
2433    private:
2434     // Private constructor. Call {GlobalMonitor::Get()} to get the singleton.
2435     GlobalMonitor() = default;
2436     friend class base::LeakyObject<GlobalMonitor>;
2437 
2438     bool IsProcessorInLinkedList_Locked(Processor* processor) const;
2439     void PrependProcessor_Locked(Processor* processor);
2440 
2441     Processor* head_ = nullptr;
2442   };
2443 
2444   LocalMonitor local_monitor_;
2445   GlobalMonitor::Processor global_monitor_processor_;
2446 
2447  private:
2448   void Init(FILE* stream);
2449 
2450   V8_EXPORT_PRIVATE void CallImpl(Address entry, CallArgument* args);
2451 
2452   void CallAnyCTypeFunction(Address target_address,
2453                             const EncodedCSignature& signature);
2454 
2455   // Read floating point return values.
2456   template <typename T>
2457   typename std::enable_if<std::is_floating_point<T>::value, T>::type
ReadReturn()2458   ReadReturn() {
2459     return static_cast<T>(dreg(0));
2460   }
2461   // Read non-float return values.
2462   template <typename T>
2463   typename std::enable_if<!std::is_floating_point<T>::value, T>::type
ReadReturn()2464   ReadReturn() {
2465     return ConvertReturn<T>(xreg(0));
2466   }
2467 
2468   template <typename T>
2469   static T FPDefaultNaN();
2470 
2471   template <typename T>
FPProcessNaN(T op)2472   T FPProcessNaN(T op) {
2473     DCHECK(std::isnan(op));
2474     return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
2475   }
2476 
2477   template <typename T>
FPProcessNaNs(T op1,T op2)2478   T FPProcessNaNs(T op1, T op2) {
2479     if (IsSignallingNaN(op1)) {
2480       return FPProcessNaN(op1);
2481     } else if (IsSignallingNaN(op2)) {
2482       return FPProcessNaN(op2);
2483     } else if (std::isnan(op1)) {
2484       DCHECK(IsQuietNaN(op1));
2485       return FPProcessNaN(op1);
2486     } else if (std::isnan(op2)) {
2487       DCHECK(IsQuietNaN(op2));
2488       return FPProcessNaN(op2);
2489     } else {
2490       return 0.0;
2491     }
2492   }
2493 
2494   template <typename T>
FPProcessNaNs3(T op1,T op2,T op3)2495   T FPProcessNaNs3(T op1, T op2, T op3) {
2496     if (IsSignallingNaN(op1)) {
2497       return FPProcessNaN(op1);
2498     } else if (IsSignallingNaN(op2)) {
2499       return FPProcessNaN(op2);
2500     } else if (IsSignallingNaN(op3)) {
2501       return FPProcessNaN(op3);
2502     } else if (std::isnan(op1)) {
2503       DCHECK(IsQuietNaN(op1));
2504       return FPProcessNaN(op1);
2505     } else if (std::isnan(op2)) {
2506       DCHECK(IsQuietNaN(op2));
2507       return FPProcessNaN(op2);
2508     } else if (std::isnan(op3)) {
2509       DCHECK(IsQuietNaN(op3));
2510       return FPProcessNaN(op3);
2511     } else {
2512       return 0.0;
2513     }
2514   }
2515 
2516   int log_parameters_;
2517   // Instruction counter only valid if FLAG_stop_sim_at isn't 0.
2518   int icount_for_stop_sim_at_;
2519   Isolate* isolate_;
2520 };
2521 
2522 template <>
2523 inline double Simulator::FPDefaultNaN<double>() {
2524   return kFP64DefaultNaN;
2525 }
2526 
2527 template <>
2528 inline float Simulator::FPDefaultNaN<float>() {
2529   return kFP32DefaultNaN;
2530 }
2531 
2532 }  // namespace internal
2533 }  // namespace v8
2534 
2535 #endif  // defined(USE_SIMULATOR)
2536 #endif  // V8_EXECUTION_ARM64_SIMULATOR_ARM64_H_
2537