Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: src/arm64/simulator-arm64.h

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

Powered by Google App Engine
This is Rietveld 408576698