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