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