simulator-aarch64.h revision 868bfc49d722d6a233390ec847fa1407820a1eab
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_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#if defined(VIXL_ABI_SUPPORT) && __cplusplus >= 201103L 1622 1623#define VIXL_SIMULATED_RUNTIME_CALL_SUPPORT 1624 1625// The implementation of the runtime call helpers require the functionality 1626// provided by `std::index_sequence`. It is only available from C++14, but 1627// we want runtime call simulation to work from C++11, so we emulate if 1628// necessary. 1629#if __cplusplus >= 201402L 1630 template <std::size_t... I> 1631 using local_index_sequence = std::index_sequence<I...>; 1632 template <typename... P> 1633 using __local_index_sequence_for = std::index_sequence_for<P...>; 1634#else 1635 // Emulate the behaviour of `std::index_sequence` and 1636 // `std::index_sequence_for`. 1637 // Naming follow the `std` names, prefixed with `emulated_`. 1638 template <size_t... I> 1639 struct emulated_index_sequence {}; 1640 1641 // A recursive template to create a sequence of indexes. 1642 // The base case (for `N == 0`) is declared outside of the class scope, as 1643 // required by C++. 1644 template <std::size_t N, size_t... I> 1645 struct emulated_make_index_sequence_helper 1646 : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {}; 1647 1648 template <std::size_t N> 1649 struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> { 1650 }; 1651 1652 template <typename... P> 1653 struct emulated_index_sequence_for 1654 : emulated_make_index_sequence<sizeof...(P)> {}; 1655 1656 template <std::size_t... I> 1657 using local_index_sequence = emulated_index_sequence<I...>; 1658 template <typename... P> 1659 using __local_index_sequence_for = emulated_index_sequence_for<P...>; 1660#endif 1661 1662 // Expand the argument tuple and perform the call. 1663 template <typename R, typename... P, std::size_t... I> 1664 R DoRuntimeCall(R (*function)(P...), 1665 std::tuple<P...> arguments, 1666 local_index_sequence<I...>) { 1667 return function(std::get<I>(arguments)...); 1668 } 1669 1670 template <typename R, typename... P> 1671 void RuntimeCallNonVoid(R (*function)(P...)) { 1672 ABI abi; 1673 std::tuple<P...> argument_operands{ 1674 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1675 R return_value = DoRuntimeCall(function, 1676 argument_operands, 1677 __local_index_sequence_for<P...>{}); 1678 WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value); 1679 } 1680 1681 template <typename R, typename... P> 1682 void RuntimeCallVoid(R (*function)(P...)) { 1683 ABI abi; 1684 std::tuple<P...> argument_operands{ 1685 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1686 DoRuntimeCall(function, 1687 argument_operands, 1688 __local_index_sequence_for<P...>{}); 1689 } 1690 1691 // We use `struct` for `void` return type specialisation. 1692 template <typename R, typename... P> 1693 struct RuntimeCallStructHelper { 1694 static void Wrapper(Simulator* simulator, void* function_pointer) { 1695 R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer); 1696 simulator->RuntimeCallNonVoid(function); 1697 } 1698 }; 1699 1700 // Partial specialization when the return type is `void`. 1701 template <typename... P> 1702 struct RuntimeCallStructHelper<void, P...> { 1703 static void Wrapper(Simulator* simulator, void* function_pointer) { 1704 void (*function)(P...) = 1705 reinterpret_cast<void (*)(P...)>(function_pointer); 1706 simulator->RuntimeCallVoid(function); 1707 } 1708 }; 1709#endif 1710 1711 protected: 1712 const char* clr_normal; 1713 const char* clr_flag_name; 1714 const char* clr_flag_value; 1715 const char* clr_reg_name; 1716 const char* clr_reg_value; 1717 const char* clr_vreg_name; 1718 const char* clr_vreg_value; 1719 const char* clr_memory_address; 1720 const char* clr_warning; 1721 const char* clr_warning_message; 1722 const char* clr_printf; 1723 1724 // Simulation helpers ------------------------------------ 1725 bool ConditionPassed(Condition cond) { 1726 switch (cond) { 1727 case eq: 1728 return ReadZ(); 1729 case ne: 1730 return !ReadZ(); 1731 case hs: 1732 return ReadC(); 1733 case lo: 1734 return !ReadC(); 1735 case mi: 1736 return ReadN(); 1737 case pl: 1738 return !ReadN(); 1739 case vs: 1740 return ReadV(); 1741 case vc: 1742 return !ReadV(); 1743 case hi: 1744 return ReadC() && !ReadZ(); 1745 case ls: 1746 return !(ReadC() && !ReadZ()); 1747 case ge: 1748 return ReadN() == ReadV(); 1749 case lt: 1750 return ReadN() != ReadV(); 1751 case gt: 1752 return !ReadZ() && (ReadN() == ReadV()); 1753 case le: 1754 return !(!ReadZ() && (ReadN() == ReadV())); 1755 case nv: 1756 VIXL_FALLTHROUGH(); 1757 case al: 1758 return true; 1759 default: 1760 VIXL_UNREACHABLE(); 1761 return false; 1762 } 1763 } 1764 1765 bool ConditionPassed(Instr cond) { 1766 return ConditionPassed(static_cast<Condition>(cond)); 1767 } 1768 1769 bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); } 1770 1771 void AddSubHelper(const Instruction* instr, int64_t op2); 1772 uint64_t AddWithCarry(unsigned reg_size, 1773 bool set_flags, 1774 uint64_t left, 1775 uint64_t right, 1776 int carry_in = 0); 1777 void LogicalHelper(const Instruction* instr, int64_t op2); 1778 void ConditionalCompareHelper(const Instruction* instr, int64_t op2); 1779 void LoadStoreHelper(const Instruction* instr, 1780 int64_t offset, 1781 AddrMode addrmode); 1782 void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode); 1783 uintptr_t AddressModeHelper(unsigned addr_reg, 1784 int64_t offset, 1785 AddrMode addrmode); 1786 void NEONLoadStoreMultiStructHelper(const Instruction* instr, 1787 AddrMode addr_mode); 1788 void NEONLoadStoreSingleStructHelper(const Instruction* instr, 1789 AddrMode addr_mode); 1790 1791 uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; } 1792 1793 template <typename T> 1794 T* AddressUntag(T* address) { 1795 uintptr_t address_raw = reinterpret_cast<uintptr_t>(address); 1796 return reinterpret_cast<T*>(AddressUntag(address_raw)); 1797 } 1798 1799 int64_t ShiftOperand(unsigned reg_size, 1800 int64_t value, 1801 Shift shift_type, 1802 unsigned amount) const; 1803 int64_t ExtendValue(unsigned reg_width, 1804 int64_t value, 1805 Extend extend_type, 1806 unsigned left_shift = 0) const; 1807 uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const; 1808 1809 void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1810 void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr); 1811 void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1812 void ld2(VectorFormat vform, 1813 LogicVRegister dst1, 1814 LogicVRegister dst2, 1815 uint64_t addr); 1816 void ld2(VectorFormat vform, 1817 LogicVRegister dst1, 1818 LogicVRegister dst2, 1819 int index, 1820 uint64_t addr); 1821 void ld2r(VectorFormat vform, 1822 LogicVRegister dst1, 1823 LogicVRegister dst2, 1824 uint64_t addr); 1825 void ld3(VectorFormat vform, 1826 LogicVRegister dst1, 1827 LogicVRegister dst2, 1828 LogicVRegister dst3, 1829 uint64_t addr); 1830 void ld3(VectorFormat vform, 1831 LogicVRegister dst1, 1832 LogicVRegister dst2, 1833 LogicVRegister dst3, 1834 int index, 1835 uint64_t addr); 1836 void ld3r(VectorFormat vform, 1837 LogicVRegister dst1, 1838 LogicVRegister dst2, 1839 LogicVRegister dst3, 1840 uint64_t addr); 1841 void ld4(VectorFormat vform, 1842 LogicVRegister dst1, 1843 LogicVRegister dst2, 1844 LogicVRegister dst3, 1845 LogicVRegister dst4, 1846 uint64_t addr); 1847 void ld4(VectorFormat vform, 1848 LogicVRegister dst1, 1849 LogicVRegister dst2, 1850 LogicVRegister dst3, 1851 LogicVRegister dst4, 1852 int index, 1853 uint64_t addr); 1854 void ld4r(VectorFormat vform, 1855 LogicVRegister dst1, 1856 LogicVRegister dst2, 1857 LogicVRegister dst3, 1858 LogicVRegister dst4, 1859 uint64_t addr); 1860 void st1(VectorFormat vform, LogicVRegister src, uint64_t addr); 1861 void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr); 1862 void st2(VectorFormat vform, 1863 LogicVRegister src, 1864 LogicVRegister src2, 1865 uint64_t addr); 1866 void st2(VectorFormat vform, 1867 LogicVRegister src, 1868 LogicVRegister src2, 1869 int index, 1870 uint64_t addr); 1871 void st3(VectorFormat vform, 1872 LogicVRegister src, 1873 LogicVRegister src2, 1874 LogicVRegister src3, 1875 uint64_t addr); 1876 void st3(VectorFormat vform, 1877 LogicVRegister src, 1878 LogicVRegister src2, 1879 LogicVRegister src3, 1880 int index, 1881 uint64_t addr); 1882 void st4(VectorFormat vform, 1883 LogicVRegister src, 1884 LogicVRegister src2, 1885 LogicVRegister src3, 1886 LogicVRegister src4, 1887 uint64_t addr); 1888 void st4(VectorFormat vform, 1889 LogicVRegister src, 1890 LogicVRegister src2, 1891 LogicVRegister src3, 1892 LogicVRegister src4, 1893 int index, 1894 uint64_t addr); 1895 LogicVRegister cmp(VectorFormat vform, 1896 LogicVRegister dst, 1897 const LogicVRegister& src1, 1898 const LogicVRegister& src2, 1899 Condition cond); 1900 LogicVRegister cmp(VectorFormat vform, 1901 LogicVRegister dst, 1902 const LogicVRegister& src1, 1903 int imm, 1904 Condition cond); 1905 LogicVRegister cmptst(VectorFormat vform, 1906 LogicVRegister dst, 1907 const LogicVRegister& src1, 1908 const LogicVRegister& src2); 1909 LogicVRegister add(VectorFormat vform, 1910 LogicVRegister dst, 1911 const LogicVRegister& src1, 1912 const LogicVRegister& src2); 1913 LogicVRegister addp(VectorFormat vform, 1914 LogicVRegister dst, 1915 const LogicVRegister& src1, 1916 const LogicVRegister& src2); 1917 LogicVRegister mla(VectorFormat vform, 1918 LogicVRegister dst, 1919 const LogicVRegister& src1, 1920 const LogicVRegister& src2); 1921 LogicVRegister mls(VectorFormat vform, 1922 LogicVRegister dst, 1923 const LogicVRegister& src1, 1924 const LogicVRegister& src2); 1925 LogicVRegister mul(VectorFormat vform, 1926 LogicVRegister dst, 1927 const LogicVRegister& src1, 1928 const LogicVRegister& src2); 1929 LogicVRegister mul(VectorFormat vform, 1930 LogicVRegister dst, 1931 const LogicVRegister& src1, 1932 const LogicVRegister& src2, 1933 int index); 1934 LogicVRegister mla(VectorFormat vform, 1935 LogicVRegister dst, 1936 const LogicVRegister& src1, 1937 const LogicVRegister& src2, 1938 int index); 1939 LogicVRegister mls(VectorFormat vform, 1940 LogicVRegister dst, 1941 const LogicVRegister& src1, 1942 const LogicVRegister& src2, 1943 int index); 1944 LogicVRegister pmul(VectorFormat vform, 1945 LogicVRegister dst, 1946 const LogicVRegister& src1, 1947 const LogicVRegister& src2); 1948 1949 typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform, 1950 LogicVRegister dst, 1951 const LogicVRegister& src1, 1952 const LogicVRegister& src2, 1953 int index); 1954 LogicVRegister fmul(VectorFormat vform, 1955 LogicVRegister dst, 1956 const LogicVRegister& src1, 1957 const LogicVRegister& src2, 1958 int index); 1959 LogicVRegister fmla(VectorFormat vform, 1960 LogicVRegister dst, 1961 const LogicVRegister& src1, 1962 const LogicVRegister& src2, 1963 int index); 1964 LogicVRegister fmls(VectorFormat vform, 1965 LogicVRegister dst, 1966 const LogicVRegister& src1, 1967 const LogicVRegister& src2, 1968 int index); 1969 LogicVRegister fmulx(VectorFormat vform, 1970 LogicVRegister dst, 1971 const LogicVRegister& src1, 1972 const LogicVRegister& src2, 1973 int index); 1974 LogicVRegister smull(VectorFormat vform, 1975 LogicVRegister dst, 1976 const LogicVRegister& src1, 1977 const LogicVRegister& src2, 1978 int index); 1979 LogicVRegister smull2(VectorFormat vform, 1980 LogicVRegister dst, 1981 const LogicVRegister& src1, 1982 const LogicVRegister& src2, 1983 int index); 1984 LogicVRegister umull(VectorFormat vform, 1985 LogicVRegister dst, 1986 const LogicVRegister& src1, 1987 const LogicVRegister& src2, 1988 int index); 1989 LogicVRegister umull2(VectorFormat vform, 1990 LogicVRegister dst, 1991 const LogicVRegister& src1, 1992 const LogicVRegister& src2, 1993 int index); 1994 LogicVRegister smlal(VectorFormat vform, 1995 LogicVRegister dst, 1996 const LogicVRegister& src1, 1997 const LogicVRegister& src2, 1998 int index); 1999 LogicVRegister smlal2(VectorFormat vform, 2000 LogicVRegister dst, 2001 const LogicVRegister& src1, 2002 const LogicVRegister& src2, 2003 int index); 2004 LogicVRegister umlal(VectorFormat vform, 2005 LogicVRegister dst, 2006 const LogicVRegister& src1, 2007 const LogicVRegister& src2, 2008 int index); 2009 LogicVRegister umlal2(VectorFormat vform, 2010 LogicVRegister dst, 2011 const LogicVRegister& src1, 2012 const LogicVRegister& src2, 2013 int index); 2014 LogicVRegister smlsl(VectorFormat vform, 2015 LogicVRegister dst, 2016 const LogicVRegister& src1, 2017 const LogicVRegister& src2, 2018 int index); 2019 LogicVRegister smlsl2(VectorFormat vform, 2020 LogicVRegister dst, 2021 const LogicVRegister& src1, 2022 const LogicVRegister& src2, 2023 int index); 2024 LogicVRegister umlsl(VectorFormat vform, 2025 LogicVRegister dst, 2026 const LogicVRegister& src1, 2027 const LogicVRegister& src2, 2028 int index); 2029 LogicVRegister umlsl2(VectorFormat vform, 2030 LogicVRegister dst, 2031 const LogicVRegister& src1, 2032 const LogicVRegister& src2, 2033 int index); 2034 LogicVRegister sqdmull(VectorFormat vform, 2035 LogicVRegister dst, 2036 const LogicVRegister& src1, 2037 const LogicVRegister& src2, 2038 int index); 2039 LogicVRegister sqdmull2(VectorFormat vform, 2040 LogicVRegister dst, 2041 const LogicVRegister& src1, 2042 const LogicVRegister& src2, 2043 int index); 2044 LogicVRegister sqdmlal(VectorFormat vform, 2045 LogicVRegister dst, 2046 const LogicVRegister& src1, 2047 const LogicVRegister& src2, 2048 int index); 2049 LogicVRegister sqdmlal2(VectorFormat vform, 2050 LogicVRegister dst, 2051 const LogicVRegister& src1, 2052 const LogicVRegister& src2, 2053 int index); 2054 LogicVRegister sqdmlsl(VectorFormat vform, 2055 LogicVRegister dst, 2056 const LogicVRegister& src1, 2057 const LogicVRegister& src2, 2058 int index); 2059 LogicVRegister sqdmlsl2(VectorFormat vform, 2060 LogicVRegister dst, 2061 const LogicVRegister& src1, 2062 const LogicVRegister& src2, 2063 int index); 2064 LogicVRegister sqdmulh(VectorFormat vform, 2065 LogicVRegister dst, 2066 const LogicVRegister& src1, 2067 const LogicVRegister& src2, 2068 int index); 2069 LogicVRegister sqrdmulh(VectorFormat vform, 2070 LogicVRegister dst, 2071 const LogicVRegister& src1, 2072 const LogicVRegister& src2, 2073 int index); 2074 LogicVRegister sub(VectorFormat vform, 2075 LogicVRegister dst, 2076 const LogicVRegister& src1, 2077 const LogicVRegister& src2); 2078 LogicVRegister and_(VectorFormat vform, 2079 LogicVRegister dst, 2080 const LogicVRegister& src1, 2081 const LogicVRegister& src2); 2082 LogicVRegister orr(VectorFormat vform, 2083 LogicVRegister dst, 2084 const LogicVRegister& src1, 2085 const LogicVRegister& src2); 2086 LogicVRegister orn(VectorFormat vform, 2087 LogicVRegister dst, 2088 const LogicVRegister& src1, 2089 const LogicVRegister& src2); 2090 LogicVRegister eor(VectorFormat vform, 2091 LogicVRegister dst, 2092 const LogicVRegister& src1, 2093 const LogicVRegister& src2); 2094 LogicVRegister bic(VectorFormat vform, 2095 LogicVRegister dst, 2096 const LogicVRegister& src1, 2097 const LogicVRegister& src2); 2098 LogicVRegister bic(VectorFormat vform, 2099 LogicVRegister dst, 2100 const LogicVRegister& src, 2101 uint64_t imm); 2102 LogicVRegister bif(VectorFormat vform, 2103 LogicVRegister dst, 2104 const LogicVRegister& src1, 2105 const LogicVRegister& src2); 2106 LogicVRegister bit(VectorFormat vform, 2107 LogicVRegister dst, 2108 const LogicVRegister& src1, 2109 const LogicVRegister& src2); 2110 LogicVRegister bsl(VectorFormat vform, 2111 LogicVRegister dst, 2112 const LogicVRegister& src1, 2113 const LogicVRegister& src2); 2114 LogicVRegister cls(VectorFormat vform, 2115 LogicVRegister dst, 2116 const LogicVRegister& src); 2117 LogicVRegister clz(VectorFormat vform, 2118 LogicVRegister dst, 2119 const LogicVRegister& src); 2120 LogicVRegister cnt(VectorFormat vform, 2121 LogicVRegister dst, 2122 const LogicVRegister& src); 2123 LogicVRegister not_(VectorFormat vform, 2124 LogicVRegister dst, 2125 const LogicVRegister& src); 2126 LogicVRegister rbit(VectorFormat vform, 2127 LogicVRegister dst, 2128 const LogicVRegister& src); 2129 LogicVRegister rev(VectorFormat vform, 2130 LogicVRegister dst, 2131 const LogicVRegister& src, 2132 int revSize); 2133 LogicVRegister rev16(VectorFormat vform, 2134 LogicVRegister dst, 2135 const LogicVRegister& src); 2136 LogicVRegister rev32(VectorFormat vform, 2137 LogicVRegister dst, 2138 const LogicVRegister& src); 2139 LogicVRegister rev64(VectorFormat vform, 2140 LogicVRegister dst, 2141 const LogicVRegister& src); 2142 LogicVRegister addlp(VectorFormat vform, 2143 LogicVRegister dst, 2144 const LogicVRegister& src, 2145 bool is_signed, 2146 bool do_accumulate); 2147 LogicVRegister saddlp(VectorFormat vform, 2148 LogicVRegister dst, 2149 const LogicVRegister& src); 2150 LogicVRegister uaddlp(VectorFormat vform, 2151 LogicVRegister dst, 2152 const LogicVRegister& src); 2153 LogicVRegister sadalp(VectorFormat vform, 2154 LogicVRegister dst, 2155 const LogicVRegister& src); 2156 LogicVRegister uadalp(VectorFormat vform, 2157 LogicVRegister dst, 2158 const LogicVRegister& src); 2159 LogicVRegister ext(VectorFormat vform, 2160 LogicVRegister dst, 2161 const LogicVRegister& src1, 2162 const LogicVRegister& src2, 2163 int index); 2164 LogicVRegister ins_element(VectorFormat vform, 2165 LogicVRegister dst, 2166 int dst_index, 2167 const LogicVRegister& src, 2168 int src_index); 2169 LogicVRegister ins_immediate(VectorFormat vform, 2170 LogicVRegister dst, 2171 int dst_index, 2172 uint64_t imm); 2173 LogicVRegister dup_element(VectorFormat vform, 2174 LogicVRegister dst, 2175 const LogicVRegister& src, 2176 int src_index); 2177 LogicVRegister dup_immediate(VectorFormat vform, 2178 LogicVRegister dst, 2179 uint64_t imm); 2180 LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2181 LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2182 LogicVRegister orr(VectorFormat vform, 2183 LogicVRegister dst, 2184 const LogicVRegister& src, 2185 uint64_t imm); 2186 LogicVRegister sshl(VectorFormat vform, 2187 LogicVRegister dst, 2188 const LogicVRegister& src1, 2189 const LogicVRegister& src2); 2190 LogicVRegister ushl(VectorFormat vform, 2191 LogicVRegister dst, 2192 const LogicVRegister& src1, 2193 const LogicVRegister& src2); 2194 LogicVRegister sminmax(VectorFormat vform, 2195 LogicVRegister dst, 2196 const LogicVRegister& src1, 2197 const LogicVRegister& src2, 2198 bool max); 2199 LogicVRegister smax(VectorFormat vform, 2200 LogicVRegister dst, 2201 const LogicVRegister& src1, 2202 const LogicVRegister& src2); 2203 LogicVRegister smin(VectorFormat vform, 2204 LogicVRegister dst, 2205 const LogicVRegister& src1, 2206 const LogicVRegister& src2); 2207 LogicVRegister sminmaxp(VectorFormat vform, 2208 LogicVRegister dst, 2209 int dst_index, 2210 const LogicVRegister& src, 2211 bool max); 2212 LogicVRegister smaxp(VectorFormat vform, 2213 LogicVRegister dst, 2214 const LogicVRegister& src1, 2215 const LogicVRegister& src2); 2216 LogicVRegister sminp(VectorFormat vform, 2217 LogicVRegister dst, 2218 const LogicVRegister& src1, 2219 const LogicVRegister& src2); 2220 LogicVRegister addp(VectorFormat vform, 2221 LogicVRegister dst, 2222 const LogicVRegister& src); 2223 LogicVRegister addv(VectorFormat vform, 2224 LogicVRegister dst, 2225 const LogicVRegister& src); 2226 LogicVRegister uaddlv(VectorFormat vform, 2227 LogicVRegister dst, 2228 const LogicVRegister& src); 2229 LogicVRegister saddlv(VectorFormat vform, 2230 LogicVRegister dst, 2231 const LogicVRegister& src); 2232 LogicVRegister sminmaxv(VectorFormat vform, 2233 LogicVRegister dst, 2234 const LogicVRegister& src, 2235 bool max); 2236 LogicVRegister smaxv(VectorFormat vform, 2237 LogicVRegister dst, 2238 const LogicVRegister& src); 2239 LogicVRegister sminv(VectorFormat vform, 2240 LogicVRegister dst, 2241 const LogicVRegister& src); 2242 LogicVRegister uxtl(VectorFormat vform, 2243 LogicVRegister dst, 2244 const LogicVRegister& src); 2245 LogicVRegister uxtl2(VectorFormat vform, 2246 LogicVRegister dst, 2247 const LogicVRegister& src); 2248 LogicVRegister sxtl(VectorFormat vform, 2249 LogicVRegister dst, 2250 const LogicVRegister& src); 2251 LogicVRegister sxtl2(VectorFormat vform, 2252 LogicVRegister dst, 2253 const LogicVRegister& src); 2254 LogicVRegister tbl(VectorFormat vform, 2255 LogicVRegister dst, 2256 const LogicVRegister& tab, 2257 const LogicVRegister& ind); 2258 LogicVRegister tbl(VectorFormat vform, 2259 LogicVRegister dst, 2260 const LogicVRegister& tab, 2261 const LogicVRegister& tab2, 2262 const LogicVRegister& ind); 2263 LogicVRegister tbl(VectorFormat vform, 2264 LogicVRegister dst, 2265 const LogicVRegister& tab, 2266 const LogicVRegister& tab2, 2267 const LogicVRegister& tab3, 2268 const LogicVRegister& ind); 2269 LogicVRegister tbl(VectorFormat vform, 2270 LogicVRegister dst, 2271 const LogicVRegister& tab, 2272 const LogicVRegister& tab2, 2273 const LogicVRegister& tab3, 2274 const LogicVRegister& tab4, 2275 const LogicVRegister& ind); 2276 LogicVRegister tbx(VectorFormat vform, 2277 LogicVRegister dst, 2278 const LogicVRegister& tab, 2279 const LogicVRegister& ind); 2280 LogicVRegister tbx(VectorFormat vform, 2281 LogicVRegister dst, 2282 const LogicVRegister& tab, 2283 const LogicVRegister& tab2, 2284 const LogicVRegister& ind); 2285 LogicVRegister tbx(VectorFormat vform, 2286 LogicVRegister dst, 2287 const LogicVRegister& tab, 2288 const LogicVRegister& tab2, 2289 const LogicVRegister& tab3, 2290 const LogicVRegister& ind); 2291 LogicVRegister tbx(VectorFormat vform, 2292 LogicVRegister dst, 2293 const LogicVRegister& tab, 2294 const LogicVRegister& tab2, 2295 const LogicVRegister& tab3, 2296 const LogicVRegister& tab4, 2297 const LogicVRegister& ind); 2298 LogicVRegister uaddl(VectorFormat vform, 2299 LogicVRegister dst, 2300 const LogicVRegister& src1, 2301 const LogicVRegister& src2); 2302 LogicVRegister uaddl2(VectorFormat vform, 2303 LogicVRegister dst, 2304 const LogicVRegister& src1, 2305 const LogicVRegister& src2); 2306 LogicVRegister uaddw(VectorFormat vform, 2307 LogicVRegister dst, 2308 const LogicVRegister& src1, 2309 const LogicVRegister& src2); 2310 LogicVRegister uaddw2(VectorFormat vform, 2311 LogicVRegister dst, 2312 const LogicVRegister& src1, 2313 const LogicVRegister& src2); 2314 LogicVRegister saddl(VectorFormat vform, 2315 LogicVRegister dst, 2316 const LogicVRegister& src1, 2317 const LogicVRegister& src2); 2318 LogicVRegister saddl2(VectorFormat vform, 2319 LogicVRegister dst, 2320 const LogicVRegister& src1, 2321 const LogicVRegister& src2); 2322 LogicVRegister saddw(VectorFormat vform, 2323 LogicVRegister dst, 2324 const LogicVRegister& src1, 2325 const LogicVRegister& src2); 2326 LogicVRegister saddw2(VectorFormat vform, 2327 LogicVRegister dst, 2328 const LogicVRegister& src1, 2329 const LogicVRegister& src2); 2330 LogicVRegister usubl(VectorFormat vform, 2331 LogicVRegister dst, 2332 const LogicVRegister& src1, 2333 const LogicVRegister& src2); 2334 LogicVRegister usubl2(VectorFormat vform, 2335 LogicVRegister dst, 2336 const LogicVRegister& src1, 2337 const LogicVRegister& src2); 2338 LogicVRegister usubw(VectorFormat vform, 2339 LogicVRegister dst, 2340 const LogicVRegister& src1, 2341 const LogicVRegister& src2); 2342 LogicVRegister usubw2(VectorFormat vform, 2343 LogicVRegister dst, 2344 const LogicVRegister& src1, 2345 const LogicVRegister& src2); 2346 LogicVRegister ssubl(VectorFormat vform, 2347 LogicVRegister dst, 2348 const LogicVRegister& src1, 2349 const LogicVRegister& src2); 2350 LogicVRegister ssubl2(VectorFormat vform, 2351 LogicVRegister dst, 2352 const LogicVRegister& src1, 2353 const LogicVRegister& src2); 2354 LogicVRegister ssubw(VectorFormat vform, 2355 LogicVRegister dst, 2356 const LogicVRegister& src1, 2357 const LogicVRegister& src2); 2358 LogicVRegister ssubw2(VectorFormat vform, 2359 LogicVRegister dst, 2360 const LogicVRegister& src1, 2361 const LogicVRegister& src2); 2362 LogicVRegister uminmax(VectorFormat vform, 2363 LogicVRegister dst, 2364 const LogicVRegister& src1, 2365 const LogicVRegister& src2, 2366 bool max); 2367 LogicVRegister umax(VectorFormat vform, 2368 LogicVRegister dst, 2369 const LogicVRegister& src1, 2370 const LogicVRegister& src2); 2371 LogicVRegister umin(VectorFormat vform, 2372 LogicVRegister dst, 2373 const LogicVRegister& src1, 2374 const LogicVRegister& src2); 2375 LogicVRegister uminmaxp(VectorFormat vform, 2376 LogicVRegister dst, 2377 int dst_index, 2378 const LogicVRegister& src, 2379 bool max); 2380 LogicVRegister umaxp(VectorFormat vform, 2381 LogicVRegister dst, 2382 const LogicVRegister& src1, 2383 const LogicVRegister& src2); 2384 LogicVRegister uminp(VectorFormat vform, 2385 LogicVRegister dst, 2386 const LogicVRegister& src1, 2387 const LogicVRegister& src2); 2388 LogicVRegister uminmaxv(VectorFormat vform, 2389 LogicVRegister dst, 2390 const LogicVRegister& src, 2391 bool max); 2392 LogicVRegister umaxv(VectorFormat vform, 2393 LogicVRegister dst, 2394 const LogicVRegister& src); 2395 LogicVRegister uminv(VectorFormat vform, 2396 LogicVRegister dst, 2397 const LogicVRegister& src); 2398 LogicVRegister trn1(VectorFormat vform, 2399 LogicVRegister dst, 2400 const LogicVRegister& src1, 2401 const LogicVRegister& src2); 2402 LogicVRegister trn2(VectorFormat vform, 2403 LogicVRegister dst, 2404 const LogicVRegister& src1, 2405 const LogicVRegister& src2); 2406 LogicVRegister zip1(VectorFormat vform, 2407 LogicVRegister dst, 2408 const LogicVRegister& src1, 2409 const LogicVRegister& src2); 2410 LogicVRegister zip2(VectorFormat vform, 2411 LogicVRegister dst, 2412 const LogicVRegister& src1, 2413 const LogicVRegister& src2); 2414 LogicVRegister uzp1(VectorFormat vform, 2415 LogicVRegister dst, 2416 const LogicVRegister& src1, 2417 const LogicVRegister& src2); 2418 LogicVRegister uzp2(VectorFormat vform, 2419 LogicVRegister dst, 2420 const LogicVRegister& src1, 2421 const LogicVRegister& src2); 2422 LogicVRegister shl(VectorFormat vform, 2423 LogicVRegister dst, 2424 const LogicVRegister& src, 2425 int shift); 2426 LogicVRegister scvtf(VectorFormat vform, 2427 LogicVRegister dst, 2428 const LogicVRegister& src, 2429 int fbits, 2430 FPRounding rounding_mode); 2431 LogicVRegister ucvtf(VectorFormat vform, 2432 LogicVRegister dst, 2433 const LogicVRegister& src, 2434 int fbits, 2435 FPRounding rounding_mode); 2436 LogicVRegister sshll(VectorFormat vform, 2437 LogicVRegister dst, 2438 const LogicVRegister& src, 2439 int shift); 2440 LogicVRegister sshll2(VectorFormat vform, 2441 LogicVRegister dst, 2442 const LogicVRegister& src, 2443 int shift); 2444 LogicVRegister shll(VectorFormat vform, 2445 LogicVRegister dst, 2446 const LogicVRegister& src); 2447 LogicVRegister shll2(VectorFormat vform, 2448 LogicVRegister dst, 2449 const LogicVRegister& src); 2450 LogicVRegister ushll(VectorFormat vform, 2451 LogicVRegister dst, 2452 const LogicVRegister& src, 2453 int shift); 2454 LogicVRegister ushll2(VectorFormat vform, 2455 LogicVRegister dst, 2456 const LogicVRegister& src, 2457 int shift); 2458 LogicVRegister sli(VectorFormat vform, 2459 LogicVRegister dst, 2460 const LogicVRegister& src, 2461 int shift); 2462 LogicVRegister sri(VectorFormat vform, 2463 LogicVRegister dst, 2464 const LogicVRegister& src, 2465 int shift); 2466 LogicVRegister sshr(VectorFormat vform, 2467 LogicVRegister dst, 2468 const LogicVRegister& src, 2469 int shift); 2470 LogicVRegister ushr(VectorFormat vform, 2471 LogicVRegister dst, 2472 const LogicVRegister& src, 2473 int shift); 2474 LogicVRegister ssra(VectorFormat vform, 2475 LogicVRegister dst, 2476 const LogicVRegister& src, 2477 int shift); 2478 LogicVRegister usra(VectorFormat vform, 2479 LogicVRegister dst, 2480 const LogicVRegister& src, 2481 int shift); 2482 LogicVRegister srsra(VectorFormat vform, 2483 LogicVRegister dst, 2484 const LogicVRegister& src, 2485 int shift); 2486 LogicVRegister ursra(VectorFormat vform, 2487 LogicVRegister dst, 2488 const LogicVRegister& src, 2489 int shift); 2490 LogicVRegister suqadd(VectorFormat vform, 2491 LogicVRegister dst, 2492 const LogicVRegister& src); 2493 LogicVRegister usqadd(VectorFormat vform, 2494 LogicVRegister dst, 2495 const LogicVRegister& src); 2496 LogicVRegister sqshl(VectorFormat vform, 2497 LogicVRegister dst, 2498 const LogicVRegister& src, 2499 int shift); 2500 LogicVRegister uqshl(VectorFormat vform, 2501 LogicVRegister dst, 2502 const LogicVRegister& src, 2503 int shift); 2504 LogicVRegister sqshlu(VectorFormat vform, 2505 LogicVRegister dst, 2506 const LogicVRegister& src, 2507 int shift); 2508 LogicVRegister abs(VectorFormat vform, 2509 LogicVRegister dst, 2510 const LogicVRegister& src); 2511 LogicVRegister neg(VectorFormat vform, 2512 LogicVRegister dst, 2513 const LogicVRegister& src); 2514 LogicVRegister extractnarrow(VectorFormat vform, 2515 LogicVRegister dst, 2516 bool dstIsSigned, 2517 const LogicVRegister& src, 2518 bool srcIsSigned); 2519 LogicVRegister xtn(VectorFormat vform, 2520 LogicVRegister dst, 2521 const LogicVRegister& src); 2522 LogicVRegister sqxtn(VectorFormat vform, 2523 LogicVRegister dst, 2524 const LogicVRegister& src); 2525 LogicVRegister uqxtn(VectorFormat vform, 2526 LogicVRegister dst, 2527 const LogicVRegister& src); 2528 LogicVRegister sqxtun(VectorFormat vform, 2529 LogicVRegister dst, 2530 const LogicVRegister& src); 2531 LogicVRegister absdiff(VectorFormat vform, 2532 LogicVRegister dst, 2533 const LogicVRegister& src1, 2534 const LogicVRegister& src2, 2535 bool issigned); 2536 LogicVRegister saba(VectorFormat vform, 2537 LogicVRegister dst, 2538 const LogicVRegister& src1, 2539 const LogicVRegister& src2); 2540 LogicVRegister uaba(VectorFormat vform, 2541 LogicVRegister dst, 2542 const LogicVRegister& src1, 2543 const LogicVRegister& src2); 2544 LogicVRegister shrn(VectorFormat vform, 2545 LogicVRegister dst, 2546 const LogicVRegister& src, 2547 int shift); 2548 LogicVRegister shrn2(VectorFormat vform, 2549 LogicVRegister dst, 2550 const LogicVRegister& src, 2551 int shift); 2552 LogicVRegister rshrn(VectorFormat vform, 2553 LogicVRegister dst, 2554 const LogicVRegister& src, 2555 int shift); 2556 LogicVRegister rshrn2(VectorFormat vform, 2557 LogicVRegister dst, 2558 const LogicVRegister& src, 2559 int shift); 2560 LogicVRegister uqshrn(VectorFormat vform, 2561 LogicVRegister dst, 2562 const LogicVRegister& src, 2563 int shift); 2564 LogicVRegister uqshrn2(VectorFormat vform, 2565 LogicVRegister dst, 2566 const LogicVRegister& src, 2567 int shift); 2568 LogicVRegister uqrshrn(VectorFormat vform, 2569 LogicVRegister dst, 2570 const LogicVRegister& src, 2571 int shift); 2572 LogicVRegister uqrshrn2(VectorFormat vform, 2573 LogicVRegister dst, 2574 const LogicVRegister& src, 2575 int shift); 2576 LogicVRegister sqshrn(VectorFormat vform, 2577 LogicVRegister dst, 2578 const LogicVRegister& src, 2579 int shift); 2580 LogicVRegister sqshrn2(VectorFormat vform, 2581 LogicVRegister dst, 2582 const LogicVRegister& src, 2583 int shift); 2584 LogicVRegister sqrshrn(VectorFormat vform, 2585 LogicVRegister dst, 2586 const LogicVRegister& src, 2587 int shift); 2588 LogicVRegister sqrshrn2(VectorFormat vform, 2589 LogicVRegister dst, 2590 const LogicVRegister& src, 2591 int shift); 2592 LogicVRegister sqshrun(VectorFormat vform, 2593 LogicVRegister dst, 2594 const LogicVRegister& src, 2595 int shift); 2596 LogicVRegister sqshrun2(VectorFormat vform, 2597 LogicVRegister dst, 2598 const LogicVRegister& src, 2599 int shift); 2600 LogicVRegister sqrshrun(VectorFormat vform, 2601 LogicVRegister dst, 2602 const LogicVRegister& src, 2603 int shift); 2604 LogicVRegister sqrshrun2(VectorFormat vform, 2605 LogicVRegister dst, 2606 const LogicVRegister& src, 2607 int shift); 2608 LogicVRegister sqrdmulh(VectorFormat vform, 2609 LogicVRegister dst, 2610 const LogicVRegister& src1, 2611 const LogicVRegister& src2, 2612 bool round = true); 2613 LogicVRegister sqdmulh(VectorFormat vform, 2614 LogicVRegister dst, 2615 const LogicVRegister& src1, 2616 const LogicVRegister& src2); 2617#define NEON_3VREG_LOGIC_LIST(V) \ 2618 V(addhn) \ 2619 V(addhn2) \ 2620 V(raddhn) \ 2621 V(raddhn2) \ 2622 V(subhn) \ 2623 V(subhn2) \ 2624 V(rsubhn) \ 2625 V(rsubhn2) \ 2626 V(pmull) \ 2627 V(pmull2) \ 2628 V(sabal) \ 2629 V(sabal2) \ 2630 V(uabal) \ 2631 V(uabal2) \ 2632 V(sabdl) \ 2633 V(sabdl2) \ 2634 V(uabdl) \ 2635 V(uabdl2) \ 2636 V(smull) \ 2637 V(smull2) \ 2638 V(umull) \ 2639 V(umull2) \ 2640 V(smlal) \ 2641 V(smlal2) \ 2642 V(umlal) \ 2643 V(umlal2) \ 2644 V(smlsl) \ 2645 V(smlsl2) \ 2646 V(umlsl) \ 2647 V(umlsl2) \ 2648 V(sqdmlal) \ 2649 V(sqdmlal2) \ 2650 V(sqdmlsl) \ 2651 V(sqdmlsl2) \ 2652 V(sqdmull) \ 2653 V(sqdmull2) 2654 2655#define DEFINE_LOGIC_FUNC(FXN) \ 2656 LogicVRegister FXN(VectorFormat vform, \ 2657 LogicVRegister dst, \ 2658 const LogicVRegister& src1, \ 2659 const LogicVRegister& src2); 2660 NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC) 2661#undef DEFINE_LOGIC_FUNC 2662 2663#define NEON_FP3SAME_LIST(V) \ 2664 V(fadd, FPAdd, false) \ 2665 V(fsub, FPSub, true) \ 2666 V(fmul, FPMul, true) \ 2667 V(fmulx, FPMulx, true) \ 2668 V(fdiv, FPDiv, true) \ 2669 V(fmax, FPMax, false) \ 2670 V(fmin, FPMin, false) \ 2671 V(fmaxnm, FPMaxNM, false) \ 2672 V(fminnm, FPMinNM, false) 2673 2674#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \ 2675 template <typename T> \ 2676 LogicVRegister FN(VectorFormat vform, \ 2677 LogicVRegister dst, \ 2678 const LogicVRegister& src1, \ 2679 const LogicVRegister& src2); \ 2680 LogicVRegister FN(VectorFormat vform, \ 2681 LogicVRegister dst, \ 2682 const LogicVRegister& src1, \ 2683 const LogicVRegister& src2); 2684 NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP) 2685#undef DECLARE_NEON_FP_VECTOR_OP 2686 2687#define NEON_FPPAIRWISE_LIST(V) \ 2688 V(faddp, fadd, FPAdd) \ 2689 V(fmaxp, fmax, FPMax) \ 2690 V(fmaxnmp, fmaxnm, FPMaxNM) \ 2691 V(fminp, fmin, FPMin) \ 2692 V(fminnmp, fminnm, FPMinNM) 2693 2694#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP) \ 2695 LogicVRegister FNP(VectorFormat vform, \ 2696 LogicVRegister dst, \ 2697 const LogicVRegister& src1, \ 2698 const LogicVRegister& src2); \ 2699 LogicVRegister FNP(VectorFormat vform, \ 2700 LogicVRegister dst, \ 2701 const LogicVRegister& src); 2702 NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP) 2703#undef DECLARE_NEON_FP_PAIR_OP 2704 2705 template <typename T> 2706 LogicVRegister frecps(VectorFormat vform, 2707 LogicVRegister dst, 2708 const LogicVRegister& src1, 2709 const LogicVRegister& src2); 2710 LogicVRegister frecps(VectorFormat vform, 2711 LogicVRegister dst, 2712 const LogicVRegister& src1, 2713 const LogicVRegister& src2); 2714 template <typename T> 2715 LogicVRegister frsqrts(VectorFormat vform, 2716 LogicVRegister dst, 2717 const LogicVRegister& src1, 2718 const LogicVRegister& src2); 2719 LogicVRegister frsqrts(VectorFormat vform, 2720 LogicVRegister dst, 2721 const LogicVRegister& src1, 2722 const LogicVRegister& src2); 2723 template <typename T> 2724 LogicVRegister fmla(VectorFormat vform, 2725 LogicVRegister dst, 2726 const LogicVRegister& src1, 2727 const LogicVRegister& src2); 2728 LogicVRegister fmla(VectorFormat vform, 2729 LogicVRegister dst, 2730 const LogicVRegister& src1, 2731 const LogicVRegister& src2); 2732 template <typename T> 2733 LogicVRegister fmls(VectorFormat vform, 2734 LogicVRegister dst, 2735 const LogicVRegister& src1, 2736 const LogicVRegister& src2); 2737 LogicVRegister fmls(VectorFormat vform, 2738 LogicVRegister dst, 2739 const LogicVRegister& src1, 2740 const LogicVRegister& src2); 2741 LogicVRegister fnmul(VectorFormat vform, 2742 LogicVRegister dst, 2743 const LogicVRegister& src1, 2744 const LogicVRegister& src2); 2745 2746 template <typename T> 2747 LogicVRegister fcmp(VectorFormat vform, 2748 LogicVRegister dst, 2749 const LogicVRegister& src1, 2750 const LogicVRegister& src2, 2751 Condition cond); 2752 LogicVRegister fcmp(VectorFormat vform, 2753 LogicVRegister dst, 2754 const LogicVRegister& src1, 2755 const LogicVRegister& src2, 2756 Condition cond); 2757 LogicVRegister fabscmp(VectorFormat vform, 2758 LogicVRegister dst, 2759 const LogicVRegister& src1, 2760 const LogicVRegister& src2, 2761 Condition cond); 2762 LogicVRegister fcmp_zero(VectorFormat vform, 2763 LogicVRegister dst, 2764 const LogicVRegister& src, 2765 Condition cond); 2766 2767 template <typename T> 2768 LogicVRegister fneg(VectorFormat vform, 2769 LogicVRegister dst, 2770 const LogicVRegister& src); 2771 LogicVRegister fneg(VectorFormat vform, 2772 LogicVRegister dst, 2773 const LogicVRegister& src); 2774 template <typename T> 2775 LogicVRegister frecpx(VectorFormat vform, 2776 LogicVRegister dst, 2777 const LogicVRegister& src); 2778 LogicVRegister frecpx(VectorFormat vform, 2779 LogicVRegister dst, 2780 const LogicVRegister& src); 2781 template <typename T> 2782 LogicVRegister fabs_(VectorFormat vform, 2783 LogicVRegister dst, 2784 const LogicVRegister& src); 2785 LogicVRegister fabs_(VectorFormat vform, 2786 LogicVRegister dst, 2787 const LogicVRegister& src); 2788 LogicVRegister fabd(VectorFormat vform, 2789 LogicVRegister dst, 2790 const LogicVRegister& src1, 2791 const LogicVRegister& src2); 2792 LogicVRegister frint(VectorFormat vform, 2793 LogicVRegister dst, 2794 const LogicVRegister& src, 2795 FPRounding rounding_mode, 2796 bool inexact_exception = false); 2797 LogicVRegister fcvts(VectorFormat vform, 2798 LogicVRegister dst, 2799 const LogicVRegister& src, 2800 FPRounding rounding_mode, 2801 int fbits = 0); 2802 LogicVRegister fcvtu(VectorFormat vform, 2803 LogicVRegister dst, 2804 const LogicVRegister& src, 2805 FPRounding rounding_mode, 2806 int fbits = 0); 2807 LogicVRegister fcvtl(VectorFormat vform, 2808 LogicVRegister dst, 2809 const LogicVRegister& src); 2810 LogicVRegister fcvtl2(VectorFormat vform, 2811 LogicVRegister dst, 2812 const LogicVRegister& src); 2813 LogicVRegister fcvtn(VectorFormat vform, 2814 LogicVRegister dst, 2815 const LogicVRegister& src); 2816 LogicVRegister fcvtn2(VectorFormat vform, 2817 LogicVRegister dst, 2818 const LogicVRegister& src); 2819 LogicVRegister fcvtxn(VectorFormat vform, 2820 LogicVRegister dst, 2821 const LogicVRegister& src); 2822 LogicVRegister fcvtxn2(VectorFormat vform, 2823 LogicVRegister dst, 2824 const LogicVRegister& src); 2825 LogicVRegister fsqrt(VectorFormat vform, 2826 LogicVRegister dst, 2827 const LogicVRegister& src); 2828 LogicVRegister frsqrte(VectorFormat vform, 2829 LogicVRegister dst, 2830 const LogicVRegister& src); 2831 LogicVRegister frecpe(VectorFormat vform, 2832 LogicVRegister dst, 2833 const LogicVRegister& src, 2834 FPRounding rounding); 2835 LogicVRegister ursqrte(VectorFormat vform, 2836 LogicVRegister dst, 2837 const LogicVRegister& src); 2838 LogicVRegister urecpe(VectorFormat vform, 2839 LogicVRegister dst, 2840 const LogicVRegister& src); 2841 2842 typedef float (Simulator::*FPMinMaxOp)(float a, float b); 2843 2844 LogicVRegister fminmaxv(VectorFormat vform, 2845 LogicVRegister dst, 2846 const LogicVRegister& src, 2847 FPMinMaxOp Op); 2848 2849 LogicVRegister fminv(VectorFormat vform, 2850 LogicVRegister dst, 2851 const LogicVRegister& src); 2852 LogicVRegister fmaxv(VectorFormat vform, 2853 LogicVRegister dst, 2854 const LogicVRegister& src); 2855 LogicVRegister fminnmv(VectorFormat vform, 2856 LogicVRegister dst, 2857 const LogicVRegister& src); 2858 LogicVRegister fmaxnmv(VectorFormat vform, 2859 LogicVRegister dst, 2860 const LogicVRegister& src); 2861 2862 static const uint32_t CRC32_POLY = 0x04C11DB7; 2863 static const uint32_t CRC32C_POLY = 0x1EDC6F41; 2864 uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly); 2865 template <typename T> 2866 uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly); 2867 uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly); 2868 2869 void SysOp_W(int op, int64_t val); 2870 2871 template <typename T> 2872 T FPRecipSqrtEstimate(T op); 2873 template <typename T> 2874 T FPRecipEstimate(T op, FPRounding rounding); 2875 template <typename T, typename R> 2876 R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding); 2877 2878 void FPCompare(double val0, double val1, FPTrapFlags trap); 2879 double FPRoundInt(double value, FPRounding round_mode); 2880 double FPToDouble(float value); 2881 float FPToFloat(double value, FPRounding round_mode); 2882 float FPToFloat(float16 value); 2883 float16 FPToFloat16(float value, FPRounding round_mode); 2884 float16 FPToFloat16(double value, FPRounding round_mode); 2885 double recip_sqrt_estimate(double a); 2886 double recip_estimate(double a); 2887 double FPRecipSqrtEstimate(double a); 2888 double FPRecipEstimate(double a); 2889 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); 2890 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); 2891 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); 2892 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); 2893 int32_t FPToInt32(double value, FPRounding rmode); 2894 int64_t FPToInt64(double value, FPRounding rmode); 2895 uint32_t FPToUInt32(double value, FPRounding rmode); 2896 uint64_t FPToUInt64(double value, FPRounding rmode); 2897 2898 template <typename T> 2899 T FPAdd(T op1, T op2); 2900 2901 template <typename T> 2902 T FPDiv(T op1, T op2); 2903 2904 template <typename T> 2905 T FPMax(T a, T b); 2906 2907 template <typename T> 2908 T FPMaxNM(T a, T b); 2909 2910 template <typename T> 2911 T FPMin(T a, T b); 2912 2913 template <typename T> 2914 T FPMinNM(T a, T b); 2915 2916 template <typename T> 2917 T FPMul(T op1, T op2); 2918 2919 template <typename T> 2920 T FPMulx(T op1, T op2); 2921 2922 template <typename T> 2923 T FPMulAdd(T a, T op1, T op2); 2924 2925 template <typename T> 2926 T FPSqrt(T op); 2927 2928 template <typename T> 2929 T FPSub(T op1, T op2); 2930 2931 template <typename T> 2932 T FPRecipStepFused(T op1, T op2); 2933 2934 template <typename T> 2935 T FPRSqrtStepFused(T op1, T op2); 2936 2937 // This doesn't do anything at the moment. We'll need it if we want support 2938 // for cumulative exception bits or floating-point exceptions. 2939 void FPProcessException() {} 2940 2941 bool FPProcessNaNs(const Instruction* instr); 2942 2943 // Pseudo Printf instruction 2944 void DoPrintf(const Instruction* instr); 2945 2946// Simulate a runtime call. 2947#ifndef VIXL_SIMULATED_RUNTIME_CALL_SUPPORT 2948 VIXL_NO_RETURN_IN_DEBUG_MODE 2949#endif 2950 void DoRuntimeCall(const Instruction* instr); 2951 2952 // Processor state --------------------------------------- 2953 2954 // Simulated monitors for exclusive access instructions. 2955 SimExclusiveLocalMonitor local_monitor_; 2956 SimExclusiveGlobalMonitor global_monitor_; 2957 2958 // Output stream. 2959 FILE* stream_; 2960 PrintDisassembler* print_disasm_; 2961 2962 // Instruction statistics instrumentation. 2963 Instrument* instrumentation_; 2964 2965 // General purpose registers. Register 31 is the stack pointer. 2966 SimRegister registers_[kNumberOfRegisters]; 2967 2968 // Vector registers 2969 SimVRegister vregisters_[kNumberOfVRegisters]; 2970 2971 // Program Status Register. 2972 // bits[31, 27]: Condition flags N, Z, C, and V. 2973 // (Negative, Zero, Carry, Overflow) 2974 SimSystemRegister nzcv_; 2975 2976 // Floating-Point Control Register 2977 SimSystemRegister fpcr_; 2978 2979 // Only a subset of FPCR features are supported by the simulator. This helper 2980 // checks that the FPCR settings are supported. 2981 // 2982 // This is checked when floating-point instructions are executed, not when 2983 // FPCR is set. This allows generated code to modify FPCR for external 2984 // functions, or to save and restore it when entering and leaving generated 2985 // code. 2986 void AssertSupportedFPCR() { 2987 // No flush-to-zero support. 2988 VIXL_ASSERT(ReadFpcr().GetFZ() == 0); 2989 // Ties-to-even rounding only. 2990 VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven); 2991 2992 // The simulator does not support half-precision operations so 2993 // GetFpcr().AHP() is irrelevant, and is not checked here. 2994 } 2995 2996 static int CalcNFlag(uint64_t result, unsigned reg_size) { 2997 return (result >> (reg_size - 1)) & 1; 2998 } 2999 3000 static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; } 3001 3002 static const uint32_t kConditionFlagsMask = 0xf0000000; 3003 3004 // Stack 3005 byte* stack_; 3006 static const int stack_protection_size_ = 256; 3007 // 2 KB stack. 3008 static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_; 3009 byte* stack_limit_; 3010 3011 Decoder* decoder_; 3012 // Indicates if the pc has been modified by the instruction and should not be 3013 // automatically incremented. 3014 bool pc_modified_; 3015 const Instruction* pc_; 3016 3017 static const char* xreg_names[]; 3018 static const char* wreg_names[]; 3019 static const char* sreg_names[]; 3020 static const char* dreg_names[]; 3021 static const char* vreg_names[]; 3022 3023 private: 3024 template <typename T> 3025 static T FPDefaultNaN(); 3026 3027 // Standard NaN processing. 3028 template <typename T> 3029 T FPProcessNaN(T op) { 3030 VIXL_ASSERT(std::isnan(op)); 3031 if (IsSignallingNaN(op)) { 3032 FPProcessException(); 3033 } 3034 return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 3035 } 3036 3037 template <typename T> 3038 T FPProcessNaNs(T op1, T op2) { 3039 if (IsSignallingNaN(op1)) { 3040 return FPProcessNaN(op1); 3041 } else if (IsSignallingNaN(op2)) { 3042 return FPProcessNaN(op2); 3043 } else if (std::isnan(op1)) { 3044 VIXL_ASSERT(IsQuietNaN(op1)); 3045 return FPProcessNaN(op1); 3046 } else if (std::isnan(op2)) { 3047 VIXL_ASSERT(IsQuietNaN(op2)); 3048 return FPProcessNaN(op2); 3049 } else { 3050 return 0.0; 3051 } 3052 } 3053 3054 template <typename T> 3055 T FPProcessNaNs3(T op1, T op2, T op3) { 3056 if (IsSignallingNaN(op1)) { 3057 return FPProcessNaN(op1); 3058 } else if (IsSignallingNaN(op2)) { 3059 return FPProcessNaN(op2); 3060 } else if (IsSignallingNaN(op3)) { 3061 return FPProcessNaN(op3); 3062 } else if (std::isnan(op1)) { 3063 VIXL_ASSERT(IsQuietNaN(op1)); 3064 return FPProcessNaN(op1); 3065 } else if (std::isnan(op2)) { 3066 VIXL_ASSERT(IsQuietNaN(op2)); 3067 return FPProcessNaN(op2); 3068 } else if (std::isnan(op3)) { 3069 VIXL_ASSERT(IsQuietNaN(op3)); 3070 return FPProcessNaN(op3); 3071 } else { 3072 return 0.0; 3073 } 3074 } 3075 3076 bool coloured_trace_; 3077 3078 // A set of TraceParameters flags. 3079 int trace_parameters_; 3080 3081 // Indicates whether the instruction instrumentation is active. 3082 bool instruction_stats_; 3083 3084 // Indicates whether the exclusive-access warning has been printed. 3085 bool print_exclusive_access_warning_; 3086 void PrintExclusiveAccessWarning(); 3087}; 3088 3089#if defined(VIXL_ABI_SUPPORT) && __cplusplus >= 201103L && __cplusplus < 201402L 3090// Base case of the recursive template used to emulate C++14 3091// `std::index_sequence`. 3092template <size_t... I> 3093struct Simulator::emulated_make_index_sequence_helper<0, I...> 3094 : Simulator::emulated_index_sequence<I...> {}; 3095#endif 3096 3097} // namespace aarch64 3098} // namespace vixl 3099 3100#endif // VIXL_AARCH64_SIMULATOR_AARCH64_H_ 3101