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