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