1 // Copyright 2015, VIXL authors 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, 8 // this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above copyright notice, 10 // this list of conditions and the following disclaimer in the documentation 11 // and/or other materials provided with the distribution. 12 // * Neither the name of ARM Limited nor the names of its contributors may be 13 // used to endorse or promote products derived from this software without 14 // specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #ifndef VIXL_AARCH64_SIMULATOR_AARCH64_H_ 28 #define VIXL_AARCH64_SIMULATOR_AARCH64_H_ 29 30 #include "../globals-vixl.h" 31 #include "../utils-vixl.h" 32 33 #include "abi-aarch64.h" 34 #include "disasm-aarch64.h" 35 #include "instructions-aarch64.h" 36 #include "instrument-aarch64.h" 37 #include "simulator-constants-aarch64.h" 38 39 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 40 41 // These are only used for the ABI feature, and depend on checks performed for 42 // it. 43 #ifdef VIXL_HAS_ABI_SUPPORT 44 #include <tuple> 45 #if __cplusplus >= 201402L 46 // Required for `std::index_sequence` 47 #include <utility> 48 #endif 49 #endif 50 51 namespace vixl { 52 namespace aarch64 { 53 54 // Assemble the specified IEEE-754 components into the target type and apply 55 // appropriate rounding. 56 // sign: 0 = positive, 1 = negative 57 // exponent: Unbiased IEEE-754 exponent. 58 // mantissa: The mantissa of the input. The top bit (which is not encoded for 59 // normal IEEE-754 values) must not be omitted. This bit has the 60 // value 'pow(2, exponent)'. 61 // 62 // The input value is assumed to be a normalized value. That is, the input may 63 // not be infinity or NaN. If the source value is subnormal, it must be 64 // normalized before calling this function such that the highest set bit in the 65 // mantissa has the value 'pow(2, exponent)'. 66 // 67 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than 68 // calling a templated FPRound. 69 template <class T, int ebits, int mbits> 70 T FPRound(int64_t sign, 71 int64_t exponent, 72 uint64_t mantissa, 73 FPRounding round_mode) { 74 VIXL_ASSERT((sign == 0) || (sign == 1)); 75 76 // Only FPTieEven and FPRoundOdd rounding modes are implemented. 77 VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd)); 78 79 // Rounding can promote subnormals to normals, and normals to infinities. For 80 // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be 81 // encodable as a float, but rounding based on the low-order mantissa bits 82 // could make it overflow. With ties-to-even rounding, this value would become 83 // an infinity. 84 85 // ---- Rounding Method ---- 86 // 87 // The exponent is irrelevant in the rounding operation, so we treat the 88 // lowest-order bit that will fit into the result ('onebit') as having 89 // the value '1'. Similarly, the highest-order bit that won't fit into 90 // the result ('halfbit') has the value '0.5'. The 'point' sits between 91 // 'onebit' and 'halfbit': 92 // 93 // These bits fit into the result. 94 // |---------------------| 95 // mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 96 // || 97 // / | 98 // / halfbit 99 // onebit 100 // 101 // For subnormal outputs, the range of representable bits is smaller and 102 // the position of onebit and halfbit depends on the exponent of the 103 // input, but the method is otherwise similar. 104 // 105 // onebit(frac) 106 // | 107 // | halfbit(frac) halfbit(adjusted) 108 // | / / 109 // | | | 110 // 0b00.0 (exact) -> 0b00.0 (exact) -> 0b00 111 // 0b00.0... -> 0b00.0... -> 0b00 112 // 0b00.1 (exact) -> 0b00.0111..111 -> 0b00 113 // 0b00.1... -> 0b00.1... -> 0b01 114 // 0b01.0 (exact) -> 0b01.0 (exact) -> 0b01 115 // 0b01.0... -> 0b01.0... -> 0b01 116 // 0b01.1 (exact) -> 0b01.1 (exact) -> 0b10 117 // 0b01.1... -> 0b01.1... -> 0b10 118 // 0b10.0 (exact) -> 0b10.0 (exact) -> 0b10 119 // 0b10.0... -> 0b10.0... -> 0b10 120 // 0b10.1 (exact) -> 0b10.0111..111 -> 0b10 121 // 0b10.1... -> 0b10.1... -> 0b11 122 // 0b11.0 (exact) -> 0b11.0 (exact) -> 0b11 123 // ... / | / | 124 // / | / | 125 // / | 126 // adjusted = frac - (halfbit(mantissa) & ~onebit(frac)); / | 127 // 128 // mantissa = (mantissa >> shift) + halfbit(adjusted); 129 130 static const int mantissa_offset = 0; 131 static const int exponent_offset = mantissa_offset + mbits; 132 static const int sign_offset = exponent_offset + ebits; 133 VIXL_ASSERT(sign_offset == (sizeof(T) * 8 - 1)); 134 135 // Bail out early for zero inputs. 136 if (mantissa == 0) { 137 return static_cast<T>(sign << sign_offset); 138 } 139 140 // If all bits in the exponent are set, the value is infinite or NaN. 141 // This is true for all binary IEEE-754 formats. 142 static const int infinite_exponent = (1 << ebits) - 1; 143 static const int max_normal_exponent = infinite_exponent - 1; 144 145 // Apply the exponent bias to encode it for the result. Doing this early makes 146 // it easy to detect values that will be infinite or subnormal. 147 exponent += max_normal_exponent >> 1; 148 149 if (exponent > max_normal_exponent) { 150 // Overflow: the input is too large for the result type to represent. 151 if (round_mode == FPTieEven) { 152 // FPTieEven rounding mode handles overflows using infinities. 153 exponent = infinite_exponent; 154 mantissa = 0; 155 } else { 156 VIXL_ASSERT(round_mode == FPRoundOdd); 157 // FPRoundOdd rounding mode handles overflows using the largest magnitude 158 // normal number. 159 exponent = max_normal_exponent; 160 mantissa = (UINT64_C(1) << exponent_offset) - 1; 161 } 162 return static_cast<T>((sign << sign_offset) | 163 (exponent << exponent_offset) | 164 (mantissa << mantissa_offset)); 165 } 166 167 // Calculate the shift required to move the top mantissa bit to the proper 168 // place in the destination type. 169 const int highest_significant_bit = 63 - CountLeadingZeros(mantissa); 170 int shift = highest_significant_bit - mbits; 171 172 if (exponent <= 0) { 173 // The output will be subnormal (before rounding). 174 // For subnormal outputs, the shift must be adjusted by the exponent. The +1 175 // is necessary because the exponent of a subnormal value (encoded as 0) is 176 // the same as the exponent of the smallest normal value (encoded as 1). 177 shift += -exponent + 1; 178 179 // Handle inputs that would produce a zero output. 180 // 181 // Shifts higher than highest_significant_bit+1 will always produce a zero 182 // result. A shift of exactly highest_significant_bit+1 might produce a 183 // non-zero result after rounding. 184 if (shift > (highest_significant_bit + 1)) { 185 if (round_mode == FPTieEven) { 186 // The result will always be +/-0.0. 187 return static_cast<T>(sign << sign_offset); 188 } else { 189 VIXL_ASSERT(round_mode == FPRoundOdd); 190 VIXL_ASSERT(mantissa != 0); 191 // For FPRoundOdd, if the mantissa is too small to represent and 192 // non-zero return the next "odd" value. 193 return static_cast<T>((sign << sign_offset) | 1); 194 } 195 } 196 197 // Properly encode the exponent for a subnormal output. 198 exponent = 0; 199 } else { 200 // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 201 // normal values. 202 mantissa &= ~(UINT64_C(1) << highest_significant_bit); 203 } 204 205 if (shift > 0) { 206 if (round_mode == FPTieEven) { 207 // We have to shift the mantissa to the right. Some precision is lost, so 208 // we need to apply rounding. 209 uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; 210 uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1; 211 uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa); 212 uint64_t adjusted = mantissa - adjustment; 213 T halfbit_adjusted = (adjusted >> (shift - 1)) & 1; 214 215 T result = 216 static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) | 217 ((mantissa >> shift) << mantissa_offset)); 218 219 // A very large mantissa can overflow during rounding. If this happens, 220 // the exponent should be incremented and the mantissa set to 1.0 221 // (encoded as 0). Applying halfbit_adjusted after assembling the float 222 // has the nice side-effect that this case is handled for free. 223 // 224 // This also handles cases where a very large finite value overflows to 225 // infinity, or where a very large subnormal value overflows to become 226 // normal. 227 return result + halfbit_adjusted; 228 } else { 229 VIXL_ASSERT(round_mode == FPRoundOdd); 230 // If any bits at position halfbit or below are set, onebit (ie. the 231 // bottom bit of the resulting mantissa) must be set. 232 uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1); 233 if (fractional_bits != 0) { 234 mantissa |= UINT64_C(1) << shift; 235 } 236 237 return static_cast<T>((sign << sign_offset) | 238 (exponent << exponent_offset) | 239 ((mantissa >> shift) << mantissa_offset)); 240 } 241 } else { 242 // We have to shift the mantissa to the left (or not at all). The input 243 // mantissa is exactly representable in the output mantissa, so apply no 244 // rounding correction. 245 return static_cast<T>((sign << sign_offset) | 246 (exponent << exponent_offset) | 247 ((mantissa << -shift) << mantissa_offset)); 248 } 249 } 250 251 252 // Representation of memory, with typed getters and setters for access. 253 class Memory { 254 public: 255 template <typename T> 256 static T AddressUntag(T address) { 257 // Cast the address using a C-style cast. A reinterpret_cast would be 258 // appropriate, but it can't cast one integral type to another. 259 uint64_t bits = (uint64_t)address; 260 return (T)(bits & ~kAddressTagMask); 261 } 262 263 template <typename T, typename A> 264 static T Read(A address) { 265 T value; 266 address = AddressUntag(address); 267 VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || 268 (sizeof(value) == 4) || (sizeof(value) == 8) || 269 (sizeof(value) == 16)); 270 memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value)); 271 return value; 272 } 273 274 template <typename T, typename A> 275 static void Write(A address, T value) { 276 address = AddressUntag(address); 277 VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || 278 (sizeof(value) == 4) || (sizeof(value) == 8) || 279 (sizeof(value) == 16)); 280 memcpy(reinterpret_cast<char*>(address), &value, sizeof(value)); 281 } 282 }; 283 284 // Represent a register (r0-r31, v0-v31). 285 template <int kSizeInBytes> 286 class SimRegisterBase { 287 public: 288 SimRegisterBase() : written_since_last_log_(false) {} 289 290 // Write the specified value. The value is zero-extended if necessary. 291 template <typename T> 292 void Write(T new_value) { 293 VIXL_STATIC_ASSERT(sizeof(new_value) <= kSizeInBytes); 294 if (sizeof(new_value) < kSizeInBytes) { 295 // All AArch64 registers are zero-extending. 296 memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value)); 297 } 298 memcpy(value_, &new_value, sizeof(new_value)); 299 NotifyRegisterWrite(); 300 } 301 template <typename T> 302 VIXL_DEPRECATED("Write", void Set(T new_value)) { 303 Write(new_value); 304 } 305 306 // Insert a typed value into a register, leaving the rest of the register 307 // unchanged. The lane parameter indicates where in the register the value 308 // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where 309 // 0 represents the least significant bits. 310 template <typename T> 311 void Insert(int lane, T new_value) { 312 VIXL_ASSERT(lane >= 0); 313 VIXL_ASSERT((sizeof(new_value) + (lane * sizeof(new_value))) <= 314 kSizeInBytes); 315 memcpy(&value_[lane * sizeof(new_value)], &new_value, sizeof(new_value)); 316 NotifyRegisterWrite(); 317 } 318 319 // Get the value as the specified type. The value is truncated if necessary. 320 template <typename T> 321 T Get() const { 322 return GetLane<T>(0); 323 } 324 325 // Get the lane value as the specified type. The value is truncated if 326 // necessary. 327 template <typename T> 328 T GetLane(int lane) const { 329 T result; 330 VIXL_ASSERT(lane >= 0); 331 VIXL_ASSERT((sizeof(result) + (lane * sizeof(result))) <= kSizeInBytes); 332 memcpy(&result, &value_[lane * sizeof(result)], sizeof(result)); 333 return result; 334 } 335 template <typename T> 336 VIXL_DEPRECATED("GetLane", T Get(int lane) const) { 337 return GetLane(lane); 338 } 339 340 // TODO: Make this return a map of updated bytes, so that we can highlight 341 // updated lanes for load-and-insert. (That never happens for scalar code, but 342 // NEON has some instructions that can update individual lanes.) 343 bool WrittenSinceLastLog() const { return written_since_last_log_; } 344 345 void NotifyRegisterLogged() { written_since_last_log_ = false; } 346 347 protected: 348 uint8_t value_[kSizeInBytes]; 349 350 // Helpers to aid with register tracing. 351 bool written_since_last_log_; 352 353 void NotifyRegisterWrite() { written_since_last_log_ = true; } 354 }; 355 typedef SimRegisterBase<kXRegSizeInBytes> SimRegister; // r0-r31 356 typedef SimRegisterBase<kQRegSizeInBytes> SimVRegister; // v0-v31 357 358 // Representation of a vector register, with typed getters and setters for lanes 359 // and additional information to represent lane state. 360 class LogicVRegister { 361 public: 362 inline LogicVRegister( 363 SimVRegister& other) // NOLINT(runtime/references)(runtime/explicit) 364 : register_(other) { 365 for (unsigned i = 0; i < sizeof(saturated_) / sizeof(saturated_[0]); i++) { 366 saturated_[i] = kNotSaturated; 367 } 368 for (unsigned i = 0; i < sizeof(round_) / sizeof(round_[0]); i++) { 369 round_[i] = 0; 370 } 371 } 372 373 int64_t Int(VectorFormat vform, int index) const { 374 int64_t element; 375 switch (LaneSizeInBitsFromFormat(vform)) { 376 case 8: 377 element = register_.GetLane<int8_t>(index); 378 break; 379 case 16: 380 element = register_.GetLane<int16_t>(index); 381 break; 382 case 32: 383 element = register_.GetLane<int32_t>(index); 384 break; 385 case 64: 386 element = register_.GetLane<int64_t>(index); 387 break; 388 default: 389 VIXL_UNREACHABLE(); 390 return 0; 391 } 392 return element; 393 } 394 395 uint64_t Uint(VectorFormat vform, int index) const { 396 uint64_t element; 397 switch (LaneSizeInBitsFromFormat(vform)) { 398 case 8: 399 element = register_.GetLane<uint8_t>(index); 400 break; 401 case 16: 402 element = register_.GetLane<uint16_t>(index); 403 break; 404 case 32: 405 element = register_.GetLane<uint32_t>(index); 406 break; 407 case 64: 408 element = register_.GetLane<uint64_t>(index); 409 break; 410 default: 411 VIXL_UNREACHABLE(); 412 return 0; 413 } 414 return element; 415 } 416 417 uint64_t UintLeftJustified(VectorFormat vform, int index) const { 418 return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform)); 419 } 420 421 int64_t IntLeftJustified(VectorFormat vform, int index) const { 422 uint64_t value = UintLeftJustified(vform, index); 423 int64_t result; 424 memcpy(&result, &value, sizeof(result)); 425 return result; 426 } 427 428 void SetInt(VectorFormat vform, int index, int64_t value) const { 429 switch (LaneSizeInBitsFromFormat(vform)) { 430 case 8: 431 register_.Insert(index, static_cast<int8_t>(value)); 432 break; 433 case 16: 434 register_.Insert(index, static_cast<int16_t>(value)); 435 break; 436 case 32: 437 register_.Insert(index, static_cast<int32_t>(value)); 438 break; 439 case 64: 440 register_.Insert(index, static_cast<int64_t>(value)); 441 break; 442 default: 443 VIXL_UNREACHABLE(); 444 return; 445 } 446 } 447 448 void SetIntArray(VectorFormat vform, const int64_t* src) const { 449 ClearForWrite(vform); 450 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 451 SetInt(vform, i, src[i]); 452 } 453 } 454 455 void SetUint(VectorFormat vform, int index, uint64_t value) const { 456 switch (LaneSizeInBitsFromFormat(vform)) { 457 case 8: 458 register_.Insert(index, static_cast<uint8_t>(value)); 459 break; 460 case 16: 461 register_.Insert(index, static_cast<uint16_t>(value)); 462 break; 463 case 32: 464 register_.Insert(index, static_cast<uint32_t>(value)); 465 break; 466 case 64: 467 register_.Insert(index, static_cast<uint64_t>(value)); 468 break; 469 default: 470 VIXL_UNREACHABLE(); 471 return; 472 } 473 } 474 475 void SetUintArray(VectorFormat vform, const uint64_t* src) const { 476 ClearForWrite(vform); 477 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 478 SetUint(vform, i, src[i]); 479 } 480 } 481 482 void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const { 483 switch (LaneSizeInBitsFromFormat(vform)) { 484 case 8: 485 register_.Insert(index, Memory::Read<uint8_t>(addr)); 486 break; 487 case 16: 488 register_.Insert(index, Memory::Read<uint16_t>(addr)); 489 break; 490 case 32: 491 register_.Insert(index, Memory::Read<uint32_t>(addr)); 492 break; 493 case 64: 494 register_.Insert(index, Memory::Read<uint64_t>(addr)); 495 break; 496 default: 497 VIXL_UNREACHABLE(); 498 return; 499 } 500 } 501 502 void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const { 503 uint64_t value = Uint(vform, index); 504 switch (LaneSizeInBitsFromFormat(vform)) { 505 case 8: 506 Memory::Write(addr, static_cast<uint8_t>(value)); 507 break; 508 case 16: 509 Memory::Write(addr, static_cast<uint16_t>(value)); 510 break; 511 case 32: 512 Memory::Write(addr, static_cast<uint32_t>(value)); 513 break; 514 case 64: 515 Memory::Write(addr, value); 516 break; 517 } 518 } 519 520 template <typename T> 521 T Float(int index) const { 522 return register_.GetLane<T>(index); 523 } 524 525 template <typename T> 526 void SetFloat(int index, T value) const { 527 register_.Insert(index, value); 528 } 529 530 // When setting a result in a register of size less than Q, the top bits of 531 // the Q register must be cleared. 532 void ClearForWrite(VectorFormat vform) const { 533 unsigned size = RegisterSizeInBytesFromFormat(vform); 534 for (unsigned i = size; i < kQRegSizeInBytes; i++) { 535 SetUint(kFormat16B, i, 0); 536 } 537 } 538 539 // Saturation state for each lane of a vector. 540 enum Saturation { 541 kNotSaturated = 0, 542 kSignedSatPositive = 1 << 0, 543 kSignedSatNegative = 1 << 1, 544 kSignedSatMask = kSignedSatPositive | kSignedSatNegative, 545 kSignedSatUndefined = kSignedSatMask, 546 kUnsignedSatPositive = 1 << 2, 547 kUnsignedSatNegative = 1 << 3, 548 kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative, 549 kUnsignedSatUndefined = kUnsignedSatMask 550 }; 551 552 // Getters for saturation state. 553 Saturation GetSignedSaturation(int index) { 554 return static_cast<Saturation>(saturated_[index] & kSignedSatMask); 555 } 556 557 Saturation GetUnsignedSaturation(int index) { 558 return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask); 559 } 560 561 // Setters for saturation state. 562 void ClearSat(int index) { saturated_[index] = kNotSaturated; } 563 564 void SetSignedSat(int index, bool positive) { 565 SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative); 566 } 567 568 void SetUnsignedSat(int index, bool positive) { 569 SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative); 570 } 571 572 void SetSatFlag(int index, Saturation sat) { 573 saturated_[index] = static_cast<Saturation>(saturated_[index] | sat); 574 VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined); 575 VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined); 576 } 577 578 // Saturate lanes of a vector based on saturation state. 579 LogicVRegister& SignedSaturate(VectorFormat vform) { 580 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 581 Saturation sat = GetSignedSaturation(i); 582 if (sat == kSignedSatPositive) { 583 SetInt(vform, i, MaxIntFromFormat(vform)); 584 } else if (sat == kSignedSatNegative) { 585 SetInt(vform, i, MinIntFromFormat(vform)); 586 } 587 } 588 return *this; 589 } 590 591 LogicVRegister& UnsignedSaturate(VectorFormat vform) { 592 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 593 Saturation sat = GetUnsignedSaturation(i); 594 if (sat == kUnsignedSatPositive) { 595 SetUint(vform, i, MaxUintFromFormat(vform)); 596 } else if (sat == kUnsignedSatNegative) { 597 SetUint(vform, i, 0); 598 } 599 } 600 return *this; 601 } 602 603 // Getter for rounding state. 604 bool GetRounding(int index) { return round_[index]; } 605 606 // Setter for rounding state. 607 void SetRounding(int index, bool round) { round_[index] = round; } 608 609 // Round lanes of a vector based on rounding state. 610 LogicVRegister& Round(VectorFormat vform) { 611 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 612 SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0)); 613 } 614 return *this; 615 } 616 617 // Unsigned halve lanes of a vector, and use the saturation state to set the 618 // top bit. 619 LogicVRegister& Uhalve(VectorFormat vform) { 620 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 621 uint64_t val = Uint(vform, i); 622 SetRounding(i, (val & 1) == 1); 623 val >>= 1; 624 if (GetUnsignedSaturation(i) != kNotSaturated) { 625 // If the operation causes unsigned saturation, the bit shifted into the 626 // most significant bit must be set. 627 val |= (MaxUintFromFormat(vform) >> 1) + 1; 628 } 629 SetInt(vform, i, val); 630 } 631 return *this; 632 } 633 634 // Signed halve lanes of a vector, and use the carry state to set the top bit. 635 LogicVRegister& Halve(VectorFormat vform) { 636 for (int i = 0; i < LaneCountFromFormat(vform); i++) { 637 int64_t val = Int(vform, i); 638 SetRounding(i, (val & 1) == 1); 639 val >>= 1; 640 if (GetSignedSaturation(i) != kNotSaturated) { 641 // If the operation causes signed saturation, the sign bit must be 642 // inverted. 643 val ^= (MaxUintFromFormat(vform) >> 1) + 1; 644 } 645 SetInt(vform, i, val); 646 } 647 return *this; 648 } 649 650 private: 651 SimVRegister& register_; 652 653 // Allocate one saturation state entry per lane; largest register is type Q, 654 // and lanes can be a minimum of one byte wide. 655 Saturation saturated_[kQRegSizeInBytes]; 656 657 // Allocate one rounding state entry per lane. 658 bool round_[kQRegSizeInBytes]; 659 }; 660 661 // The proper way to initialize a simulated system register (such as NZCV) is as 662 // follows: 663 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); 664 class SimSystemRegister { 665 public: 666 // The default constructor represents a register which has no writable bits. 667 // It is not possible to set its value to anything other than 0. 668 SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {} 669 670 uint32_t GetRawValue() const { return value_; } 671 VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) { 672 return GetRawValue(); 673 } 674 675 void SetRawValue(uint32_t new_value) { 676 value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_); 677 } 678 679 uint32_t ExtractBits(int msb, int lsb) const { 680 return ExtractUnsignedBitfield32(msb, lsb, value_); 681 } 682 VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) { 683 return ExtractBits(msb, lsb); 684 } 685 686 int32_t ExtractSignedBits(int msb, int lsb) const { 687 return ExtractSignedBitfield32(msb, lsb, value_); 688 } 689 VIXL_DEPRECATED("ExtractSignedBits", 690 int32_t SignedBits(int msb, int lsb) const) { 691 return ExtractSignedBits(msb, lsb); 692 } 693 694 void SetBits(int msb, int lsb, uint32_t bits); 695 696 // Default system register values. 697 static SimSystemRegister DefaultValueFor(SystemRegister id); 698 699 #define DEFINE_GETTER(Name, HighBit, LowBit, Func) \ 700 uint32_t Get##Name() const { return this->Func(HighBit, LowBit); } \ 701 VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \ 702 void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); } 703 #define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \ 704 static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask); 705 706 SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK) 707 708 #undef DEFINE_ZERO_BITS 709 #undef DEFINE_GETTER 710 711 protected: 712 // Most system registers only implement a few of the bits in the word. Other 713 // bits are "read-as-zero, write-ignored". The write_ignore_mask argument 714 // describes the bits which are not modifiable. 715 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) 716 : value_(value), write_ignore_mask_(write_ignore_mask) {} 717 718 uint32_t value_; 719 uint32_t write_ignore_mask_; 720 }; 721 722 723 class SimExclusiveLocalMonitor { 724 public: 725 SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) { 726 Clear(); 727 } 728 729 // Clear the exclusive monitor (like clrex). 730 void Clear() { 731 address_ = 0; 732 size_ = 0; 733 } 734 735 // Clear the exclusive monitor most of the time. 736 void MaybeClear() { 737 if ((seed_ % kSkipClearProbability) != 0) { 738 Clear(); 739 } 740 741 // Advance seed_ using a simple linear congruential generator. 742 seed_ = (seed_ * 48271) % 2147483647; 743 } 744 745 // Mark the address range for exclusive access (like load-exclusive). 746 void MarkExclusive(uint64_t address, size_t size) { 747 address_ = address; 748 size_ = size; 749 } 750 751 // Return true if the address range is marked (like store-exclusive). 752 // This helper doesn't implicitly clear the monitor. 753 bool IsExclusive(uint64_t address, size_t size) { 754 VIXL_ASSERT(size > 0); 755 // Be pedantic: Require both the address and the size to match. 756 return (size == size_) && (address == address_); 757 } 758 759 private: 760 uint64_t address_; 761 size_t size_; 762 763 const int kSkipClearProbability; 764 uint32_t seed_; 765 }; 766 767 768 // We can't accurate simulate the global monitor since it depends on external 769 // influences. Instead, this implementation occasionally causes accesses to 770 // fail, according to kPassProbability. 771 class SimExclusiveGlobalMonitor { 772 public: 773 SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {} 774 775 bool IsExclusive(uint64_t address, size_t size) { 776 USE(address, size); 777 778 bool pass = (seed_ % kPassProbability) != 0; 779 // Advance seed_ using a simple linear congruential generator. 780 seed_ = (seed_ * 48271) % 2147483647; 781 return pass; 782 } 783 784 private: 785 const int kPassProbability; 786 uint32_t seed_; 787 }; 788 789 790 class Simulator : public DecoderVisitor { 791 public: 792 explicit Simulator(Decoder* decoder, FILE* stream = stdout); 793 ~Simulator(); 794 795 void ResetState(); 796 797 // Run the simulator. 798 virtual void Run(); 799 void RunFrom(const Instruction* first); 800 801 // Execution ends when the PC hits this address. 802 static const Instruction* kEndOfSimAddress; 803 804 // Simulation helpers. 805 const Instruction* ReadPc() const { return pc_; } 806 VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); } 807 808 enum BranchLogMode { LogBranches, NoBranchLog }; 809 810 void WritePc(const Instruction* new_pc, 811 BranchLogMode log_mode = LogBranches) { 812 if (log_mode == LogBranches) LogTakenBranch(new_pc); 813 pc_ = Memory::AddressUntag(new_pc); 814 pc_modified_ = true; 815 } 816 VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) { 817 return WritePc(new_pc); 818 } 819 820 void IncrementPc() { 821 if (!pc_modified_) { 822 pc_ = pc_->GetNextInstruction(); 823 } 824 } 825 VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); } 826 827 void ExecuteInstruction() { 828 // The program counter should always be aligned. 829 VIXL_ASSERT(IsWordAligned(pc_)); 830 pc_modified_ = false; 831 decoder_->Decode(pc_); 832 IncrementPc(); 833 LogAllWrittenRegisters(); 834 } 835 836 // Declare all Visitor functions. 837 #define DECLARE(A) \ 838 virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE; 839 VISITOR_LIST_THAT_RETURN(DECLARE) 840 #undef DECLARE 841 842 #define DECLARE(A) \ 843 VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr) \ 844 VIXL_OVERRIDE; 845 VISITOR_LIST_THAT_DONT_RETURN(DECLARE) 846 #undef DECLARE 847 848 849 // Integer register accessors. 850 851 // Basic accessor: Read the register as the specified type. 852 template <typename T> 853 T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { 854 VIXL_ASSERT( 855 code < kNumberOfRegisters || 856 ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode))); 857 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 858 T result; 859 memset(&result, 0, sizeof(result)); 860 return result; 861 } 862 if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) { 863 code = 31; 864 } 865 return registers_[code].Get<T>(); 866 } 867 template <typename T> 868 VIXL_DEPRECATED("ReadRegister", 869 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) 870 const) { 871 return ReadRegister<T>(code, r31mode); 872 } 873 874 // Common specialized accessors for the ReadRegister() template. 875 int32_t ReadWRegister(unsigned code, 876 Reg31Mode r31mode = Reg31IsZeroRegister) const { 877 return ReadRegister<int32_t>(code, r31mode); 878 } 879 VIXL_DEPRECATED("ReadWRegister", 880 int32_t wreg(unsigned code, 881 Reg31Mode r31mode = Reg31IsZeroRegister) const) { 882 return ReadWRegister(code, r31mode); 883 } 884 885 int64_t ReadXRegister(unsigned code, 886 Reg31Mode r31mode = Reg31IsZeroRegister) const { 887 return ReadRegister<int64_t>(code, r31mode); 888 } 889 VIXL_DEPRECATED("ReadXRegister", 890 int64_t xreg(unsigned code, 891 Reg31Mode r31mode = Reg31IsZeroRegister) const) { 892 return ReadXRegister(code, r31mode); 893 } 894 895 // As above, with parameterized size and return type. The value is 896 // either zero-extended or truncated to fit, as required. 897 template <typename T> 898 T ReadRegister(unsigned size, 899 unsigned code, 900 Reg31Mode r31mode = Reg31IsZeroRegister) const { 901 uint64_t raw; 902 switch (size) { 903 case kWRegSize: 904 raw = ReadRegister<uint32_t>(code, r31mode); 905 break; 906 case kXRegSize: 907 raw = ReadRegister<uint64_t>(code, r31mode); 908 break; 909 default: 910 VIXL_UNREACHABLE(); 911 return 0; 912 } 913 914 T result; 915 VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw)); 916 // Copy the result and truncate to fit. This assumes a little-endian host. 917 memcpy(&result, &raw, sizeof(result)); 918 return result; 919 } 920 template <typename T> 921 VIXL_DEPRECATED("ReadRegister", 922 T reg(unsigned size, 923 unsigned code, 924 Reg31Mode r31mode = Reg31IsZeroRegister) const) { 925 return ReadRegister<T>(size, code, r31mode); 926 } 927 928 // Use int64_t by default if T is not specified. 929 int64_t ReadRegister(unsigned size, 930 unsigned code, 931 Reg31Mode r31mode = Reg31IsZeroRegister) const { 932 return ReadRegister<int64_t>(size, code, r31mode); 933 } 934 VIXL_DEPRECATED("ReadRegister", 935 int64_t reg(unsigned size, 936 unsigned code, 937 Reg31Mode r31mode = Reg31IsZeroRegister) const) { 938 return ReadRegister(size, code, r31mode); 939 } 940 941 enum RegLogMode { LogRegWrites, NoRegLog }; 942 943 // Write 'value' into an integer register. The value is zero-extended. This 944 // behaviour matches AArch64 register writes. 945 template <typename T> 946 void WriteRegister(unsigned code, 947 T value, 948 RegLogMode log_mode = LogRegWrites, 949 Reg31Mode r31mode = Reg31IsZeroRegister) { 950 VIXL_STATIC_ASSERT((sizeof(T) == kWRegSizeInBytes) || 951 (sizeof(T) == kXRegSizeInBytes)); 952 VIXL_ASSERT( 953 code < kNumberOfRegisters || 954 ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode))); 955 956 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 957 return; 958 } 959 960 if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) { 961 code = 31; 962 } 963 964 registers_[code].Write(value); 965 966 if (log_mode == LogRegWrites) LogRegister(code, r31mode); 967 } 968 template <typename T> 969 VIXL_DEPRECATED("WriteRegister", 970 void set_reg(unsigned code, 971 T value, 972 RegLogMode log_mode = LogRegWrites, 973 Reg31Mode r31mode = Reg31IsZeroRegister)) { 974 WriteRegister<T>(code, value, log_mode, r31mode); 975 } 976 977 // Common specialized accessors for the set_reg() template. 978 void WriteWRegister(unsigned code, 979 int32_t value, 980 RegLogMode log_mode = LogRegWrites, 981 Reg31Mode r31mode = Reg31IsZeroRegister) { 982 WriteRegister(code, value, log_mode, r31mode); 983 } 984 VIXL_DEPRECATED("WriteWRegister", 985 void set_wreg(unsigned code, 986 int32_t value, 987 RegLogMode log_mode = LogRegWrites, 988 Reg31Mode r31mode = Reg31IsZeroRegister)) { 989 WriteWRegister(code, value, log_mode, r31mode); 990 } 991 992 void WriteXRegister(unsigned code, 993 int64_t value, 994 RegLogMode log_mode = LogRegWrites, 995 Reg31Mode r31mode = Reg31IsZeroRegister) { 996 WriteRegister(code, value, log_mode, r31mode); 997 } 998 VIXL_DEPRECATED("WriteXRegister", 999 void set_xreg(unsigned code, 1000 int64_t value, 1001 RegLogMode log_mode = LogRegWrites, 1002 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1003 WriteXRegister(code, value, log_mode, r31mode); 1004 } 1005 1006 // As above, with parameterized size and type. The value is either 1007 // zero-extended or truncated to fit, as required. 1008 template <typename T> 1009 void WriteRegister(unsigned size, 1010 unsigned code, 1011 T value, 1012 RegLogMode log_mode = LogRegWrites, 1013 Reg31Mode r31mode = Reg31IsZeroRegister) { 1014 // Zero-extend the input. 1015 uint64_t raw = 0; 1016 VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw)); 1017 memcpy(&raw, &value, sizeof(value)); 1018 1019 // Write (and possibly truncate) the value. 1020 switch (size) { 1021 case kWRegSize: 1022 WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode); 1023 break; 1024 case kXRegSize: 1025 WriteRegister(code, raw, log_mode, r31mode); 1026 break; 1027 default: 1028 VIXL_UNREACHABLE(); 1029 return; 1030 } 1031 } 1032 template <typename T> 1033 VIXL_DEPRECATED("WriteRegister", 1034 void set_reg(unsigned size, 1035 unsigned code, 1036 T value, 1037 RegLogMode log_mode = LogRegWrites, 1038 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1039 WriteRegister(size, code, value, log_mode, r31mode); 1040 } 1041 1042 // Common specialized accessors for the set_reg() template. 1043 1044 // Commonly-used special cases. 1045 template <typename T> 1046 void WriteLr(T value) { 1047 WriteRegister(kLinkRegCode, value); 1048 } 1049 template <typename T> 1050 VIXL_DEPRECATED("WriteLr", void set_lr(T value)) { 1051 WriteLr(value); 1052 } 1053 1054 template <typename T> 1055 void WriteSp(T value) { 1056 WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer); 1057 } 1058 template <typename T> 1059 VIXL_DEPRECATED("WriteSp", void set_sp(T value)) { 1060 WriteSp(value); 1061 } 1062 1063 // Vector register accessors. 1064 // These are equivalent to the integer register accessors, but for vector 1065 // registers. 1066 1067 // A structure for representing a 128-bit Q register. 1068 struct qreg_t { 1069 uint8_t val[kQRegSizeInBytes]; 1070 }; 1071 1072 // Basic accessor: read the register as the specified type. 1073 template <typename T> 1074 T ReadVRegister(unsigned code) const { 1075 VIXL_STATIC_ASSERT( 1076 (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) || 1077 (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) || 1078 (sizeof(T) == kQRegSizeInBytes)); 1079 VIXL_ASSERT(code < kNumberOfVRegisters); 1080 1081 return vregisters_[code].Get<T>(); 1082 } 1083 template <typename T> 1084 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) { 1085 return ReadVRegister<T>(code); 1086 } 1087 1088 // Common specialized accessors for the vreg() template. 1089 int8_t ReadBRegister(unsigned code) const { 1090 return ReadVRegister<int8_t>(code); 1091 } 1092 VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) { 1093 return ReadBRegister(code); 1094 } 1095 1096 int16_t ReadHRegister(unsigned code) const { 1097 return ReadVRegister<int16_t>(code); 1098 } 1099 VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) { 1100 return ReadHRegister(code); 1101 } 1102 1103 float ReadSRegister(unsigned code) const { 1104 return ReadVRegister<float>(code); 1105 } 1106 VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) { 1107 return ReadSRegister(code); 1108 } 1109 1110 uint32_t ReadSRegisterBits(unsigned code) const { 1111 return ReadVRegister<uint32_t>(code); 1112 } 1113 VIXL_DEPRECATED("ReadSRegisterBits", 1114 uint32_t sreg_bits(unsigned code) const) { 1115 return ReadSRegisterBits(code); 1116 } 1117 1118 double ReadDRegister(unsigned code) const { 1119 return ReadVRegister<double>(code); 1120 } 1121 VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) { 1122 return ReadDRegister(code); 1123 } 1124 1125 uint64_t ReadDRegisterBits(unsigned code) const { 1126 return ReadVRegister<uint64_t>(code); 1127 } 1128 VIXL_DEPRECATED("ReadDRegisterBits", 1129 uint64_t dreg_bits(unsigned code) const) { 1130 return ReadDRegisterBits(code); 1131 } 1132 1133 qreg_t ReadQRegister(unsigned code) const { 1134 return ReadVRegister<qreg_t>(code); 1135 } 1136 VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) { 1137 return ReadQRegister(code); 1138 } 1139 1140 // As above, with parameterized size and return type. The value is 1141 // either zero-extended or truncated to fit, as required. 1142 template <typename T> 1143 T ReadVRegister(unsigned size, unsigned code) const { 1144 uint64_t raw = 0; 1145 T result; 1146 1147 switch (size) { 1148 case kSRegSize: 1149 raw = ReadVRegister<uint32_t>(code); 1150 break; 1151 case kDRegSize: 1152 raw = ReadVRegister<uint64_t>(code); 1153 break; 1154 default: 1155 VIXL_UNREACHABLE(); 1156 break; 1157 } 1158 1159 VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw)); 1160 // Copy the result and truncate to fit. This assumes a little-endian host. 1161 memcpy(&result, &raw, sizeof(result)); 1162 return result; 1163 } 1164 template <typename T> 1165 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) { 1166 return ReadVRegister<T>(size, code); 1167 } 1168 1169 SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; } 1170 VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) { 1171 return ReadVRegister(code); 1172 } 1173 1174 // Basic accessor: Write the specified value. 1175 template <typename T> 1176 void WriteVRegister(unsigned code, 1177 T value, 1178 RegLogMode log_mode = LogRegWrites) { 1179 VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) || 1180 (sizeof(value) == kHRegSizeInBytes) || 1181 (sizeof(value) == kSRegSizeInBytes) || 1182 (sizeof(value) == kDRegSizeInBytes) || 1183 (sizeof(value) == kQRegSizeInBytes)); 1184 VIXL_ASSERT(code < kNumberOfVRegisters); 1185 vregisters_[code].Write(value); 1186 1187 if (log_mode == LogRegWrites) { 1188 LogVRegister(code, GetPrintRegisterFormat(value)); 1189 } 1190 } 1191 template <typename T> 1192 VIXL_DEPRECATED("WriteVRegister", 1193 void set_vreg(unsigned code, 1194 T value, 1195 RegLogMode log_mode = LogRegWrites)) { 1196 WriteVRegister(code, value, log_mode); 1197 } 1198 1199 // Common specialized accessors for the WriteVRegister() template. 1200 void WriteBRegister(unsigned code, 1201 int8_t value, 1202 RegLogMode log_mode = LogRegWrites) { 1203 WriteVRegister(code, value, log_mode); 1204 } 1205 VIXL_DEPRECATED("WriteBRegister", 1206 void set_breg(unsigned code, 1207 int8_t value, 1208 RegLogMode log_mode = LogRegWrites)) { 1209 return WriteBRegister(code, value, log_mode); 1210 } 1211 1212 void WriteHRegister(unsigned code, 1213 int16_t value, 1214 RegLogMode log_mode = LogRegWrites) { 1215 WriteVRegister(code, value, log_mode); 1216 } 1217 VIXL_DEPRECATED("WriteHRegister", 1218 void set_hreg(unsigned code, 1219 int16_t value, 1220 RegLogMode log_mode = LogRegWrites)) { 1221 return WriteHRegister(code, value, log_mode); 1222 } 1223 1224 void WriteSRegister(unsigned code, 1225 float value, 1226 RegLogMode log_mode = LogRegWrites) { 1227 WriteVRegister(code, value, log_mode); 1228 } 1229 VIXL_DEPRECATED("WriteSRegister", 1230 void set_sreg(unsigned code, 1231 float value, 1232 RegLogMode log_mode = LogRegWrites)) { 1233 WriteSRegister(code, value, log_mode); 1234 } 1235 1236 void WriteSRegisterBits(unsigned code, 1237 uint32_t value, 1238 RegLogMode log_mode = LogRegWrites) { 1239 WriteVRegister(code, value, log_mode); 1240 } 1241 VIXL_DEPRECATED("WriteSRegisterBits", 1242 void set_sreg_bits(unsigned code, 1243 uint32_t value, 1244 RegLogMode log_mode = LogRegWrites)) { 1245 WriteSRegisterBits(code, value, log_mode); 1246 } 1247 1248 void WriteDRegister(unsigned code, 1249 double value, 1250 RegLogMode log_mode = LogRegWrites) { 1251 WriteVRegister(code, value, log_mode); 1252 } 1253 VIXL_DEPRECATED("WriteDRegister", 1254 void set_dreg(unsigned code, 1255 double value, 1256 RegLogMode log_mode = LogRegWrites)) { 1257 WriteDRegister(code, value, log_mode); 1258 } 1259 1260 void WriteDRegisterBits(unsigned code, 1261 uint64_t value, 1262 RegLogMode log_mode = LogRegWrites) { 1263 WriteVRegister(code, value, log_mode); 1264 } 1265 VIXL_DEPRECATED("WriteDRegisterBits", 1266 void set_dreg_bits(unsigned code, 1267 uint64_t value, 1268 RegLogMode log_mode = LogRegWrites)) { 1269 WriteDRegisterBits(code, value, log_mode); 1270 } 1271 1272 void WriteQRegister(unsigned code, 1273 qreg_t value, 1274 RegLogMode log_mode = LogRegWrites) { 1275 WriteVRegister(code, value, log_mode); 1276 } 1277 VIXL_DEPRECATED("WriteQRegister", 1278 void set_qreg(unsigned code, 1279 qreg_t value, 1280 RegLogMode log_mode = LogRegWrites)) { 1281 WriteQRegister(code, value, log_mode); 1282 } 1283 1284 template <typename T> 1285 T ReadRegister(Register reg) const { 1286 return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister); 1287 } 1288 1289 template <typename T> 1290 void WriteRegister(Register reg, 1291 T value, 1292 RegLogMode log_mode = LogRegWrites) { 1293 WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister); 1294 } 1295 1296 template <typename T> 1297 T ReadVRegister(VRegister vreg) const { 1298 return ReadVRegister<T>(vreg.GetCode()); 1299 } 1300 1301 template <typename T> 1302 void WriteVRegister(VRegister vreg, 1303 T value, 1304 RegLogMode log_mode = LogRegWrites) { 1305 WriteVRegister<T>(vreg.GetCode(), value, log_mode); 1306 } 1307 1308 template <typename T> 1309 T ReadCPURegister(CPURegister reg) const { 1310 if (reg.IsVRegister()) { 1311 return ReadVRegister<T>(VRegister(reg)); 1312 } else { 1313 return ReadRegister<T>(Register(reg)); 1314 } 1315 } 1316 1317 template <typename T> 1318 void WriteCPURegister(CPURegister reg, 1319 T value, 1320 RegLogMode log_mode = LogRegWrites) { 1321 if (reg.IsVRegister()) { 1322 WriteVRegister<T>(VRegister(reg), value, log_mode); 1323 } else { 1324 WriteRegister<T>(Register(reg), value, log_mode); 1325 } 1326 } 1327 1328 uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const; 1329 1330 template <typename T> 1331 T ReadGenericOperand(GenericOperand operand) const { 1332 if (operand.IsCPURegister()) { 1333 return ReadCPURegister<T>(operand.GetCPURegister()); 1334 } else { 1335 VIXL_ASSERT(operand.IsMemOperand()); 1336 return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand())); 1337 } 1338 } 1339 1340 template <typename T> 1341 void WriteGenericOperand(GenericOperand operand, 1342 T value, 1343 RegLogMode log_mode = LogRegWrites) { 1344 if (operand.IsCPURegister()) { 1345 WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode); 1346 } else { 1347 VIXL_ASSERT(operand.IsMemOperand()); 1348 Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value); 1349 } 1350 } 1351 1352 bool ReadN() const { return nzcv_.GetN() != 0; } 1353 VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); } 1354 1355 bool ReadZ() const { return nzcv_.GetZ() != 0; } 1356 VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); } 1357 1358 bool ReadC() const { return nzcv_.GetC() != 0; } 1359 VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); } 1360 1361 bool ReadV() const { return nzcv_.GetV() != 0; } 1362 VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); } 1363 1364 SimSystemRegister& ReadNzcv() { return nzcv_; } 1365 VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); } 1366 1367 // TODO: Find a way to make the fpcr_ members return the proper types, so 1368 // these accessors are not necessary. 1369 FPRounding ReadRMode() const { 1370 return static_cast<FPRounding>(fpcr_.GetRMode()); 1371 } 1372 VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); } 1373 1374 bool ReadDN() const { return fpcr_.GetDN() != 0; } 1375 VIXL_DEPRECATED("ReadDN", bool DN()) { return ReadDN(); } 1376 1377 SimSystemRegister& ReadFpcr() { return fpcr_; } 1378 VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); } 1379 1380 // Specify relevant register formats for Print(V)Register and related helpers. 1381 enum PrintRegisterFormat { 1382 // The lane size. 1383 kPrintRegLaneSizeB = 0 << 0, 1384 kPrintRegLaneSizeH = 1 << 0, 1385 kPrintRegLaneSizeS = 2 << 0, 1386 kPrintRegLaneSizeW = kPrintRegLaneSizeS, 1387 kPrintRegLaneSizeD = 3 << 0, 1388 kPrintRegLaneSizeX = kPrintRegLaneSizeD, 1389 kPrintRegLaneSizeQ = 4 << 0, 1390 1391 kPrintRegLaneSizeOffset = 0, 1392 kPrintRegLaneSizeMask = 7 << 0, 1393 1394 // The lane count. 1395 kPrintRegAsScalar = 0, 1396 kPrintRegAsDVector = 1 << 3, 1397 kPrintRegAsQVector = 2 << 3, 1398 1399 kPrintRegAsVectorMask = 3 << 3, 1400 1401 // Indicate floating-point format lanes. (This flag is only supported for S- 1402 // and D-sized lanes.) 1403 kPrintRegAsFP = 1 << 5, 1404 1405 // Supported combinations. 1406 1407 kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar, 1408 kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar, 1409 kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, 1410 kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, 1411 1412 kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar, 1413 kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector, 1414 kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector, 1415 kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar, 1416 kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector, 1417 kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector, 1418 kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar, 1419 kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector, 1420 kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector, 1421 kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, 1422 kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP, 1423 kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP, 1424 kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar, 1425 kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector, 1426 kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, 1427 kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP, 1428 kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar 1429 }; 1430 1431 unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) { 1432 return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset; 1433 } 1434 1435 unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) { 1436 return 1 << GetPrintRegLaneSizeInBytesLog2(format); 1437 } 1438 1439 unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) { 1440 if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2; 1441 if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2; 1442 1443 // Scalar types. 1444 return GetPrintRegLaneSizeInBytesLog2(format); 1445 } 1446 1447 unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) { 1448 return 1 << GetPrintRegSizeInBytesLog2(format); 1449 } 1450 1451 unsigned GetPrintRegLaneCount(PrintRegisterFormat format) { 1452 unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format); 1453 unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format); 1454 VIXL_ASSERT(reg_size_log2 >= lane_size_log2); 1455 return 1 << (reg_size_log2 - lane_size_log2); 1456 } 1457 1458 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size, 1459 unsigned lane_size); 1460 1461 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) { 1462 return GetPrintRegisterFormatForSize(size, size); 1463 } 1464 1465 PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) { 1466 switch (size) { 1467 default: 1468 VIXL_UNREACHABLE(); 1469 return kPrintDReg; 1470 case kDRegSizeInBytes: 1471 return kPrintDReg; 1472 case kSRegSizeInBytes: 1473 return kPrintSReg; 1474 } 1475 } 1476 1477 PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) { 1478 if ((GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) || 1479 (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) { 1480 return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP); 1481 } 1482 return format; 1483 } 1484 1485 template <typename T> 1486 PrintRegisterFormat GetPrintRegisterFormat(T value) { 1487 return GetPrintRegisterFormatForSize(sizeof(value)); 1488 } 1489 1490 PrintRegisterFormat GetPrintRegisterFormat(double value) { 1491 VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes); 1492 return GetPrintRegisterFormatForSizeFP(sizeof(value)); 1493 } 1494 1495 PrintRegisterFormat GetPrintRegisterFormat(float value) { 1496 VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes); 1497 return GetPrintRegisterFormatForSizeFP(sizeof(value)); 1498 } 1499 1500 PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform); 1501 PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform); 1502 1503 // Print all registers of the specified types. 1504 void PrintRegisters(); 1505 void PrintVRegisters(); 1506 void PrintSystemRegisters(); 1507 1508 // As above, but only print the registers that have been updated. 1509 void PrintWrittenRegisters(); 1510 void PrintWrittenVRegisters(); 1511 1512 // As above, but respect LOG_REG and LOG_VREG. 1513 void LogWrittenRegisters() { 1514 if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters(); 1515 } 1516 void LogWrittenVRegisters() { 1517 if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters(); 1518 } 1519 void LogAllWrittenRegisters() { 1520 LogWrittenRegisters(); 1521 LogWrittenVRegisters(); 1522 } 1523 1524 // Print individual register values (after update). 1525 void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer); 1526 void PrintVRegister(unsigned code, PrintRegisterFormat format); 1527 void PrintSystemRegister(SystemRegister id); 1528 void PrintTakenBranch(const Instruction* target); 1529 1530 // Like Print* (above), but respect GetTraceParameters(). 1531 void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) { 1532 if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode); 1533 } 1534 void LogVRegister(unsigned code, PrintRegisterFormat format) { 1535 if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format); 1536 } 1537 void LogSystemRegister(SystemRegister id) { 1538 if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id); 1539 } 1540 void LogTakenBranch(const Instruction* target) { 1541 if (GetTraceParameters() & LOG_BRANCH) PrintTakenBranch(target); 1542 } 1543 1544 // Print memory accesses. 1545 void PrintRead(uintptr_t address, 1546 unsigned reg_code, 1547 PrintRegisterFormat format); 1548 void PrintWrite(uintptr_t address, 1549 unsigned reg_code, 1550 PrintRegisterFormat format); 1551 void PrintVRead(uintptr_t address, 1552 unsigned reg_code, 1553 PrintRegisterFormat format, 1554 unsigned lane); 1555 void PrintVWrite(uintptr_t address, 1556 unsigned reg_code, 1557 PrintRegisterFormat format, 1558 unsigned lane); 1559 1560 // Like Print* (above), but respect GetTraceParameters(). 1561 void LogRead(uintptr_t address, 1562 unsigned reg_code, 1563 PrintRegisterFormat format) { 1564 if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format); 1565 } 1566 void LogWrite(uintptr_t address, 1567 unsigned reg_code, 1568 PrintRegisterFormat format) { 1569 if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format); 1570 } 1571 void LogVRead(uintptr_t address, 1572 unsigned reg_code, 1573 PrintRegisterFormat format, 1574 unsigned lane = 0) { 1575 if (GetTraceParameters() & LOG_VREGS) { 1576 PrintVRead(address, reg_code, format, lane); 1577 } 1578 } 1579 void LogVWrite(uintptr_t address, 1580 unsigned reg_code, 1581 PrintRegisterFormat format, 1582 unsigned lane = 0) { 1583 if (GetTraceParameters() & LOG_WRITE) { 1584 PrintVWrite(address, reg_code, format, lane); 1585 } 1586 } 1587 1588 // Helper functions for register tracing. 1589 void PrintRegisterRawHelper(unsigned code, 1590 Reg31Mode r31mode, 1591 int size_in_bytes = kXRegSizeInBytes); 1592 void PrintVRegisterRawHelper(unsigned code, 1593 int bytes = kQRegSizeInBytes, 1594 int lsb = 0); 1595 void PrintVRegisterFPHelper(unsigned code, 1596 unsigned lane_size_in_bytes, 1597 int lane_count = 1, 1598 int rightmost_lane = 0); 1599 1600 VIXL_NO_RETURN void DoUnreachable(const Instruction* instr); 1601 void DoTrace(const Instruction* instr); 1602 void DoLog(const Instruction* instr); 1603 1604 static const char* WRegNameForCode(unsigned code, 1605 Reg31Mode mode = Reg31IsZeroRegister); 1606 static const char* XRegNameForCode(unsigned code, 1607 Reg31Mode mode = Reg31IsZeroRegister); 1608 static const char* SRegNameForCode(unsigned code); 1609 static const char* DRegNameForCode(unsigned code); 1610 static const char* VRegNameForCode(unsigned code); 1611 1612 bool IsColouredTrace() const { return coloured_trace_; } 1613 VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) { 1614 return IsColouredTrace(); 1615 } 1616 1617 void SetColouredTrace(bool value); 1618 VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) { 1619 SetColouredTrace(value); 1620 } 1621 1622 // Values for traces parameters defined in simulator-constants-aarch64.h in 1623 // enum TraceParameters. 1624 int GetTraceParameters() const { return trace_parameters_; } 1625 VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) { 1626 return GetTraceParameters(); 1627 } 1628 1629 void SetTraceParameters(int parameters); 1630 VIXL_DEPRECATED("SetTraceParameters", 1631 void set_trace_parameters(int parameters)) { 1632 SetTraceParameters(parameters); 1633 } 1634 1635 void SetInstructionStats(bool value); 1636 VIXL_DEPRECATED("SetInstructionStats", 1637 void set_instruction_stats(bool value)) { 1638 SetInstructionStats(value); 1639 } 1640 1641 // Clear the simulated local monitor to force the next store-exclusive 1642 // instruction to fail. 1643 void ClearLocalMonitor() { local_monitor_.Clear(); } 1644 1645 void SilenceExclusiveAccessWarning() { 1646 print_exclusive_access_warning_ = false; 1647 } 1648 1649 // Runtime call emulation support. 1650 // It requires VIXL's ABI features, and C++11 or greater. 1651 // Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect 1652 // in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253 1653 #if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \ 1654 (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1)) 1655 1656 #define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 1657 1658 // The implementation of the runtime call helpers require the functionality 1659 // provided by `std::index_sequence`. It is only available from C++14, but 1660 // we want runtime call simulation to work from C++11, so we emulate if 1661 // necessary. 1662 #if __cplusplus >= 201402L 1663 template <std::size_t... I> 1664 using local_index_sequence = std::index_sequence<I...>; 1665 template <typename... P> 1666 using __local_index_sequence_for = std::index_sequence_for<P...>; 1667 #else 1668 // Emulate the behaviour of `std::index_sequence` and 1669 // `std::index_sequence_for`. 1670 // Naming follow the `std` names, prefixed with `emulated_`. 1671 template <size_t... I> 1672 struct emulated_index_sequence {}; 1673 1674 // A recursive template to create a sequence of indexes. 1675 // The base case (for `N == 0`) is declared outside of the class scope, as 1676 // required by C++. 1677 template <std::size_t N, size_t... I> 1678 struct emulated_make_index_sequence_helper 1679 : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {}; 1680 1681 template <std::size_t N> 1682 struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> { 1683 }; 1684 1685 template <typename... P> 1686 struct emulated_index_sequence_for 1687 : emulated_make_index_sequence<sizeof...(P)> {}; 1688 1689 template <std::size_t... I> 1690 using local_index_sequence = emulated_index_sequence<I...>; 1691 template <typename... P> 1692 using __local_index_sequence_for = emulated_index_sequence_for<P...>; 1693 #endif 1694 1695 // Expand the argument tuple and perform the call. 1696 template <typename R, typename... P, std::size_t... I> 1697 R DoRuntimeCall(R (*function)(P...), 1698 std::tuple<P...> arguments, 1699 local_index_sequence<I...>) { 1700 return function(std::get<I>(arguments)...); 1701 } 1702 1703 template <typename R, typename... P> 1704 void RuntimeCallNonVoid(R (*function)(P...)) { 1705 ABI abi; 1706 std::tuple<P...> argument_operands{ 1707 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1708 R return_value = DoRuntimeCall(function, 1709 argument_operands, 1710 __local_index_sequence_for<P...>{}); 1711 WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value); 1712 } 1713 1714 template <typename R, typename... P> 1715 void RuntimeCallVoid(R (*function)(P...)) { 1716 ABI abi; 1717 std::tuple<P...> argument_operands{ 1718 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1719 DoRuntimeCall(function, 1720 argument_operands, 1721 __local_index_sequence_for<P...>{}); 1722 } 1723 1724 // We use `struct` for `void` return type specialisation. 1725 template <typename R, typename... P> 1726 struct RuntimeCallStructHelper { 1727 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) { 1728 R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer); 1729 simulator->RuntimeCallNonVoid(function); 1730 } 1731 }; 1732 1733 // Partial specialization when the return type is `void`. 1734 template <typename... P> 1735 struct RuntimeCallStructHelper<void, P...> { 1736 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) { 1737 void (*function)(P...) = 1738 reinterpret_cast<void (*)(P...)>(function_pointer); 1739 simulator->RuntimeCallVoid(function); 1740 } 1741 }; 1742 #endif 1743 1744 protected: 1745 const char* clr_normal; 1746 const char* clr_flag_name; 1747 const char* clr_flag_value; 1748 const char* clr_reg_name; 1749 const char* clr_reg_value; 1750 const char* clr_vreg_name; 1751 const char* clr_vreg_value; 1752 const char* clr_memory_address; 1753 const char* clr_warning; 1754 const char* clr_warning_message; 1755 const char* clr_printf; 1756 const char* clr_branch_marker; 1757 1758 // Simulation helpers ------------------------------------ 1759 bool ConditionPassed(Condition cond) { 1760 switch (cond) { 1761 case eq: 1762 return ReadZ(); 1763 case ne: 1764 return !ReadZ(); 1765 case hs: 1766 return ReadC(); 1767 case lo: 1768 return !ReadC(); 1769 case mi: 1770 return ReadN(); 1771 case pl: 1772 return !ReadN(); 1773 case vs: 1774 return ReadV(); 1775 case vc: 1776 return !ReadV(); 1777 case hi: 1778 return ReadC() && !ReadZ(); 1779 case ls: 1780 return !(ReadC() && !ReadZ()); 1781 case ge: 1782 return ReadN() == ReadV(); 1783 case lt: 1784 return ReadN() != ReadV(); 1785 case gt: 1786 return !ReadZ() && (ReadN() == ReadV()); 1787 case le: 1788 return !(!ReadZ() && (ReadN() == ReadV())); 1789 case nv: 1790 VIXL_FALLTHROUGH(); 1791 case al: 1792 return true; 1793 default: 1794 VIXL_UNREACHABLE(); 1795 return false; 1796 } 1797 } 1798 1799 bool ConditionPassed(Instr cond) { 1800 return ConditionPassed(static_cast<Condition>(cond)); 1801 } 1802 1803 bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); } 1804 1805 void AddSubHelper(const Instruction* instr, int64_t op2); 1806 uint64_t AddWithCarry(unsigned reg_size, 1807 bool set_flags, 1808 uint64_t left, 1809 uint64_t right, 1810 int carry_in = 0); 1811 void LogicalHelper(const Instruction* instr, int64_t op2); 1812 void ConditionalCompareHelper(const Instruction* instr, int64_t op2); 1813 void LoadStoreHelper(const Instruction* instr, 1814 int64_t offset, 1815 AddrMode addrmode); 1816 void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode); 1817 uintptr_t AddressModeHelper(unsigned addr_reg, 1818 int64_t offset, 1819 AddrMode addrmode); 1820 void NEONLoadStoreMultiStructHelper(const Instruction* instr, 1821 AddrMode addr_mode); 1822 void NEONLoadStoreSingleStructHelper(const Instruction* instr, 1823 AddrMode addr_mode); 1824 1825 uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; } 1826 1827 template <typename T> 1828 T* AddressUntag(T* address) { 1829 uintptr_t address_raw = reinterpret_cast<uintptr_t>(address); 1830 return reinterpret_cast<T*>(AddressUntag(address_raw)); 1831 } 1832 1833 int64_t ShiftOperand(unsigned reg_size, 1834 int64_t value, 1835 Shift shift_type, 1836 unsigned amount) const; 1837 int64_t ExtendValue(unsigned reg_width, 1838 int64_t value, 1839 Extend extend_type, 1840 unsigned left_shift = 0) const; 1841 uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const; 1842 1843 void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1844 void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr); 1845 void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1846 void ld2(VectorFormat vform, 1847 LogicVRegister dst1, 1848 LogicVRegister dst2, 1849 uint64_t addr); 1850 void ld2(VectorFormat vform, 1851 LogicVRegister dst1, 1852 LogicVRegister dst2, 1853 int index, 1854 uint64_t addr); 1855 void ld2r(VectorFormat vform, 1856 LogicVRegister dst1, 1857 LogicVRegister dst2, 1858 uint64_t addr); 1859 void ld3(VectorFormat vform, 1860 LogicVRegister dst1, 1861 LogicVRegister dst2, 1862 LogicVRegister dst3, 1863 uint64_t addr); 1864 void ld3(VectorFormat vform, 1865 LogicVRegister dst1, 1866 LogicVRegister dst2, 1867 LogicVRegister dst3, 1868 int index, 1869 uint64_t addr); 1870 void ld3r(VectorFormat vform, 1871 LogicVRegister dst1, 1872 LogicVRegister dst2, 1873 LogicVRegister dst3, 1874 uint64_t addr); 1875 void ld4(VectorFormat vform, 1876 LogicVRegister dst1, 1877 LogicVRegister dst2, 1878 LogicVRegister dst3, 1879 LogicVRegister dst4, 1880 uint64_t addr); 1881 void ld4(VectorFormat vform, 1882 LogicVRegister dst1, 1883 LogicVRegister dst2, 1884 LogicVRegister dst3, 1885 LogicVRegister dst4, 1886 int index, 1887 uint64_t addr); 1888 void ld4r(VectorFormat vform, 1889 LogicVRegister dst1, 1890 LogicVRegister dst2, 1891 LogicVRegister dst3, 1892 LogicVRegister dst4, 1893 uint64_t addr); 1894 void st1(VectorFormat vform, LogicVRegister src, uint64_t addr); 1895 void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr); 1896 void st2(VectorFormat vform, 1897 LogicVRegister src, 1898 LogicVRegister src2, 1899 uint64_t addr); 1900 void st2(VectorFormat vform, 1901 LogicVRegister src, 1902 LogicVRegister src2, 1903 int index, 1904 uint64_t addr); 1905 void st3(VectorFormat vform, 1906 LogicVRegister src, 1907 LogicVRegister src2, 1908 LogicVRegister src3, 1909 uint64_t addr); 1910 void st3(VectorFormat vform, 1911 LogicVRegister src, 1912 LogicVRegister src2, 1913 LogicVRegister src3, 1914 int index, 1915 uint64_t addr); 1916 void st4(VectorFormat vform, 1917 LogicVRegister src, 1918 LogicVRegister src2, 1919 LogicVRegister src3, 1920 LogicVRegister src4, 1921 uint64_t addr); 1922 void st4(VectorFormat vform, 1923 LogicVRegister src, 1924 LogicVRegister src2, 1925 LogicVRegister src3, 1926 LogicVRegister src4, 1927 int index, 1928 uint64_t addr); 1929 LogicVRegister cmp(VectorFormat vform, 1930 LogicVRegister dst, 1931 const LogicVRegister& src1, 1932 const LogicVRegister& src2, 1933 Condition cond); 1934 LogicVRegister cmp(VectorFormat vform, 1935 LogicVRegister dst, 1936 const LogicVRegister& src1, 1937 int imm, 1938 Condition cond); 1939 LogicVRegister cmptst(VectorFormat vform, 1940 LogicVRegister dst, 1941 const LogicVRegister& src1, 1942 const LogicVRegister& src2); 1943 LogicVRegister add(VectorFormat vform, 1944 LogicVRegister dst, 1945 const LogicVRegister& src1, 1946 const LogicVRegister& src2); 1947 LogicVRegister addp(VectorFormat vform, 1948 LogicVRegister dst, 1949 const LogicVRegister& src1, 1950 const LogicVRegister& src2); 1951 LogicVRegister mla(VectorFormat vform, 1952 LogicVRegister dst, 1953 const LogicVRegister& src1, 1954 const LogicVRegister& src2); 1955 LogicVRegister mls(VectorFormat vform, 1956 LogicVRegister dst, 1957 const LogicVRegister& src1, 1958 const LogicVRegister& src2); 1959 LogicVRegister mul(VectorFormat vform, 1960 LogicVRegister dst, 1961 const LogicVRegister& src1, 1962 const LogicVRegister& src2); 1963 LogicVRegister mul(VectorFormat vform, 1964 LogicVRegister dst, 1965 const LogicVRegister& src1, 1966 const LogicVRegister& src2, 1967 int index); 1968 LogicVRegister mla(VectorFormat vform, 1969 LogicVRegister dst, 1970 const LogicVRegister& src1, 1971 const LogicVRegister& src2, 1972 int index); 1973 LogicVRegister mls(VectorFormat vform, 1974 LogicVRegister dst, 1975 const LogicVRegister& src1, 1976 const LogicVRegister& src2, 1977 int index); 1978 LogicVRegister pmul(VectorFormat vform, 1979 LogicVRegister dst, 1980 const LogicVRegister& src1, 1981 const LogicVRegister& src2); 1982 1983 typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform, 1984 LogicVRegister dst, 1985 const LogicVRegister& src1, 1986 const LogicVRegister& src2, 1987 int index); 1988 LogicVRegister fmul(VectorFormat vform, 1989 LogicVRegister dst, 1990 const LogicVRegister& src1, 1991 const LogicVRegister& src2, 1992 int index); 1993 LogicVRegister fmla(VectorFormat vform, 1994 LogicVRegister dst, 1995 const LogicVRegister& src1, 1996 const LogicVRegister& src2, 1997 int index); 1998 LogicVRegister fmls(VectorFormat vform, 1999 LogicVRegister dst, 2000 const LogicVRegister& src1, 2001 const LogicVRegister& src2, 2002 int index); 2003 LogicVRegister fmulx(VectorFormat vform, 2004 LogicVRegister dst, 2005 const LogicVRegister& src1, 2006 const LogicVRegister& src2, 2007 int index); 2008 LogicVRegister smull(VectorFormat vform, 2009 LogicVRegister dst, 2010 const LogicVRegister& src1, 2011 const LogicVRegister& src2, 2012 int index); 2013 LogicVRegister smull2(VectorFormat vform, 2014 LogicVRegister dst, 2015 const LogicVRegister& src1, 2016 const LogicVRegister& src2, 2017 int index); 2018 LogicVRegister umull(VectorFormat vform, 2019 LogicVRegister dst, 2020 const LogicVRegister& src1, 2021 const LogicVRegister& src2, 2022 int index); 2023 LogicVRegister umull2(VectorFormat vform, 2024 LogicVRegister dst, 2025 const LogicVRegister& src1, 2026 const LogicVRegister& src2, 2027 int index); 2028 LogicVRegister smlal(VectorFormat vform, 2029 LogicVRegister dst, 2030 const LogicVRegister& src1, 2031 const LogicVRegister& src2, 2032 int index); 2033 LogicVRegister smlal2(VectorFormat vform, 2034 LogicVRegister dst, 2035 const LogicVRegister& src1, 2036 const LogicVRegister& src2, 2037 int index); 2038 LogicVRegister umlal(VectorFormat vform, 2039 LogicVRegister dst, 2040 const LogicVRegister& src1, 2041 const LogicVRegister& src2, 2042 int index); 2043 LogicVRegister umlal2(VectorFormat vform, 2044 LogicVRegister dst, 2045 const LogicVRegister& src1, 2046 const LogicVRegister& src2, 2047 int index); 2048 LogicVRegister smlsl(VectorFormat vform, 2049 LogicVRegister dst, 2050 const LogicVRegister& src1, 2051 const LogicVRegister& src2, 2052 int index); 2053 LogicVRegister smlsl2(VectorFormat vform, 2054 LogicVRegister dst, 2055 const LogicVRegister& src1, 2056 const LogicVRegister& src2, 2057 int index); 2058 LogicVRegister umlsl(VectorFormat vform, 2059 LogicVRegister dst, 2060 const LogicVRegister& src1, 2061 const LogicVRegister& src2, 2062 int index); 2063 LogicVRegister umlsl2(VectorFormat vform, 2064 LogicVRegister dst, 2065 const LogicVRegister& src1, 2066 const LogicVRegister& src2, 2067 int index); 2068 LogicVRegister sqdmull(VectorFormat vform, 2069 LogicVRegister dst, 2070 const LogicVRegister& src1, 2071 const LogicVRegister& src2, 2072 int index); 2073 LogicVRegister sqdmull2(VectorFormat vform, 2074 LogicVRegister dst, 2075 const LogicVRegister& src1, 2076 const LogicVRegister& src2, 2077 int index); 2078 LogicVRegister sqdmlal(VectorFormat vform, 2079 LogicVRegister dst, 2080 const LogicVRegister& src1, 2081 const LogicVRegister& src2, 2082 int index); 2083 LogicVRegister sqdmlal2(VectorFormat vform, 2084 LogicVRegister dst, 2085 const LogicVRegister& src1, 2086 const LogicVRegister& src2, 2087 int index); 2088 LogicVRegister sqdmlsl(VectorFormat vform, 2089 LogicVRegister dst, 2090 const LogicVRegister& src1, 2091 const LogicVRegister& src2, 2092 int index); 2093 LogicVRegister sqdmlsl2(VectorFormat vform, 2094 LogicVRegister dst, 2095 const LogicVRegister& src1, 2096 const LogicVRegister& src2, 2097 int index); 2098 LogicVRegister sqdmulh(VectorFormat vform, 2099 LogicVRegister dst, 2100 const LogicVRegister& src1, 2101 const LogicVRegister& src2, 2102 int index); 2103 LogicVRegister sqrdmulh(VectorFormat vform, 2104 LogicVRegister dst, 2105 const LogicVRegister& src1, 2106 const LogicVRegister& src2, 2107 int index); 2108 LogicVRegister sub(VectorFormat vform, 2109 LogicVRegister dst, 2110 const LogicVRegister& src1, 2111 const LogicVRegister& src2); 2112 LogicVRegister and_(VectorFormat vform, 2113 LogicVRegister dst, 2114 const LogicVRegister& src1, 2115 const LogicVRegister& src2); 2116 LogicVRegister orr(VectorFormat vform, 2117 LogicVRegister dst, 2118 const LogicVRegister& src1, 2119 const LogicVRegister& src2); 2120 LogicVRegister orn(VectorFormat vform, 2121 LogicVRegister dst, 2122 const LogicVRegister& src1, 2123 const LogicVRegister& src2); 2124 LogicVRegister eor(VectorFormat vform, 2125 LogicVRegister dst, 2126 const LogicVRegister& src1, 2127 const LogicVRegister& src2); 2128 LogicVRegister bic(VectorFormat vform, 2129 LogicVRegister dst, 2130 const LogicVRegister& src1, 2131 const LogicVRegister& src2); 2132 LogicVRegister bic(VectorFormat vform, 2133 LogicVRegister dst, 2134 const LogicVRegister& src, 2135 uint64_t imm); 2136 LogicVRegister bif(VectorFormat vform, 2137 LogicVRegister dst, 2138 const LogicVRegister& src1, 2139 const LogicVRegister& src2); 2140 LogicVRegister bit(VectorFormat vform, 2141 LogicVRegister dst, 2142 const LogicVRegister& src1, 2143 const LogicVRegister& src2); 2144 LogicVRegister bsl(VectorFormat vform, 2145 LogicVRegister dst, 2146 const LogicVRegister& src1, 2147 const LogicVRegister& src2); 2148 LogicVRegister cls(VectorFormat vform, 2149 LogicVRegister dst, 2150 const LogicVRegister& src); 2151 LogicVRegister clz(VectorFormat vform, 2152 LogicVRegister dst, 2153 const LogicVRegister& src); 2154 LogicVRegister cnt(VectorFormat vform, 2155 LogicVRegister dst, 2156 const LogicVRegister& src); 2157 LogicVRegister not_(VectorFormat vform, 2158 LogicVRegister dst, 2159 const LogicVRegister& src); 2160 LogicVRegister rbit(VectorFormat vform, 2161 LogicVRegister dst, 2162 const LogicVRegister& src); 2163 LogicVRegister rev(VectorFormat vform, 2164 LogicVRegister dst, 2165 const LogicVRegister& src, 2166 int revSize); 2167 LogicVRegister rev16(VectorFormat vform, 2168 LogicVRegister dst, 2169 const LogicVRegister& src); 2170 LogicVRegister rev32(VectorFormat vform, 2171 LogicVRegister dst, 2172 const LogicVRegister& src); 2173 LogicVRegister rev64(VectorFormat vform, 2174 LogicVRegister dst, 2175 const LogicVRegister& src); 2176 LogicVRegister addlp(VectorFormat vform, 2177 LogicVRegister dst, 2178 const LogicVRegister& src, 2179 bool is_signed, 2180 bool do_accumulate); 2181 LogicVRegister saddlp(VectorFormat vform, 2182 LogicVRegister dst, 2183 const LogicVRegister& src); 2184 LogicVRegister uaddlp(VectorFormat vform, 2185 LogicVRegister dst, 2186 const LogicVRegister& src); 2187 LogicVRegister sadalp(VectorFormat vform, 2188 LogicVRegister dst, 2189 const LogicVRegister& src); 2190 LogicVRegister uadalp(VectorFormat vform, 2191 LogicVRegister dst, 2192 const LogicVRegister& src); 2193 LogicVRegister ext(VectorFormat vform, 2194 LogicVRegister dst, 2195 const LogicVRegister& src1, 2196 const LogicVRegister& src2, 2197 int index); 2198 LogicVRegister ins_element(VectorFormat vform, 2199 LogicVRegister dst, 2200 int dst_index, 2201 const LogicVRegister& src, 2202 int src_index); 2203 LogicVRegister ins_immediate(VectorFormat vform, 2204 LogicVRegister dst, 2205 int dst_index, 2206 uint64_t imm); 2207 LogicVRegister dup_element(VectorFormat vform, 2208 LogicVRegister dst, 2209 const LogicVRegister& src, 2210 int src_index); 2211 LogicVRegister dup_immediate(VectorFormat vform, 2212 LogicVRegister dst, 2213 uint64_t imm); 2214 LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2215 LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2216 LogicVRegister orr(VectorFormat vform, 2217 LogicVRegister dst, 2218 const LogicVRegister& src, 2219 uint64_t imm); 2220 LogicVRegister sshl(VectorFormat vform, 2221 LogicVRegister dst, 2222 const LogicVRegister& src1, 2223 const LogicVRegister& src2); 2224 LogicVRegister ushl(VectorFormat vform, 2225 LogicVRegister dst, 2226 const LogicVRegister& src1, 2227 const LogicVRegister& src2); 2228 LogicVRegister sminmax(VectorFormat vform, 2229 LogicVRegister dst, 2230 const LogicVRegister& src1, 2231 const LogicVRegister& src2, 2232 bool max); 2233 LogicVRegister smax(VectorFormat vform, 2234 LogicVRegister dst, 2235 const LogicVRegister& src1, 2236 const LogicVRegister& src2); 2237 LogicVRegister smin(VectorFormat vform, 2238 LogicVRegister dst, 2239 const LogicVRegister& src1, 2240 const LogicVRegister& src2); 2241 LogicVRegister sminmaxp(VectorFormat vform, 2242 LogicVRegister dst, 2243 const LogicVRegister& src1, 2244 const LogicVRegister& src2, 2245 bool max); 2246 LogicVRegister smaxp(VectorFormat vform, 2247 LogicVRegister dst, 2248 const LogicVRegister& src1, 2249 const LogicVRegister& src2); 2250 LogicVRegister sminp(VectorFormat vform, 2251 LogicVRegister dst, 2252 const LogicVRegister& src1, 2253 const LogicVRegister& src2); 2254 LogicVRegister addp(VectorFormat vform, 2255 LogicVRegister dst, 2256 const LogicVRegister& src); 2257 LogicVRegister addv(VectorFormat vform, 2258 LogicVRegister dst, 2259 const LogicVRegister& src); 2260 LogicVRegister uaddlv(VectorFormat vform, 2261 LogicVRegister dst, 2262 const LogicVRegister& src); 2263 LogicVRegister saddlv(VectorFormat vform, 2264 LogicVRegister dst, 2265 const LogicVRegister& src); 2266 LogicVRegister sminmaxv(VectorFormat vform, 2267 LogicVRegister dst, 2268 const LogicVRegister& src, 2269 bool max); 2270 LogicVRegister smaxv(VectorFormat vform, 2271 LogicVRegister dst, 2272 const LogicVRegister& src); 2273 LogicVRegister sminv(VectorFormat vform, 2274 LogicVRegister dst, 2275 const LogicVRegister& src); 2276 LogicVRegister uxtl(VectorFormat vform, 2277 LogicVRegister dst, 2278 const LogicVRegister& src); 2279 LogicVRegister uxtl2(VectorFormat vform, 2280 LogicVRegister dst, 2281 const LogicVRegister& src); 2282 LogicVRegister sxtl(VectorFormat vform, 2283 LogicVRegister dst, 2284 const LogicVRegister& src); 2285 LogicVRegister sxtl2(VectorFormat vform, 2286 LogicVRegister dst, 2287 const LogicVRegister& src); 2288 LogicVRegister tbl(VectorFormat vform, 2289 LogicVRegister dst, 2290 const LogicVRegister& tab, 2291 const LogicVRegister& ind); 2292 LogicVRegister tbl(VectorFormat vform, 2293 LogicVRegister dst, 2294 const LogicVRegister& tab, 2295 const LogicVRegister& tab2, 2296 const LogicVRegister& ind); 2297 LogicVRegister tbl(VectorFormat vform, 2298 LogicVRegister dst, 2299 const LogicVRegister& tab, 2300 const LogicVRegister& tab2, 2301 const LogicVRegister& tab3, 2302 const LogicVRegister& ind); 2303 LogicVRegister tbl(VectorFormat vform, 2304 LogicVRegister dst, 2305 const LogicVRegister& tab, 2306 const LogicVRegister& tab2, 2307 const LogicVRegister& tab3, 2308 const LogicVRegister& tab4, 2309 const LogicVRegister& ind); 2310 LogicVRegister Table(VectorFormat vform, 2311 LogicVRegister dst, 2312 const LogicVRegister& ind, 2313 bool zero_out_of_bounds, 2314 const LogicVRegister* tab1, 2315 const LogicVRegister* tab2 = NULL, 2316 const LogicVRegister* tab3 = NULL, 2317 const LogicVRegister* tab4 = NULL); 2318 LogicVRegister tbx(VectorFormat vform, 2319 LogicVRegister dst, 2320 const LogicVRegister& tab, 2321 const LogicVRegister& ind); 2322 LogicVRegister tbx(VectorFormat vform, 2323 LogicVRegister dst, 2324 const LogicVRegister& tab, 2325 const LogicVRegister& tab2, 2326 const LogicVRegister& ind); 2327 LogicVRegister tbx(VectorFormat vform, 2328 LogicVRegister dst, 2329 const LogicVRegister& tab, 2330 const LogicVRegister& tab2, 2331 const LogicVRegister& tab3, 2332 const LogicVRegister& ind); 2333 LogicVRegister tbx(VectorFormat vform, 2334 LogicVRegister dst, 2335 const LogicVRegister& tab, 2336 const LogicVRegister& tab2, 2337 const LogicVRegister& tab3, 2338 const LogicVRegister& tab4, 2339 const LogicVRegister& ind); 2340 LogicVRegister uaddl(VectorFormat vform, 2341 LogicVRegister dst, 2342 const LogicVRegister& src1, 2343 const LogicVRegister& src2); 2344 LogicVRegister uaddl2(VectorFormat vform, 2345 LogicVRegister dst, 2346 const LogicVRegister& src1, 2347 const LogicVRegister& src2); 2348 LogicVRegister uaddw(VectorFormat vform, 2349 LogicVRegister dst, 2350 const LogicVRegister& src1, 2351 const LogicVRegister& src2); 2352 LogicVRegister uaddw2(VectorFormat vform, 2353 LogicVRegister dst, 2354 const LogicVRegister& src1, 2355 const LogicVRegister& src2); 2356 LogicVRegister saddl(VectorFormat vform, 2357 LogicVRegister dst, 2358 const LogicVRegister& src1, 2359 const LogicVRegister& src2); 2360 LogicVRegister saddl2(VectorFormat vform, 2361 LogicVRegister dst, 2362 const LogicVRegister& src1, 2363 const LogicVRegister& src2); 2364 LogicVRegister saddw(VectorFormat vform, 2365 LogicVRegister dst, 2366 const LogicVRegister& src1, 2367 const LogicVRegister& src2); 2368 LogicVRegister saddw2(VectorFormat vform, 2369 LogicVRegister dst, 2370 const LogicVRegister& src1, 2371 const LogicVRegister& src2); 2372 LogicVRegister usubl(VectorFormat vform, 2373 LogicVRegister dst, 2374 const LogicVRegister& src1, 2375 const LogicVRegister& src2); 2376 LogicVRegister usubl2(VectorFormat vform, 2377 LogicVRegister dst, 2378 const LogicVRegister& src1, 2379 const LogicVRegister& src2); 2380 LogicVRegister usubw(VectorFormat vform, 2381 LogicVRegister dst, 2382 const LogicVRegister& src1, 2383 const LogicVRegister& src2); 2384 LogicVRegister usubw2(VectorFormat vform, 2385 LogicVRegister dst, 2386 const LogicVRegister& src1, 2387 const LogicVRegister& src2); 2388 LogicVRegister ssubl(VectorFormat vform, 2389 LogicVRegister dst, 2390 const LogicVRegister& src1, 2391 const LogicVRegister& src2); 2392 LogicVRegister ssubl2(VectorFormat vform, 2393 LogicVRegister dst, 2394 const LogicVRegister& src1, 2395 const LogicVRegister& src2); 2396 LogicVRegister ssubw(VectorFormat vform, 2397 LogicVRegister dst, 2398 const LogicVRegister& src1, 2399 const LogicVRegister& src2); 2400 LogicVRegister ssubw2(VectorFormat vform, 2401 LogicVRegister dst, 2402 const LogicVRegister& src1, 2403 const LogicVRegister& src2); 2404 LogicVRegister uminmax(VectorFormat vform, 2405 LogicVRegister dst, 2406 const LogicVRegister& src1, 2407 const LogicVRegister& src2, 2408 bool max); 2409 LogicVRegister umax(VectorFormat vform, 2410 LogicVRegister dst, 2411 const LogicVRegister& src1, 2412 const LogicVRegister& src2); 2413 LogicVRegister umin(VectorFormat vform, 2414 LogicVRegister dst, 2415 const LogicVRegister& src1, 2416 const LogicVRegister& src2); 2417 LogicVRegister uminmaxp(VectorFormat vform, 2418 LogicVRegister dst, 2419 const LogicVRegister& src1, 2420 const LogicVRegister& src2, 2421 bool max); 2422 LogicVRegister umaxp(VectorFormat vform, 2423 LogicVRegister dst, 2424 const LogicVRegister& src1, 2425 const LogicVRegister& src2); 2426 LogicVRegister uminp(VectorFormat vform, 2427 LogicVRegister dst, 2428 const LogicVRegister& src1, 2429 const LogicVRegister& src2); 2430 LogicVRegister uminmaxv(VectorFormat vform, 2431 LogicVRegister dst, 2432 const LogicVRegister& src, 2433 bool max); 2434 LogicVRegister umaxv(VectorFormat vform, 2435 LogicVRegister dst, 2436 const LogicVRegister& src); 2437 LogicVRegister uminv(VectorFormat vform, 2438 LogicVRegister dst, 2439 const LogicVRegister& src); 2440 LogicVRegister trn1(VectorFormat vform, 2441 LogicVRegister dst, 2442 const LogicVRegister& src1, 2443 const LogicVRegister& src2); 2444 LogicVRegister trn2(VectorFormat vform, 2445 LogicVRegister dst, 2446 const LogicVRegister& src1, 2447 const LogicVRegister& src2); 2448 LogicVRegister zip1(VectorFormat vform, 2449 LogicVRegister dst, 2450 const LogicVRegister& src1, 2451 const LogicVRegister& src2); 2452 LogicVRegister zip2(VectorFormat vform, 2453 LogicVRegister dst, 2454 const LogicVRegister& src1, 2455 const LogicVRegister& src2); 2456 LogicVRegister uzp1(VectorFormat vform, 2457 LogicVRegister dst, 2458 const LogicVRegister& src1, 2459 const LogicVRegister& src2); 2460 LogicVRegister uzp2(VectorFormat vform, 2461 LogicVRegister dst, 2462 const LogicVRegister& src1, 2463 const LogicVRegister& src2); 2464 LogicVRegister shl(VectorFormat vform, 2465 LogicVRegister dst, 2466 const LogicVRegister& src, 2467 int shift); 2468 LogicVRegister scvtf(VectorFormat vform, 2469 LogicVRegister dst, 2470 const LogicVRegister& src, 2471 int fbits, 2472 FPRounding rounding_mode); 2473 LogicVRegister ucvtf(VectorFormat vform, 2474 LogicVRegister dst, 2475 const LogicVRegister& src, 2476 int fbits, 2477 FPRounding rounding_mode); 2478 LogicVRegister sshll(VectorFormat vform, 2479 LogicVRegister dst, 2480 const LogicVRegister& src, 2481 int shift); 2482 LogicVRegister sshll2(VectorFormat vform, 2483 LogicVRegister dst, 2484 const LogicVRegister& src, 2485 int shift); 2486 LogicVRegister shll(VectorFormat vform, 2487 LogicVRegister dst, 2488 const LogicVRegister& src); 2489 LogicVRegister shll2(VectorFormat vform, 2490 LogicVRegister dst, 2491 const LogicVRegister& src); 2492 LogicVRegister ushll(VectorFormat vform, 2493 LogicVRegister dst, 2494 const LogicVRegister& src, 2495 int shift); 2496 LogicVRegister ushll2(VectorFormat vform, 2497 LogicVRegister dst, 2498 const LogicVRegister& src, 2499 int shift); 2500 LogicVRegister sli(VectorFormat vform, 2501 LogicVRegister dst, 2502 const LogicVRegister& src, 2503 int shift); 2504 LogicVRegister sri(VectorFormat vform, 2505 LogicVRegister dst, 2506 const LogicVRegister& src, 2507 int shift); 2508 LogicVRegister sshr(VectorFormat vform, 2509 LogicVRegister dst, 2510 const LogicVRegister& src, 2511 int shift); 2512 LogicVRegister ushr(VectorFormat vform, 2513 LogicVRegister dst, 2514 const LogicVRegister& src, 2515 int shift); 2516 LogicVRegister ssra(VectorFormat vform, 2517 LogicVRegister dst, 2518 const LogicVRegister& src, 2519 int shift); 2520 LogicVRegister usra(VectorFormat vform, 2521 LogicVRegister dst, 2522 const LogicVRegister& src, 2523 int shift); 2524 LogicVRegister srsra(VectorFormat vform, 2525 LogicVRegister dst, 2526 const LogicVRegister& src, 2527 int shift); 2528 LogicVRegister ursra(VectorFormat vform, 2529 LogicVRegister dst, 2530 const LogicVRegister& src, 2531 int shift); 2532 LogicVRegister suqadd(VectorFormat vform, 2533 LogicVRegister dst, 2534 const LogicVRegister& src); 2535 LogicVRegister usqadd(VectorFormat vform, 2536 LogicVRegister dst, 2537 const LogicVRegister& src); 2538 LogicVRegister sqshl(VectorFormat vform, 2539 LogicVRegister dst, 2540 const LogicVRegister& src, 2541 int shift); 2542 LogicVRegister uqshl(VectorFormat vform, 2543 LogicVRegister dst, 2544 const LogicVRegister& src, 2545 int shift); 2546 LogicVRegister sqshlu(VectorFormat vform, 2547 LogicVRegister dst, 2548 const LogicVRegister& src, 2549 int shift); 2550 LogicVRegister abs(VectorFormat vform, 2551 LogicVRegister dst, 2552 const LogicVRegister& src); 2553 LogicVRegister neg(VectorFormat vform, 2554 LogicVRegister dst, 2555 const LogicVRegister& src); 2556 LogicVRegister extractnarrow(VectorFormat vform, 2557 LogicVRegister dst, 2558 bool dstIsSigned, 2559 const LogicVRegister& src, 2560 bool srcIsSigned); 2561 LogicVRegister xtn(VectorFormat vform, 2562 LogicVRegister dst, 2563 const LogicVRegister& src); 2564 LogicVRegister sqxtn(VectorFormat vform, 2565 LogicVRegister dst, 2566 const LogicVRegister& src); 2567 LogicVRegister uqxtn(VectorFormat vform, 2568 LogicVRegister dst, 2569 const LogicVRegister& src); 2570 LogicVRegister sqxtun(VectorFormat vform, 2571 LogicVRegister dst, 2572 const LogicVRegister& src); 2573 LogicVRegister absdiff(VectorFormat vform, 2574 LogicVRegister dst, 2575 const LogicVRegister& src1, 2576 const LogicVRegister& src2, 2577 bool issigned); 2578 LogicVRegister saba(VectorFormat vform, 2579 LogicVRegister dst, 2580 const LogicVRegister& src1, 2581 const LogicVRegister& src2); 2582 LogicVRegister uaba(VectorFormat vform, 2583 LogicVRegister dst, 2584 const LogicVRegister& src1, 2585 const LogicVRegister& src2); 2586 LogicVRegister shrn(VectorFormat vform, 2587 LogicVRegister dst, 2588 const LogicVRegister& src, 2589 int shift); 2590 LogicVRegister shrn2(VectorFormat vform, 2591 LogicVRegister dst, 2592 const LogicVRegister& src, 2593 int shift); 2594 LogicVRegister rshrn(VectorFormat vform, 2595 LogicVRegister dst, 2596 const LogicVRegister& src, 2597 int shift); 2598 LogicVRegister rshrn2(VectorFormat vform, 2599 LogicVRegister dst, 2600 const LogicVRegister& src, 2601 int shift); 2602 LogicVRegister uqshrn(VectorFormat vform, 2603 LogicVRegister dst, 2604 const LogicVRegister& src, 2605 int shift); 2606 LogicVRegister uqshrn2(VectorFormat vform, 2607 LogicVRegister dst, 2608 const LogicVRegister& src, 2609 int shift); 2610 LogicVRegister uqrshrn(VectorFormat vform, 2611 LogicVRegister dst, 2612 const LogicVRegister& src, 2613 int shift); 2614 LogicVRegister uqrshrn2(VectorFormat vform, 2615 LogicVRegister dst, 2616 const LogicVRegister& src, 2617 int shift); 2618 LogicVRegister sqshrn(VectorFormat vform, 2619 LogicVRegister dst, 2620 const LogicVRegister& src, 2621 int shift); 2622 LogicVRegister sqshrn2(VectorFormat vform, 2623 LogicVRegister dst, 2624 const LogicVRegister& src, 2625 int shift); 2626 LogicVRegister sqrshrn(VectorFormat vform, 2627 LogicVRegister dst, 2628 const LogicVRegister& src, 2629 int shift); 2630 LogicVRegister sqrshrn2(VectorFormat vform, 2631 LogicVRegister dst, 2632 const LogicVRegister& src, 2633 int shift); 2634 LogicVRegister sqshrun(VectorFormat vform, 2635 LogicVRegister dst, 2636 const LogicVRegister& src, 2637 int shift); 2638 LogicVRegister sqshrun2(VectorFormat vform, 2639 LogicVRegister dst, 2640 const LogicVRegister& src, 2641 int shift); 2642 LogicVRegister sqrshrun(VectorFormat vform, 2643 LogicVRegister dst, 2644 const LogicVRegister& src, 2645 int shift); 2646 LogicVRegister sqrshrun2(VectorFormat vform, 2647 LogicVRegister dst, 2648 const LogicVRegister& src, 2649 int shift); 2650 LogicVRegister sqrdmulh(VectorFormat vform, 2651 LogicVRegister dst, 2652 const LogicVRegister& src1, 2653 const LogicVRegister& src2, 2654 bool round = true); 2655 LogicVRegister sqdmulh(VectorFormat vform, 2656 LogicVRegister dst, 2657 const LogicVRegister& src1, 2658 const LogicVRegister& src2); 2659 #define NEON_3VREG_LOGIC_LIST(V) \ 2660 V(addhn) \ 2661 V(addhn2) \ 2662 V(raddhn) \ 2663 V(raddhn2) \ 2664 V(subhn) \ 2665 V(subhn2) \ 2666 V(rsubhn) \ 2667 V(rsubhn2) \ 2668 V(pmull) \ 2669 V(pmull2) \ 2670 V(sabal) \ 2671 V(sabal2) \ 2672 V(uabal) \ 2673 V(uabal2) \ 2674 V(sabdl) \ 2675 V(sabdl2) \ 2676 V(uabdl) \ 2677 V(uabdl2) \ 2678 V(smull) \ 2679 V(smull2) \ 2680 V(umull) \ 2681 V(umull2) \ 2682 V(smlal) \ 2683 V(smlal2) \ 2684 V(umlal) \ 2685 V(umlal2) \ 2686 V(smlsl) \ 2687 V(smlsl2) \ 2688 V(umlsl) \ 2689 V(umlsl2) \ 2690 V(sqdmlal) \ 2691 V(sqdmlal2) \ 2692 V(sqdmlsl) \ 2693 V(sqdmlsl2) \ 2694 V(sqdmull) \ 2695 V(sqdmull2) 2696 2697 #define DEFINE_LOGIC_FUNC(FXN) \ 2698 LogicVRegister FXN(VectorFormat vform, \ 2699 LogicVRegister dst, \ 2700 const LogicVRegister& src1, \ 2701 const LogicVRegister& src2); 2702 NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC) 2703 #undef DEFINE_LOGIC_FUNC 2704 2705 #define NEON_FP3SAME_LIST(V) \ 2706 V(fadd, FPAdd, false) \ 2707 V(fsub, FPSub, true) \ 2708 V(fmul, FPMul, true) \ 2709 V(fmulx, FPMulx, true) \ 2710 V(fdiv, FPDiv, true) \ 2711 V(fmax, FPMax, false) \ 2712 V(fmin, FPMin, false) \ 2713 V(fmaxnm, FPMaxNM, false) \ 2714 V(fminnm, FPMinNM, false) 2715 2716 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \ 2717 template <typename T> \ 2718 LogicVRegister FN(VectorFormat vform, \ 2719 LogicVRegister dst, \ 2720 const LogicVRegister& src1, \ 2721 const LogicVRegister& src2); \ 2722 LogicVRegister FN(VectorFormat vform, \ 2723 LogicVRegister dst, \ 2724 const LogicVRegister& src1, \ 2725 const LogicVRegister& src2); 2726 NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP) 2727 #undef DECLARE_NEON_FP_VECTOR_OP 2728 2729 #define NEON_FPPAIRWISE_LIST(V) \ 2730 V(faddp, fadd, FPAdd) \ 2731 V(fmaxp, fmax, FPMax) \ 2732 V(fmaxnmp, fmaxnm, FPMaxNM) \ 2733 V(fminp, fmin, FPMin) \ 2734 V(fminnmp, fminnm, FPMinNM) 2735 2736 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP) \ 2737 LogicVRegister FNP(VectorFormat vform, \ 2738 LogicVRegister dst, \ 2739 const LogicVRegister& src1, \ 2740 const LogicVRegister& src2); \ 2741 LogicVRegister FNP(VectorFormat vform, \ 2742 LogicVRegister dst, \ 2743 const LogicVRegister& src); 2744 NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP) 2745 #undef DECLARE_NEON_FP_PAIR_OP 2746 2747 template <typename T> 2748 LogicVRegister frecps(VectorFormat vform, 2749 LogicVRegister dst, 2750 const LogicVRegister& src1, 2751 const LogicVRegister& src2); 2752 LogicVRegister frecps(VectorFormat vform, 2753 LogicVRegister dst, 2754 const LogicVRegister& src1, 2755 const LogicVRegister& src2); 2756 template <typename T> 2757 LogicVRegister frsqrts(VectorFormat vform, 2758 LogicVRegister dst, 2759 const LogicVRegister& src1, 2760 const LogicVRegister& src2); 2761 LogicVRegister frsqrts(VectorFormat vform, 2762 LogicVRegister dst, 2763 const LogicVRegister& src1, 2764 const LogicVRegister& src2); 2765 template <typename T> 2766 LogicVRegister fmla(VectorFormat vform, 2767 LogicVRegister dst, 2768 const LogicVRegister& src1, 2769 const LogicVRegister& src2); 2770 LogicVRegister fmla(VectorFormat vform, 2771 LogicVRegister dst, 2772 const LogicVRegister& src1, 2773 const LogicVRegister& src2); 2774 template <typename T> 2775 LogicVRegister fmls(VectorFormat vform, 2776 LogicVRegister dst, 2777 const LogicVRegister& src1, 2778 const LogicVRegister& src2); 2779 LogicVRegister fmls(VectorFormat vform, 2780 LogicVRegister dst, 2781 const LogicVRegister& src1, 2782 const LogicVRegister& src2); 2783 LogicVRegister fnmul(VectorFormat vform, 2784 LogicVRegister dst, 2785 const LogicVRegister& src1, 2786 const LogicVRegister& src2); 2787 2788 template <typename T> 2789 LogicVRegister fcmp(VectorFormat vform, 2790 LogicVRegister dst, 2791 const LogicVRegister& src1, 2792 const LogicVRegister& src2, 2793 Condition cond); 2794 LogicVRegister fcmp(VectorFormat vform, 2795 LogicVRegister dst, 2796 const LogicVRegister& src1, 2797 const LogicVRegister& src2, 2798 Condition cond); 2799 LogicVRegister fabscmp(VectorFormat vform, 2800 LogicVRegister dst, 2801 const LogicVRegister& src1, 2802 const LogicVRegister& src2, 2803 Condition cond); 2804 LogicVRegister fcmp_zero(VectorFormat vform, 2805 LogicVRegister dst, 2806 const LogicVRegister& src, 2807 Condition cond); 2808 2809 template <typename T> 2810 LogicVRegister fneg(VectorFormat vform, 2811 LogicVRegister dst, 2812 const LogicVRegister& src); 2813 LogicVRegister fneg(VectorFormat vform, 2814 LogicVRegister dst, 2815 const LogicVRegister& src); 2816 template <typename T> 2817 LogicVRegister frecpx(VectorFormat vform, 2818 LogicVRegister dst, 2819 const LogicVRegister& src); 2820 LogicVRegister frecpx(VectorFormat vform, 2821 LogicVRegister dst, 2822 const LogicVRegister& src); 2823 template <typename T> 2824 LogicVRegister fabs_(VectorFormat vform, 2825 LogicVRegister dst, 2826 const LogicVRegister& src); 2827 LogicVRegister fabs_(VectorFormat vform, 2828 LogicVRegister dst, 2829 const LogicVRegister& src); 2830 LogicVRegister fabd(VectorFormat vform, 2831 LogicVRegister dst, 2832 const LogicVRegister& src1, 2833 const LogicVRegister& src2); 2834 LogicVRegister frint(VectorFormat vform, 2835 LogicVRegister dst, 2836 const LogicVRegister& src, 2837 FPRounding rounding_mode, 2838 bool inexact_exception = false); 2839 LogicVRegister fcvts(VectorFormat vform, 2840 LogicVRegister dst, 2841 const LogicVRegister& src, 2842 FPRounding rounding_mode, 2843 int fbits = 0); 2844 LogicVRegister fcvtu(VectorFormat vform, 2845 LogicVRegister dst, 2846 const LogicVRegister& src, 2847 FPRounding rounding_mode, 2848 int fbits = 0); 2849 LogicVRegister fcvtl(VectorFormat vform, 2850 LogicVRegister dst, 2851 const LogicVRegister& src); 2852 LogicVRegister fcvtl2(VectorFormat vform, 2853 LogicVRegister dst, 2854 const LogicVRegister& src); 2855 LogicVRegister fcvtn(VectorFormat vform, 2856 LogicVRegister dst, 2857 const LogicVRegister& src); 2858 LogicVRegister fcvtn2(VectorFormat vform, 2859 LogicVRegister dst, 2860 const LogicVRegister& src); 2861 LogicVRegister fcvtxn(VectorFormat vform, 2862 LogicVRegister dst, 2863 const LogicVRegister& src); 2864 LogicVRegister fcvtxn2(VectorFormat vform, 2865 LogicVRegister dst, 2866 const LogicVRegister& src); 2867 LogicVRegister fsqrt(VectorFormat vform, 2868 LogicVRegister dst, 2869 const LogicVRegister& src); 2870 LogicVRegister frsqrte(VectorFormat vform, 2871 LogicVRegister dst, 2872 const LogicVRegister& src); 2873 LogicVRegister frecpe(VectorFormat vform, 2874 LogicVRegister dst, 2875 const LogicVRegister& src, 2876 FPRounding rounding); 2877 LogicVRegister ursqrte(VectorFormat vform, 2878 LogicVRegister dst, 2879 const LogicVRegister& src); 2880 LogicVRegister urecpe(VectorFormat vform, 2881 LogicVRegister dst, 2882 const LogicVRegister& src); 2883 2884 typedef float (Simulator::*FPMinMaxOp)(float a, float b); 2885 2886 LogicVRegister fminmaxv(VectorFormat vform, 2887 LogicVRegister dst, 2888 const LogicVRegister& src, 2889 FPMinMaxOp Op); 2890 2891 LogicVRegister fminv(VectorFormat vform, 2892 LogicVRegister dst, 2893 const LogicVRegister& src); 2894 LogicVRegister fmaxv(VectorFormat vform, 2895 LogicVRegister dst, 2896 const LogicVRegister& src); 2897 LogicVRegister fminnmv(VectorFormat vform, 2898 LogicVRegister dst, 2899 const LogicVRegister& src); 2900 LogicVRegister fmaxnmv(VectorFormat vform, 2901 LogicVRegister dst, 2902 const LogicVRegister& src); 2903 2904 static const uint32_t CRC32_POLY = 0x04C11DB7; 2905 static const uint32_t CRC32C_POLY = 0x1EDC6F41; 2906 uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly); 2907 template <typename T> 2908 uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly); 2909 uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly); 2910 2911 void SysOp_W(int op, int64_t val); 2912 2913 template <typename T> 2914 T FPRecipSqrtEstimate(T op); 2915 template <typename T> 2916 T FPRecipEstimate(T op, FPRounding rounding); 2917 template <typename T, typename R> 2918 R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding); 2919 2920 void FPCompare(double val0, double val1, FPTrapFlags trap); 2921 double FPRoundInt(double value, FPRounding round_mode); 2922 double FPToDouble(float value); 2923 float FPToFloat(double value, FPRounding round_mode); 2924 float FPToFloat(float16 value); 2925 float16 FPToFloat16(float value, FPRounding round_mode); 2926 float16 FPToFloat16(double value, FPRounding round_mode); 2927 double recip_sqrt_estimate(double a); 2928 double recip_estimate(double a); 2929 double FPRecipSqrtEstimate(double a); 2930 double FPRecipEstimate(double a); 2931 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); 2932 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); 2933 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); 2934 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); 2935 int32_t FPToInt32(double value, FPRounding rmode); 2936 int64_t FPToInt64(double value, FPRounding rmode); 2937 uint32_t FPToUInt32(double value, FPRounding rmode); 2938 uint64_t FPToUInt64(double value, FPRounding rmode); 2939 2940 template <typename T> 2941 T FPAdd(T op1, T op2); 2942 2943 template <typename T> 2944 T FPDiv(T op1, T op2); 2945 2946 template <typename T> 2947 T FPMax(T a, T b); 2948 2949 template <typename T> 2950 T FPMaxNM(T a, T b); 2951 2952 template <typename T> 2953 T FPMin(T a, T b); 2954 2955 template <typename T> 2956 T FPMinNM(T a, T b); 2957 2958 template <typename T> 2959 T FPMul(T op1, T op2); 2960 2961 template <typename T> 2962 T FPMulx(T op1, T op2); 2963 2964 template <typename T> 2965 T FPMulAdd(T a, T op1, T op2); 2966 2967 template <typename T> 2968 T FPSqrt(T op); 2969 2970 template <typename T> 2971 T FPSub(T op1, T op2); 2972 2973 template <typename T> 2974 T FPRecipStepFused(T op1, T op2); 2975 2976 template <typename T> 2977 T FPRSqrtStepFused(T op1, T op2); 2978 2979 // This doesn't do anything at the moment. We'll need it if we want support 2980 // for cumulative exception bits or floating-point exceptions. 2981 void FPProcessException() {} 2982 2983 bool FPProcessNaNs(const Instruction* instr); 2984 2985 // Pseudo Printf instruction 2986 void DoPrintf(const Instruction* instr); 2987 2988 // Simulate a runtime call. 2989 #ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 2990 VIXL_NO_RETURN_IN_DEBUG_MODE 2991 #endif 2992 void DoRuntimeCall(const Instruction* instr); 2993 2994 // Processor state --------------------------------------- 2995 2996 // Simulated monitors for exclusive access instructions. 2997 SimExclusiveLocalMonitor local_monitor_; 2998 SimExclusiveGlobalMonitor global_monitor_; 2999 3000 // Output stream. 3001 FILE* stream_; 3002 PrintDisassembler* print_disasm_; 3003 3004 // Instruction statistics instrumentation. 3005 Instrument* instrumentation_; 3006 3007 // General purpose registers. Register 31 is the stack pointer. 3008 SimRegister registers_[kNumberOfRegisters]; 3009 3010 // Vector registers 3011 SimVRegister vregisters_[kNumberOfVRegisters]; 3012 3013 // Program Status Register. 3014 // bits[31, 27]: Condition flags N, Z, C, and V. 3015 // (Negative, Zero, Carry, Overflow) 3016 SimSystemRegister nzcv_; 3017 3018 // Floating-Point Control Register 3019 SimSystemRegister fpcr_; 3020 3021 // Only a subset of FPCR features are supported by the simulator. This helper 3022 // checks that the FPCR settings are supported. 3023 // 3024 // This is checked when floating-point instructions are executed, not when 3025 // FPCR is set. This allows generated code to modify FPCR for external 3026 // functions, or to save and restore it when entering and leaving generated 3027 // code. 3028 void AssertSupportedFPCR() { 3029 // No flush-to-zero support. 3030 VIXL_ASSERT(ReadFpcr().GetFZ() == 0); 3031 // Ties-to-even rounding only. 3032 VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven); 3033 3034 // The simulator does not support half-precision operations so 3035 // GetFpcr().AHP() is irrelevant, and is not checked here. 3036 } 3037 3038 static int CalcNFlag(uint64_t result, unsigned reg_size) { 3039 return (result >> (reg_size - 1)) & 1; 3040 } 3041 3042 static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; } 3043 3044 static const uint32_t kConditionFlagsMask = 0xf0000000; 3045 3046 // Stack 3047 byte* stack_; 3048 static const int stack_protection_size_ = 256; 3049 // 2 KB stack. 3050 static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_; 3051 byte* stack_limit_; 3052 3053 Decoder* decoder_; 3054 // Indicates if the pc has been modified by the instruction and should not be 3055 // automatically incremented. 3056 bool pc_modified_; 3057 const Instruction* pc_; 3058 3059 static const char* xreg_names[]; 3060 static const char* wreg_names[]; 3061 static const char* sreg_names[]; 3062 static const char* dreg_names[]; 3063 static const char* vreg_names[]; 3064 3065 private: 3066 template <typename T> 3067 static T FPDefaultNaN(); 3068 3069 // Standard NaN processing. 3070 template <typename T> 3071 T FPProcessNaN(T op) { 3072 VIXL_ASSERT(std::isnan(op)); 3073 if (IsSignallingNaN(op)) { 3074 FPProcessException(); 3075 } 3076 return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 3077 } 3078 3079 template <typename T> 3080 T FPProcessNaNs(T op1, T op2) { 3081 if (IsSignallingNaN(op1)) { 3082 return FPProcessNaN(op1); 3083 } else if (IsSignallingNaN(op2)) { 3084 return FPProcessNaN(op2); 3085 } else if (std::isnan(op1)) { 3086 VIXL_ASSERT(IsQuietNaN(op1)); 3087 return FPProcessNaN(op1); 3088 } else if (std::isnan(op2)) { 3089 VIXL_ASSERT(IsQuietNaN(op2)); 3090 return FPProcessNaN(op2); 3091 } else { 3092 return 0.0; 3093 } 3094 } 3095 3096 template <typename T> 3097 T FPProcessNaNs3(T op1, T op2, T op3) { 3098 if (IsSignallingNaN(op1)) { 3099 return FPProcessNaN(op1); 3100 } else if (IsSignallingNaN(op2)) { 3101 return FPProcessNaN(op2); 3102 } else if (IsSignallingNaN(op3)) { 3103 return FPProcessNaN(op3); 3104 } else if (std::isnan(op1)) { 3105 VIXL_ASSERT(IsQuietNaN(op1)); 3106 return FPProcessNaN(op1); 3107 } else if (std::isnan(op2)) { 3108 VIXL_ASSERT(IsQuietNaN(op2)); 3109 return FPProcessNaN(op2); 3110 } else if (std::isnan(op3)) { 3111 VIXL_ASSERT(IsQuietNaN(op3)); 3112 return FPProcessNaN(op3); 3113 } else { 3114 return 0.0; 3115 } 3116 } 3117 3118 bool coloured_trace_; 3119 3120 // A set of TraceParameters flags. 3121 int trace_parameters_; 3122 3123 // Indicates whether the instruction instrumentation is active. 3124 bool instruction_stats_; 3125 3126 // Indicates whether the exclusive-access warning has been printed. 3127 bool print_exclusive_access_warning_; 3128 void PrintExclusiveAccessWarning(); 3129 }; 3130 3131 #if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L 3132 // Base case of the recursive template used to emulate C++14 3133 // `std::index_sequence`. 3134 template <size_t... I> 3135 struct Simulator::emulated_make_index_sequence_helper<0, I...> 3136 : Simulator::emulated_index_sequence<I...> {}; 3137 #endif 3138 3139 } // namespace aarch64 3140 } // namespace vixl 3141 3142 #endif // VIXL_INCLUDE_SIMULATOR_AARCH64 3143 3144 #endif // VIXL_AARCH64_SIMULATOR_AARCH64_H_ 3145