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