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