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