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