simulator-aarch64.h revision f75ec85cb9c8690e42125aea3dac1e57d46c21da
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 VIXL_STATIC_ASSERT((sizeof(T) == kWRegSizeInBytes) || 1008 (sizeof(T) == kXRegSizeInBytes)); 1009 VIXL_ASSERT( 1010 code < kNumberOfRegisters || 1011 ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode))); 1012 1013 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { 1014 return; 1015 } 1016 1017 if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) { 1018 code = 31; 1019 } 1020 1021 registers_[code].Write(value); 1022 1023 if (log_mode == LogRegWrites) LogRegister(code, r31mode); 1024 } 1025 template <typename T> 1026 VIXL_DEPRECATED("WriteRegister", 1027 void set_reg(unsigned code, 1028 T value, 1029 RegLogMode log_mode = LogRegWrites, 1030 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1031 WriteRegister<T>(code, value, log_mode, r31mode); 1032 } 1033 1034 // Common specialized accessors for the set_reg() template. 1035 void WriteWRegister(unsigned code, 1036 int32_t value, 1037 RegLogMode log_mode = LogRegWrites, 1038 Reg31Mode r31mode = Reg31IsZeroRegister) { 1039 WriteRegister(code, value, log_mode, r31mode); 1040 } 1041 VIXL_DEPRECATED("WriteWRegister", 1042 void set_wreg(unsigned code, 1043 int32_t value, 1044 RegLogMode log_mode = LogRegWrites, 1045 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1046 WriteWRegister(code, value, log_mode, r31mode); 1047 } 1048 1049 void WriteXRegister(unsigned code, 1050 int64_t value, 1051 RegLogMode log_mode = LogRegWrites, 1052 Reg31Mode r31mode = Reg31IsZeroRegister) { 1053 WriteRegister(code, value, log_mode, r31mode); 1054 } 1055 VIXL_DEPRECATED("WriteXRegister", 1056 void set_xreg(unsigned code, 1057 int64_t value, 1058 RegLogMode log_mode = LogRegWrites, 1059 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1060 WriteXRegister(code, value, log_mode, r31mode); 1061 } 1062 1063 // As above, with parameterized size and type. The value is either 1064 // zero-extended or truncated to fit, as required. 1065 template <typename T> 1066 void WriteRegister(unsigned size, 1067 unsigned code, 1068 T value, 1069 RegLogMode log_mode = LogRegWrites, 1070 Reg31Mode r31mode = Reg31IsZeroRegister) { 1071 // Zero-extend the input. 1072 uint64_t raw = 0; 1073 VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw)); 1074 memcpy(&raw, &value, sizeof(value)); 1075 1076 // Write (and possibly truncate) the value. 1077 switch (size) { 1078 case kWRegSize: 1079 WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode); 1080 break; 1081 case kXRegSize: 1082 WriteRegister(code, raw, log_mode, r31mode); 1083 break; 1084 default: 1085 VIXL_UNREACHABLE(); 1086 return; 1087 } 1088 } 1089 template <typename T> 1090 VIXL_DEPRECATED("WriteRegister", 1091 void set_reg(unsigned size, 1092 unsigned code, 1093 T value, 1094 RegLogMode log_mode = LogRegWrites, 1095 Reg31Mode r31mode = Reg31IsZeroRegister)) { 1096 WriteRegister(size, code, value, log_mode, r31mode); 1097 } 1098 1099 // Common specialized accessors for the set_reg() template. 1100 1101 // Commonly-used special cases. 1102 template <typename T> 1103 void WriteLr(T value) { 1104 WriteRegister(kLinkRegCode, value); 1105 } 1106 template <typename T> 1107 VIXL_DEPRECATED("WriteLr", void set_lr(T value)) { 1108 WriteLr(value); 1109 } 1110 1111 template <typename T> 1112 void WriteSp(T value) { 1113 WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer); 1114 } 1115 template <typename T> 1116 VIXL_DEPRECATED("WriteSp", void set_sp(T value)) { 1117 WriteSp(value); 1118 } 1119 1120 // Vector register accessors. 1121 // These are equivalent to the integer register accessors, but for vector 1122 // registers. 1123 1124 // A structure for representing a 128-bit Q register. 1125 struct qreg_t { 1126 uint8_t val[kQRegSizeInBytes]; 1127 }; 1128 1129 // Basic accessor: read the register as the specified type. 1130 template <typename T> 1131 T ReadVRegister(unsigned code) const { 1132 VIXL_STATIC_ASSERT( 1133 (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) || 1134 (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) || 1135 (sizeof(T) == kQRegSizeInBytes)); 1136 VIXL_ASSERT(code < kNumberOfVRegisters); 1137 1138 return vregisters_[code].Get<T>(); 1139 } 1140 template <typename T> 1141 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) { 1142 return ReadVRegister<T>(code); 1143 } 1144 1145 // Common specialized accessors for the vreg() template. 1146 int8_t ReadBRegister(unsigned code) const { 1147 return ReadVRegister<int8_t>(code); 1148 } 1149 VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) { 1150 return ReadBRegister(code); 1151 } 1152 1153 int16_t ReadHRegister(unsigned code) const { 1154 return ReadVRegister<int16_t>(code); 1155 } 1156 VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) { 1157 return ReadHRegister(code); 1158 } 1159 1160 float ReadSRegister(unsigned code) const { 1161 return ReadVRegister<float>(code); 1162 } 1163 VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) { 1164 return ReadSRegister(code); 1165 } 1166 1167 uint32_t ReadSRegisterBits(unsigned code) const { 1168 return ReadVRegister<uint32_t>(code); 1169 } 1170 VIXL_DEPRECATED("ReadSRegisterBits", 1171 uint32_t sreg_bits(unsigned code) const) { 1172 return ReadSRegisterBits(code); 1173 } 1174 1175 double ReadDRegister(unsigned code) const { 1176 return ReadVRegister<double>(code); 1177 } 1178 VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) { 1179 return ReadDRegister(code); 1180 } 1181 1182 uint64_t ReadDRegisterBits(unsigned code) const { 1183 return ReadVRegister<uint64_t>(code); 1184 } 1185 VIXL_DEPRECATED("ReadDRegisterBits", 1186 uint64_t dreg_bits(unsigned code) const) { 1187 return ReadDRegisterBits(code); 1188 } 1189 1190 qreg_t ReadQRegister(unsigned code) const { 1191 return ReadVRegister<qreg_t>(code); 1192 } 1193 VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) { 1194 return ReadQRegister(code); 1195 } 1196 1197 // As above, with parameterized size and return type. The value is 1198 // either zero-extended or truncated to fit, as required. 1199 template <typename T> 1200 T ReadVRegister(unsigned size, unsigned code) const { 1201 uint64_t raw = 0; 1202 T result; 1203 1204 switch (size) { 1205 case kSRegSize: 1206 raw = ReadVRegister<uint32_t>(code); 1207 break; 1208 case kDRegSize: 1209 raw = ReadVRegister<uint64_t>(code); 1210 break; 1211 default: 1212 VIXL_UNREACHABLE(); 1213 break; 1214 } 1215 1216 VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw)); 1217 // Copy the result and truncate to fit. This assumes a little-endian host. 1218 memcpy(&result, &raw, sizeof(result)); 1219 return result; 1220 } 1221 template <typename T> 1222 VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) { 1223 return ReadVRegister<T>(size, code); 1224 } 1225 1226 SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; } 1227 VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) { 1228 return ReadVRegister(code); 1229 } 1230 1231 // Basic accessor: Write the specified value. 1232 template <typename T> 1233 void WriteVRegister(unsigned code, 1234 T value, 1235 RegLogMode log_mode = LogRegWrites) { 1236 VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) || 1237 (sizeof(value) == kHRegSizeInBytes) || 1238 (sizeof(value) == kSRegSizeInBytes) || 1239 (sizeof(value) == kDRegSizeInBytes) || 1240 (sizeof(value) == kQRegSizeInBytes)); 1241 VIXL_ASSERT(code < kNumberOfVRegisters); 1242 vregisters_[code].Write(value); 1243 1244 if (log_mode == LogRegWrites) { 1245 LogVRegister(code, GetPrintRegisterFormat(value)); 1246 } 1247 } 1248 template <typename T> 1249 VIXL_DEPRECATED("WriteVRegister", 1250 void set_vreg(unsigned code, 1251 T value, 1252 RegLogMode log_mode = LogRegWrites)) { 1253 WriteVRegister(code, value, log_mode); 1254 } 1255 1256 // Common specialized accessors for the WriteVRegister() template. 1257 void WriteBRegister(unsigned code, 1258 int8_t value, 1259 RegLogMode log_mode = LogRegWrites) { 1260 WriteVRegister(code, value, log_mode); 1261 } 1262 VIXL_DEPRECATED("WriteBRegister", 1263 void set_breg(unsigned code, 1264 int8_t value, 1265 RegLogMode log_mode = LogRegWrites)) { 1266 return WriteBRegister(code, value, log_mode); 1267 } 1268 1269 void WriteHRegister(unsigned code, 1270 int16_t value, 1271 RegLogMode log_mode = LogRegWrites) { 1272 WriteVRegister(code, value, log_mode); 1273 } 1274 VIXL_DEPRECATED("WriteHRegister", 1275 void set_hreg(unsigned code, 1276 int16_t value, 1277 RegLogMode log_mode = LogRegWrites)) { 1278 return WriteHRegister(code, value, log_mode); 1279 } 1280 1281 void WriteSRegister(unsigned code, 1282 float value, 1283 RegLogMode log_mode = LogRegWrites) { 1284 WriteVRegister(code, value, log_mode); 1285 } 1286 VIXL_DEPRECATED("WriteSRegister", 1287 void set_sreg(unsigned code, 1288 float value, 1289 RegLogMode log_mode = LogRegWrites)) { 1290 WriteSRegister(code, value, log_mode); 1291 } 1292 1293 void WriteSRegisterBits(unsigned code, 1294 uint32_t value, 1295 RegLogMode log_mode = LogRegWrites) { 1296 WriteVRegister(code, value, log_mode); 1297 } 1298 VIXL_DEPRECATED("WriteSRegisterBits", 1299 void set_sreg_bits(unsigned code, 1300 uint32_t value, 1301 RegLogMode log_mode = LogRegWrites)) { 1302 WriteSRegisterBits(code, value, log_mode); 1303 } 1304 1305 void WriteDRegister(unsigned code, 1306 double value, 1307 RegLogMode log_mode = LogRegWrites) { 1308 WriteVRegister(code, value, log_mode); 1309 } 1310 VIXL_DEPRECATED("WriteDRegister", 1311 void set_dreg(unsigned code, 1312 double value, 1313 RegLogMode log_mode = LogRegWrites)) { 1314 WriteDRegister(code, value, log_mode); 1315 } 1316 1317 void WriteDRegisterBits(unsigned code, 1318 uint64_t value, 1319 RegLogMode log_mode = LogRegWrites) { 1320 WriteVRegister(code, value, log_mode); 1321 } 1322 VIXL_DEPRECATED("WriteDRegisterBits", 1323 void set_dreg_bits(unsigned code, 1324 uint64_t value, 1325 RegLogMode log_mode = LogRegWrites)) { 1326 WriteDRegisterBits(code, value, log_mode); 1327 } 1328 1329 void WriteQRegister(unsigned code, 1330 qreg_t value, 1331 RegLogMode log_mode = LogRegWrites) { 1332 WriteVRegister(code, value, log_mode); 1333 } 1334 VIXL_DEPRECATED("WriteQRegister", 1335 void set_qreg(unsigned code, 1336 qreg_t value, 1337 RegLogMode log_mode = LogRegWrites)) { 1338 WriteQRegister(code, value, log_mode); 1339 } 1340 1341 template <typename T> 1342 T ReadRegister(Register reg) const { 1343 return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister); 1344 } 1345 1346 template <typename T> 1347 void WriteRegister(Register reg, 1348 T value, 1349 RegLogMode log_mode = LogRegWrites) { 1350 WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister); 1351 } 1352 1353 template <typename T> 1354 T ReadVRegister(VRegister vreg) const { 1355 return ReadVRegister<T>(vreg.GetCode()); 1356 } 1357 1358 template <typename T> 1359 void WriteVRegister(VRegister vreg, 1360 T value, 1361 RegLogMode log_mode = LogRegWrites) { 1362 WriteVRegister<T>(vreg.GetCode(), value, log_mode); 1363 } 1364 1365 template <typename T> 1366 T ReadCPURegister(CPURegister reg) const { 1367 if (reg.IsVRegister()) { 1368 return ReadVRegister<T>(VRegister(reg)); 1369 } else { 1370 return ReadRegister<T>(Register(reg)); 1371 } 1372 } 1373 1374 template <typename T> 1375 void WriteCPURegister(CPURegister reg, 1376 T value, 1377 RegLogMode log_mode = LogRegWrites) { 1378 if (reg.IsVRegister()) { 1379 WriteVRegister<T>(VRegister(reg), value, log_mode); 1380 } else { 1381 WriteRegister<T>(Register(reg), value, log_mode); 1382 } 1383 } 1384 1385 uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const; 1386 1387 template <typename T> 1388 T ReadGenericOperand(GenericOperand operand) const { 1389 if (operand.IsCPURegister()) { 1390 return ReadCPURegister<T>(operand.GetCPURegister()); 1391 } else { 1392 VIXL_ASSERT(operand.IsMemOperand()); 1393 return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand())); 1394 } 1395 } 1396 1397 template <typename T> 1398 void WriteGenericOperand(GenericOperand operand, 1399 T value, 1400 RegLogMode log_mode = LogRegWrites) { 1401 if (operand.IsCPURegister()) { 1402 WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode); 1403 } else { 1404 VIXL_ASSERT(operand.IsMemOperand()); 1405 Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value); 1406 } 1407 } 1408 1409 bool ReadN() const { return nzcv_.GetN() != 0; } 1410 VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); } 1411 1412 bool ReadZ() const { return nzcv_.GetZ() != 0; } 1413 VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); } 1414 1415 bool ReadC() const { return nzcv_.GetC() != 0; } 1416 VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); } 1417 1418 bool ReadV() const { return nzcv_.GetV() != 0; } 1419 VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); } 1420 1421 SimSystemRegister& ReadNzcv() { return nzcv_; } 1422 VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); } 1423 1424 // TODO: Find a way to make the fpcr_ members return the proper types, so 1425 // these accessors are not necessary. 1426 FPRounding ReadRMode() const { 1427 return static_cast<FPRounding>(fpcr_.GetRMode()); 1428 } 1429 VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); } 1430 1431 bool ReadDN() const { return fpcr_.GetDN() != 0; } 1432 VIXL_DEPRECATED("ReadDN", bool DN()) { return ReadDN(); } 1433 1434 SimSystemRegister& ReadFpcr() { return fpcr_; } 1435 VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); } 1436 1437 // Specify relevant register formats for Print(V)Register and related helpers. 1438 enum PrintRegisterFormat { 1439 // The lane size. 1440 kPrintRegLaneSizeB = 0 << 0, 1441 kPrintRegLaneSizeH = 1 << 0, 1442 kPrintRegLaneSizeS = 2 << 0, 1443 kPrintRegLaneSizeW = kPrintRegLaneSizeS, 1444 kPrintRegLaneSizeD = 3 << 0, 1445 kPrintRegLaneSizeX = kPrintRegLaneSizeD, 1446 kPrintRegLaneSizeQ = 4 << 0, 1447 1448 kPrintRegLaneSizeOffset = 0, 1449 kPrintRegLaneSizeMask = 7 << 0, 1450 1451 // The lane count. 1452 kPrintRegAsScalar = 0, 1453 kPrintRegAsDVector = 1 << 3, 1454 kPrintRegAsQVector = 2 << 3, 1455 1456 kPrintRegAsVectorMask = 3 << 3, 1457 1458 // Indicate floating-point format lanes. (This flag is only supported for S- 1459 // and D-sized lanes.) 1460 kPrintRegAsFP = 1 << 5, 1461 1462 // Supported combinations. 1463 1464 kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar, 1465 kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar, 1466 kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, 1467 kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, 1468 1469 kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar, 1470 kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector, 1471 kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector, 1472 kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar, 1473 kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector, 1474 kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector, 1475 kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar, 1476 kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector, 1477 kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector, 1478 kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, 1479 kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP, 1480 kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP, 1481 kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar, 1482 kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector, 1483 kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, 1484 kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP, 1485 kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar 1486 }; 1487 1488 unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) { 1489 return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset; 1490 } 1491 1492 unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) { 1493 return 1 << GetPrintRegLaneSizeInBytesLog2(format); 1494 } 1495 1496 unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) { 1497 if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2; 1498 if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2; 1499 1500 // Scalar types. 1501 return GetPrintRegLaneSizeInBytesLog2(format); 1502 } 1503 1504 unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) { 1505 return 1 << GetPrintRegSizeInBytesLog2(format); 1506 } 1507 1508 unsigned GetPrintRegLaneCount(PrintRegisterFormat format) { 1509 unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format); 1510 unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format); 1511 VIXL_ASSERT(reg_size_log2 >= lane_size_log2); 1512 return 1 << (reg_size_log2 - lane_size_log2); 1513 } 1514 1515 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size, 1516 unsigned lane_size); 1517 1518 PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) { 1519 return GetPrintRegisterFormatForSize(size, size); 1520 } 1521 1522 PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) { 1523 switch (size) { 1524 default: 1525 VIXL_UNREACHABLE(); 1526 return kPrintDReg; 1527 case kDRegSizeInBytes: 1528 return kPrintDReg; 1529 case kSRegSizeInBytes: 1530 return kPrintSReg; 1531 } 1532 } 1533 1534 PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) { 1535 if ((GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) || 1536 (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) { 1537 return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP); 1538 } 1539 return format; 1540 } 1541 1542 template <typename T> 1543 PrintRegisterFormat GetPrintRegisterFormat(T value) { 1544 return GetPrintRegisterFormatForSize(sizeof(value)); 1545 } 1546 1547 PrintRegisterFormat GetPrintRegisterFormat(double value) { 1548 VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes); 1549 return GetPrintRegisterFormatForSizeFP(sizeof(value)); 1550 } 1551 1552 PrintRegisterFormat GetPrintRegisterFormat(float value) { 1553 VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes); 1554 return GetPrintRegisterFormatForSizeFP(sizeof(value)); 1555 } 1556 1557 PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform); 1558 PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform); 1559 1560 // Print all registers of the specified types. 1561 void PrintRegisters(); 1562 void PrintVRegisters(); 1563 void PrintSystemRegisters(); 1564 1565 // As above, but only print the registers that have been updated. 1566 void PrintWrittenRegisters(); 1567 void PrintWrittenVRegisters(); 1568 1569 // As above, but respect LOG_REG and LOG_VREG. 1570 void LogWrittenRegisters() { 1571 if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters(); 1572 } 1573 void LogWrittenVRegisters() { 1574 if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters(); 1575 } 1576 void LogAllWrittenRegisters() { 1577 LogWrittenRegisters(); 1578 LogWrittenVRegisters(); 1579 } 1580 1581 // Print individual register values (after update). 1582 void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer); 1583 void PrintVRegister(unsigned code, PrintRegisterFormat format); 1584 void PrintSystemRegister(SystemRegister id); 1585 void PrintTakenBranch(const Instruction* target); 1586 1587 // Like Print* (above), but respect GetTraceParameters(). 1588 void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) { 1589 if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode); 1590 } 1591 void LogVRegister(unsigned code, PrintRegisterFormat format) { 1592 if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format); 1593 } 1594 void LogSystemRegister(SystemRegister id) { 1595 if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id); 1596 } 1597 void LogTakenBranch(const Instruction* target) { 1598 if (GetTraceParameters() & LOG_BRANCH) PrintTakenBranch(target); 1599 } 1600 1601 // Print memory accesses. 1602 void PrintRead(uintptr_t address, 1603 unsigned reg_code, 1604 PrintRegisterFormat format); 1605 void PrintWrite(uintptr_t address, 1606 unsigned reg_code, 1607 PrintRegisterFormat format); 1608 void PrintVRead(uintptr_t address, 1609 unsigned reg_code, 1610 PrintRegisterFormat format, 1611 unsigned lane); 1612 void PrintVWrite(uintptr_t address, 1613 unsigned reg_code, 1614 PrintRegisterFormat format, 1615 unsigned lane); 1616 1617 // Like Print* (above), but respect GetTraceParameters(). 1618 void LogRead(uintptr_t address, 1619 unsigned reg_code, 1620 PrintRegisterFormat format) { 1621 if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format); 1622 } 1623 void LogWrite(uintptr_t address, 1624 unsigned reg_code, 1625 PrintRegisterFormat format) { 1626 if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format); 1627 } 1628 void LogVRead(uintptr_t address, 1629 unsigned reg_code, 1630 PrintRegisterFormat format, 1631 unsigned lane = 0) { 1632 if (GetTraceParameters() & LOG_VREGS) { 1633 PrintVRead(address, reg_code, format, lane); 1634 } 1635 } 1636 void LogVWrite(uintptr_t address, 1637 unsigned reg_code, 1638 PrintRegisterFormat format, 1639 unsigned lane = 0) { 1640 if (GetTraceParameters() & LOG_WRITE) { 1641 PrintVWrite(address, reg_code, format, lane); 1642 } 1643 } 1644 1645 // Helper functions for register tracing. 1646 void PrintRegisterRawHelper(unsigned code, 1647 Reg31Mode r31mode, 1648 int size_in_bytes = kXRegSizeInBytes); 1649 void PrintVRegisterRawHelper(unsigned code, 1650 int bytes = kQRegSizeInBytes, 1651 int lsb = 0); 1652 void PrintVRegisterFPHelper(unsigned code, 1653 unsigned lane_size_in_bytes, 1654 int lane_count = 1, 1655 int rightmost_lane = 0); 1656 1657 VIXL_NO_RETURN void DoUnreachable(const Instruction* instr); 1658 void DoTrace(const Instruction* instr); 1659 void DoLog(const Instruction* instr); 1660 1661 static const char* WRegNameForCode(unsigned code, 1662 Reg31Mode mode = Reg31IsZeroRegister); 1663 static const char* XRegNameForCode(unsigned code, 1664 Reg31Mode mode = Reg31IsZeroRegister); 1665 static const char* SRegNameForCode(unsigned code); 1666 static const char* DRegNameForCode(unsigned code); 1667 static const char* VRegNameForCode(unsigned code); 1668 1669 bool IsColouredTrace() const { return coloured_trace_; } 1670 VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) { 1671 return IsColouredTrace(); 1672 } 1673 1674 void SetColouredTrace(bool value); 1675 VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) { 1676 SetColouredTrace(value); 1677 } 1678 1679 // Values for traces parameters defined in simulator-constants-aarch64.h in 1680 // enum TraceParameters. 1681 int GetTraceParameters() const { return trace_parameters_; } 1682 VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) { 1683 return GetTraceParameters(); 1684 } 1685 1686 void SetTraceParameters(int parameters); 1687 VIXL_DEPRECATED("SetTraceParameters", 1688 void set_trace_parameters(int parameters)) { 1689 SetTraceParameters(parameters); 1690 } 1691 1692 void SetInstructionStats(bool value); 1693 VIXL_DEPRECATED("SetInstructionStats", 1694 void set_instruction_stats(bool value)) { 1695 SetInstructionStats(value); 1696 } 1697 1698 // Clear the simulated local monitor to force the next store-exclusive 1699 // instruction to fail. 1700 void ClearLocalMonitor() { local_monitor_.Clear(); } 1701 1702 void SilenceExclusiveAccessWarning() { 1703 print_exclusive_access_warning_ = false; 1704 } 1705 1706// Runtime call emulation support. 1707// It requires VIXL's ABI features, and C++11 or greater. 1708// Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect 1709// in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253 1710#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \ 1711 (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1)) 1712 1713#define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 1714 1715// The implementation of the runtime call helpers require the functionality 1716// provided by `std::index_sequence`. It is only available from C++14, but 1717// we want runtime call simulation to work from C++11, so we emulate if 1718// necessary. 1719#if __cplusplus >= 201402L 1720 template <std::size_t... I> 1721 using local_index_sequence = std::index_sequence<I...>; 1722 template <typename... P> 1723 using __local_index_sequence_for = std::index_sequence_for<P...>; 1724#else 1725 // Emulate the behaviour of `std::index_sequence` and 1726 // `std::index_sequence_for`. 1727 // Naming follow the `std` names, prefixed with `emulated_`. 1728 template <size_t... I> 1729 struct emulated_index_sequence {}; 1730 1731 // A recursive template to create a sequence of indexes. 1732 // The base case (for `N == 0`) is declared outside of the class scope, as 1733 // required by C++. 1734 template <std::size_t N, size_t... I> 1735 struct emulated_make_index_sequence_helper 1736 : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {}; 1737 1738 template <std::size_t N> 1739 struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> { 1740 }; 1741 1742 template <typename... P> 1743 struct emulated_index_sequence_for 1744 : emulated_make_index_sequence<sizeof...(P)> {}; 1745 1746 template <std::size_t... I> 1747 using local_index_sequence = emulated_index_sequence<I...>; 1748 template <typename... P> 1749 using __local_index_sequence_for = emulated_index_sequence_for<P...>; 1750#endif 1751 1752 // Expand the argument tuple and perform the call. 1753 template <typename R, typename... P, std::size_t... I> 1754 R DoRuntimeCall(R (*function)(P...), 1755 std::tuple<P...> arguments, 1756 local_index_sequence<I...>) { 1757 return function(std::get<I>(arguments)...); 1758 } 1759 1760 template <typename R, typename... P> 1761 void RuntimeCallNonVoid(R (*function)(P...)) { 1762 ABI abi; 1763 std::tuple<P...> argument_operands{ 1764 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1765 R return_value = DoRuntimeCall(function, 1766 argument_operands, 1767 __local_index_sequence_for<P...>{}); 1768 WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value); 1769 } 1770 1771 template <typename R, typename... P> 1772 void RuntimeCallVoid(R (*function)(P...)) { 1773 ABI abi; 1774 std::tuple<P...> argument_operands{ 1775 ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...}; 1776 DoRuntimeCall(function, 1777 argument_operands, 1778 __local_index_sequence_for<P...>{}); 1779 } 1780 1781 // We use `struct` for `void` return type specialisation. 1782 template <typename R, typename... P> 1783 struct RuntimeCallStructHelper { 1784 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) { 1785 R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer); 1786 simulator->RuntimeCallNonVoid(function); 1787 } 1788 }; 1789 1790 // Partial specialization when the return type is `void`. 1791 template <typename... P> 1792 struct RuntimeCallStructHelper<void, P...> { 1793 static void Wrapper(Simulator* simulator, uintptr_t function_pointer) { 1794 void (*function)(P...) = 1795 reinterpret_cast<void (*)(P...)>(function_pointer); 1796 simulator->RuntimeCallVoid(function); 1797 } 1798 }; 1799#endif 1800 1801 protected: 1802 const char* clr_normal; 1803 const char* clr_flag_name; 1804 const char* clr_flag_value; 1805 const char* clr_reg_name; 1806 const char* clr_reg_value; 1807 const char* clr_vreg_name; 1808 const char* clr_vreg_value; 1809 const char* clr_memory_address; 1810 const char* clr_warning; 1811 const char* clr_warning_message; 1812 const char* clr_printf; 1813 const char* clr_branch_marker; 1814 1815 // Simulation helpers ------------------------------------ 1816 bool ConditionPassed(Condition cond) { 1817 switch (cond) { 1818 case eq: 1819 return ReadZ(); 1820 case ne: 1821 return !ReadZ(); 1822 case hs: 1823 return ReadC(); 1824 case lo: 1825 return !ReadC(); 1826 case mi: 1827 return ReadN(); 1828 case pl: 1829 return !ReadN(); 1830 case vs: 1831 return ReadV(); 1832 case vc: 1833 return !ReadV(); 1834 case hi: 1835 return ReadC() && !ReadZ(); 1836 case ls: 1837 return !(ReadC() && !ReadZ()); 1838 case ge: 1839 return ReadN() == ReadV(); 1840 case lt: 1841 return ReadN() != ReadV(); 1842 case gt: 1843 return !ReadZ() && (ReadN() == ReadV()); 1844 case le: 1845 return !(!ReadZ() && (ReadN() == ReadV())); 1846 case nv: 1847 VIXL_FALLTHROUGH(); 1848 case al: 1849 return true; 1850 default: 1851 VIXL_UNREACHABLE(); 1852 return false; 1853 } 1854 } 1855 1856 bool ConditionPassed(Instr cond) { 1857 return ConditionPassed(static_cast<Condition>(cond)); 1858 } 1859 1860 bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); } 1861 1862 void AddSubHelper(const Instruction* instr, int64_t op2); 1863 uint64_t AddWithCarry(unsigned reg_size, 1864 bool set_flags, 1865 uint64_t left, 1866 uint64_t right, 1867 int carry_in = 0); 1868 void LogicalHelper(const Instruction* instr, int64_t op2); 1869 void ConditionalCompareHelper(const Instruction* instr, int64_t op2); 1870 void LoadStoreHelper(const Instruction* instr, 1871 int64_t offset, 1872 AddrMode addrmode); 1873 void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode); 1874 uintptr_t AddressModeHelper(unsigned addr_reg, 1875 int64_t offset, 1876 AddrMode addrmode); 1877 void NEONLoadStoreMultiStructHelper(const Instruction* instr, 1878 AddrMode addr_mode); 1879 void NEONLoadStoreSingleStructHelper(const Instruction* instr, 1880 AddrMode addr_mode); 1881 1882 uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; } 1883 1884 template <typename T> 1885 T* AddressUntag(T* address) { 1886 uintptr_t address_raw = reinterpret_cast<uintptr_t>(address); 1887 return reinterpret_cast<T*>(AddressUntag(address_raw)); 1888 } 1889 1890 int64_t ShiftOperand(unsigned reg_size, 1891 int64_t value, 1892 Shift shift_type, 1893 unsigned amount) const; 1894 int64_t ExtendValue(unsigned reg_width, 1895 int64_t value, 1896 Extend extend_type, 1897 unsigned left_shift = 0) const; 1898 uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const; 1899 1900 void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1901 void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr); 1902 void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr); 1903 void ld2(VectorFormat vform, 1904 LogicVRegister dst1, 1905 LogicVRegister dst2, 1906 uint64_t addr); 1907 void ld2(VectorFormat vform, 1908 LogicVRegister dst1, 1909 LogicVRegister dst2, 1910 int index, 1911 uint64_t addr); 1912 void ld2r(VectorFormat vform, 1913 LogicVRegister dst1, 1914 LogicVRegister dst2, 1915 uint64_t addr); 1916 void ld3(VectorFormat vform, 1917 LogicVRegister dst1, 1918 LogicVRegister dst2, 1919 LogicVRegister dst3, 1920 uint64_t addr); 1921 void ld3(VectorFormat vform, 1922 LogicVRegister dst1, 1923 LogicVRegister dst2, 1924 LogicVRegister dst3, 1925 int index, 1926 uint64_t addr); 1927 void ld3r(VectorFormat vform, 1928 LogicVRegister dst1, 1929 LogicVRegister dst2, 1930 LogicVRegister dst3, 1931 uint64_t addr); 1932 void ld4(VectorFormat vform, 1933 LogicVRegister dst1, 1934 LogicVRegister dst2, 1935 LogicVRegister dst3, 1936 LogicVRegister dst4, 1937 uint64_t addr); 1938 void ld4(VectorFormat vform, 1939 LogicVRegister dst1, 1940 LogicVRegister dst2, 1941 LogicVRegister dst3, 1942 LogicVRegister dst4, 1943 int index, 1944 uint64_t addr); 1945 void ld4r(VectorFormat vform, 1946 LogicVRegister dst1, 1947 LogicVRegister dst2, 1948 LogicVRegister dst3, 1949 LogicVRegister dst4, 1950 uint64_t addr); 1951 void st1(VectorFormat vform, LogicVRegister src, uint64_t addr); 1952 void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr); 1953 void st2(VectorFormat vform, 1954 LogicVRegister src, 1955 LogicVRegister src2, 1956 uint64_t addr); 1957 void st2(VectorFormat vform, 1958 LogicVRegister src, 1959 LogicVRegister src2, 1960 int index, 1961 uint64_t addr); 1962 void st3(VectorFormat vform, 1963 LogicVRegister src, 1964 LogicVRegister src2, 1965 LogicVRegister src3, 1966 uint64_t addr); 1967 void st3(VectorFormat vform, 1968 LogicVRegister src, 1969 LogicVRegister src2, 1970 LogicVRegister src3, 1971 int index, 1972 uint64_t addr); 1973 void st4(VectorFormat vform, 1974 LogicVRegister src, 1975 LogicVRegister src2, 1976 LogicVRegister src3, 1977 LogicVRegister src4, 1978 uint64_t addr); 1979 void st4(VectorFormat vform, 1980 LogicVRegister src, 1981 LogicVRegister src2, 1982 LogicVRegister src3, 1983 LogicVRegister src4, 1984 int index, 1985 uint64_t addr); 1986 LogicVRegister cmp(VectorFormat vform, 1987 LogicVRegister dst, 1988 const LogicVRegister& src1, 1989 const LogicVRegister& src2, 1990 Condition cond); 1991 LogicVRegister cmp(VectorFormat vform, 1992 LogicVRegister dst, 1993 const LogicVRegister& src1, 1994 int imm, 1995 Condition cond); 1996 LogicVRegister cmptst(VectorFormat vform, 1997 LogicVRegister dst, 1998 const LogicVRegister& src1, 1999 const LogicVRegister& src2); 2000 LogicVRegister add(VectorFormat vform, 2001 LogicVRegister dst, 2002 const LogicVRegister& src1, 2003 const LogicVRegister& src2); 2004 LogicVRegister addp(VectorFormat vform, 2005 LogicVRegister dst, 2006 const LogicVRegister& src1, 2007 const LogicVRegister& src2); 2008 LogicVRegister mla(VectorFormat vform, 2009 LogicVRegister dst, 2010 const LogicVRegister& src1, 2011 const LogicVRegister& src2); 2012 LogicVRegister mls(VectorFormat vform, 2013 LogicVRegister dst, 2014 const LogicVRegister& src1, 2015 const LogicVRegister& src2); 2016 LogicVRegister mul(VectorFormat vform, 2017 LogicVRegister dst, 2018 const LogicVRegister& src1, 2019 const LogicVRegister& src2); 2020 LogicVRegister mul(VectorFormat vform, 2021 LogicVRegister dst, 2022 const LogicVRegister& src1, 2023 const LogicVRegister& src2, 2024 int index); 2025 LogicVRegister mla(VectorFormat vform, 2026 LogicVRegister dst, 2027 const LogicVRegister& src1, 2028 const LogicVRegister& src2, 2029 int index); 2030 LogicVRegister mls(VectorFormat vform, 2031 LogicVRegister dst, 2032 const LogicVRegister& src1, 2033 const LogicVRegister& src2, 2034 int index); 2035 LogicVRegister pmul(VectorFormat vform, 2036 LogicVRegister dst, 2037 const LogicVRegister& src1, 2038 const LogicVRegister& src2); 2039 2040 typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform, 2041 LogicVRegister dst, 2042 const LogicVRegister& src1, 2043 const LogicVRegister& src2, 2044 int index); 2045 LogicVRegister fmul(VectorFormat vform, 2046 LogicVRegister dst, 2047 const LogicVRegister& src1, 2048 const LogicVRegister& src2, 2049 int index); 2050 LogicVRegister fmla(VectorFormat vform, 2051 LogicVRegister dst, 2052 const LogicVRegister& src1, 2053 const LogicVRegister& src2, 2054 int index); 2055 LogicVRegister fmls(VectorFormat vform, 2056 LogicVRegister dst, 2057 const LogicVRegister& src1, 2058 const LogicVRegister& src2, 2059 int index); 2060 LogicVRegister fmulx(VectorFormat vform, 2061 LogicVRegister dst, 2062 const LogicVRegister& src1, 2063 const LogicVRegister& src2, 2064 int index); 2065 LogicVRegister smull(VectorFormat vform, 2066 LogicVRegister dst, 2067 const LogicVRegister& src1, 2068 const LogicVRegister& src2, 2069 int index); 2070 LogicVRegister smull2(VectorFormat vform, 2071 LogicVRegister dst, 2072 const LogicVRegister& src1, 2073 const LogicVRegister& src2, 2074 int index); 2075 LogicVRegister umull(VectorFormat vform, 2076 LogicVRegister dst, 2077 const LogicVRegister& src1, 2078 const LogicVRegister& src2, 2079 int index); 2080 LogicVRegister umull2(VectorFormat vform, 2081 LogicVRegister dst, 2082 const LogicVRegister& src1, 2083 const LogicVRegister& src2, 2084 int index); 2085 LogicVRegister smlal(VectorFormat vform, 2086 LogicVRegister dst, 2087 const LogicVRegister& src1, 2088 const LogicVRegister& src2, 2089 int index); 2090 LogicVRegister smlal2(VectorFormat vform, 2091 LogicVRegister dst, 2092 const LogicVRegister& src1, 2093 const LogicVRegister& src2, 2094 int index); 2095 LogicVRegister umlal(VectorFormat vform, 2096 LogicVRegister dst, 2097 const LogicVRegister& src1, 2098 const LogicVRegister& src2, 2099 int index); 2100 LogicVRegister umlal2(VectorFormat vform, 2101 LogicVRegister dst, 2102 const LogicVRegister& src1, 2103 const LogicVRegister& src2, 2104 int index); 2105 LogicVRegister smlsl(VectorFormat vform, 2106 LogicVRegister dst, 2107 const LogicVRegister& src1, 2108 const LogicVRegister& src2, 2109 int index); 2110 LogicVRegister smlsl2(VectorFormat vform, 2111 LogicVRegister dst, 2112 const LogicVRegister& src1, 2113 const LogicVRegister& src2, 2114 int index); 2115 LogicVRegister umlsl(VectorFormat vform, 2116 LogicVRegister dst, 2117 const LogicVRegister& src1, 2118 const LogicVRegister& src2, 2119 int index); 2120 LogicVRegister umlsl2(VectorFormat vform, 2121 LogicVRegister dst, 2122 const LogicVRegister& src1, 2123 const LogicVRegister& src2, 2124 int index); 2125 LogicVRegister sqdmull(VectorFormat vform, 2126 LogicVRegister dst, 2127 const LogicVRegister& src1, 2128 const LogicVRegister& src2, 2129 int index); 2130 LogicVRegister sqdmull2(VectorFormat vform, 2131 LogicVRegister dst, 2132 const LogicVRegister& src1, 2133 const LogicVRegister& src2, 2134 int index); 2135 LogicVRegister sqdmlal(VectorFormat vform, 2136 LogicVRegister dst, 2137 const LogicVRegister& src1, 2138 const LogicVRegister& src2, 2139 int index); 2140 LogicVRegister sqdmlal2(VectorFormat vform, 2141 LogicVRegister dst, 2142 const LogicVRegister& src1, 2143 const LogicVRegister& src2, 2144 int index); 2145 LogicVRegister sqdmlsl(VectorFormat vform, 2146 LogicVRegister dst, 2147 const LogicVRegister& src1, 2148 const LogicVRegister& src2, 2149 int index); 2150 LogicVRegister sqdmlsl2(VectorFormat vform, 2151 LogicVRegister dst, 2152 const LogicVRegister& src1, 2153 const LogicVRegister& src2, 2154 int index); 2155 LogicVRegister sqdmulh(VectorFormat vform, 2156 LogicVRegister dst, 2157 const LogicVRegister& src1, 2158 const LogicVRegister& src2, 2159 int index); 2160 LogicVRegister sqrdmulh(VectorFormat vform, 2161 LogicVRegister dst, 2162 const LogicVRegister& src1, 2163 const LogicVRegister& src2, 2164 int index); 2165 LogicVRegister sub(VectorFormat vform, 2166 LogicVRegister dst, 2167 const LogicVRegister& src1, 2168 const LogicVRegister& src2); 2169 LogicVRegister and_(VectorFormat vform, 2170 LogicVRegister dst, 2171 const LogicVRegister& src1, 2172 const LogicVRegister& src2); 2173 LogicVRegister orr(VectorFormat vform, 2174 LogicVRegister dst, 2175 const LogicVRegister& src1, 2176 const LogicVRegister& src2); 2177 LogicVRegister orn(VectorFormat vform, 2178 LogicVRegister dst, 2179 const LogicVRegister& src1, 2180 const LogicVRegister& src2); 2181 LogicVRegister eor(VectorFormat vform, 2182 LogicVRegister dst, 2183 const LogicVRegister& src1, 2184 const LogicVRegister& src2); 2185 LogicVRegister bic(VectorFormat vform, 2186 LogicVRegister dst, 2187 const LogicVRegister& src1, 2188 const LogicVRegister& src2); 2189 LogicVRegister bic(VectorFormat vform, 2190 LogicVRegister dst, 2191 const LogicVRegister& src, 2192 uint64_t imm); 2193 LogicVRegister bif(VectorFormat vform, 2194 LogicVRegister dst, 2195 const LogicVRegister& src1, 2196 const LogicVRegister& src2); 2197 LogicVRegister bit(VectorFormat vform, 2198 LogicVRegister dst, 2199 const LogicVRegister& src1, 2200 const LogicVRegister& src2); 2201 LogicVRegister bsl(VectorFormat vform, 2202 LogicVRegister dst, 2203 const LogicVRegister& src1, 2204 const LogicVRegister& src2); 2205 LogicVRegister cls(VectorFormat vform, 2206 LogicVRegister dst, 2207 const LogicVRegister& src); 2208 LogicVRegister clz(VectorFormat vform, 2209 LogicVRegister dst, 2210 const LogicVRegister& src); 2211 LogicVRegister cnt(VectorFormat vform, 2212 LogicVRegister dst, 2213 const LogicVRegister& src); 2214 LogicVRegister not_(VectorFormat vform, 2215 LogicVRegister dst, 2216 const LogicVRegister& src); 2217 LogicVRegister rbit(VectorFormat vform, 2218 LogicVRegister dst, 2219 const LogicVRegister& src); 2220 LogicVRegister rev(VectorFormat vform, 2221 LogicVRegister dst, 2222 const LogicVRegister& src, 2223 int revSize); 2224 LogicVRegister rev16(VectorFormat vform, 2225 LogicVRegister dst, 2226 const LogicVRegister& src); 2227 LogicVRegister rev32(VectorFormat vform, 2228 LogicVRegister dst, 2229 const LogicVRegister& src); 2230 LogicVRegister rev64(VectorFormat vform, 2231 LogicVRegister dst, 2232 const LogicVRegister& src); 2233 LogicVRegister addlp(VectorFormat vform, 2234 LogicVRegister dst, 2235 const LogicVRegister& src, 2236 bool is_signed, 2237 bool do_accumulate); 2238 LogicVRegister saddlp(VectorFormat vform, 2239 LogicVRegister dst, 2240 const LogicVRegister& src); 2241 LogicVRegister uaddlp(VectorFormat vform, 2242 LogicVRegister dst, 2243 const LogicVRegister& src); 2244 LogicVRegister sadalp(VectorFormat vform, 2245 LogicVRegister dst, 2246 const LogicVRegister& src); 2247 LogicVRegister uadalp(VectorFormat vform, 2248 LogicVRegister dst, 2249 const LogicVRegister& src); 2250 LogicVRegister ext(VectorFormat vform, 2251 LogicVRegister dst, 2252 const LogicVRegister& src1, 2253 const LogicVRegister& src2, 2254 int index); 2255 LogicVRegister ins_element(VectorFormat vform, 2256 LogicVRegister dst, 2257 int dst_index, 2258 const LogicVRegister& src, 2259 int src_index); 2260 LogicVRegister ins_immediate(VectorFormat vform, 2261 LogicVRegister dst, 2262 int dst_index, 2263 uint64_t imm); 2264 LogicVRegister dup_element(VectorFormat vform, 2265 LogicVRegister dst, 2266 const LogicVRegister& src, 2267 int src_index); 2268 LogicVRegister dup_immediate(VectorFormat vform, 2269 LogicVRegister dst, 2270 uint64_t imm); 2271 LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2272 LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm); 2273 LogicVRegister orr(VectorFormat vform, 2274 LogicVRegister dst, 2275 const LogicVRegister& src, 2276 uint64_t imm); 2277 LogicVRegister sshl(VectorFormat vform, 2278 LogicVRegister dst, 2279 const LogicVRegister& src1, 2280 const LogicVRegister& src2); 2281 LogicVRegister ushl(VectorFormat vform, 2282 LogicVRegister dst, 2283 const LogicVRegister& src1, 2284 const LogicVRegister& src2); 2285 LogicVRegister sminmax(VectorFormat vform, 2286 LogicVRegister dst, 2287 const LogicVRegister& src1, 2288 const LogicVRegister& src2, 2289 bool max); 2290 LogicVRegister smax(VectorFormat vform, 2291 LogicVRegister dst, 2292 const LogicVRegister& src1, 2293 const LogicVRegister& src2); 2294 LogicVRegister smin(VectorFormat vform, 2295 LogicVRegister dst, 2296 const LogicVRegister& src1, 2297 const LogicVRegister& src2); 2298 LogicVRegister sminmaxp(VectorFormat vform, 2299 LogicVRegister dst, 2300 const LogicVRegister& src1, 2301 const LogicVRegister& src2, 2302 bool max); 2303 LogicVRegister smaxp(VectorFormat vform, 2304 LogicVRegister dst, 2305 const LogicVRegister& src1, 2306 const LogicVRegister& src2); 2307 LogicVRegister sminp(VectorFormat vform, 2308 LogicVRegister dst, 2309 const LogicVRegister& src1, 2310 const LogicVRegister& src2); 2311 LogicVRegister addp(VectorFormat vform, 2312 LogicVRegister dst, 2313 const LogicVRegister& src); 2314 LogicVRegister addv(VectorFormat vform, 2315 LogicVRegister dst, 2316 const LogicVRegister& src); 2317 LogicVRegister uaddlv(VectorFormat vform, 2318 LogicVRegister dst, 2319 const LogicVRegister& src); 2320 LogicVRegister saddlv(VectorFormat vform, 2321 LogicVRegister dst, 2322 const LogicVRegister& src); 2323 LogicVRegister sminmaxv(VectorFormat vform, 2324 LogicVRegister dst, 2325 const LogicVRegister& src, 2326 bool max); 2327 LogicVRegister smaxv(VectorFormat vform, 2328 LogicVRegister dst, 2329 const LogicVRegister& src); 2330 LogicVRegister sminv(VectorFormat vform, 2331 LogicVRegister dst, 2332 const LogicVRegister& src); 2333 LogicVRegister uxtl(VectorFormat vform, 2334 LogicVRegister dst, 2335 const LogicVRegister& src); 2336 LogicVRegister uxtl2(VectorFormat vform, 2337 LogicVRegister dst, 2338 const LogicVRegister& src); 2339 LogicVRegister sxtl(VectorFormat vform, 2340 LogicVRegister dst, 2341 const LogicVRegister& src); 2342 LogicVRegister sxtl2(VectorFormat vform, 2343 LogicVRegister dst, 2344 const LogicVRegister& src); 2345 LogicVRegister tbl(VectorFormat vform, 2346 LogicVRegister dst, 2347 const LogicVRegister& tab, 2348 const LogicVRegister& ind); 2349 LogicVRegister tbl(VectorFormat vform, 2350 LogicVRegister dst, 2351 const LogicVRegister& tab, 2352 const LogicVRegister& tab2, 2353 const LogicVRegister& ind); 2354 LogicVRegister tbl(VectorFormat vform, 2355 LogicVRegister dst, 2356 const LogicVRegister& tab, 2357 const LogicVRegister& tab2, 2358 const LogicVRegister& tab3, 2359 const LogicVRegister& ind); 2360 LogicVRegister tbl(VectorFormat vform, 2361 LogicVRegister dst, 2362 const LogicVRegister& tab, 2363 const LogicVRegister& tab2, 2364 const LogicVRegister& tab3, 2365 const LogicVRegister& tab4, 2366 const LogicVRegister& ind); 2367 LogicVRegister Table(VectorFormat vform, 2368 LogicVRegister dst, 2369 const LogicVRegister& ind, 2370 bool zero_out_of_bounds, 2371 const LogicVRegister* tab1, 2372 const LogicVRegister* tab2 = NULL, 2373 const LogicVRegister* tab3 = NULL, 2374 const LogicVRegister* tab4 = NULL); 2375 LogicVRegister tbx(VectorFormat vform, 2376 LogicVRegister dst, 2377 const LogicVRegister& tab, 2378 const LogicVRegister& ind); 2379 LogicVRegister tbx(VectorFormat vform, 2380 LogicVRegister dst, 2381 const LogicVRegister& tab, 2382 const LogicVRegister& tab2, 2383 const LogicVRegister& ind); 2384 LogicVRegister tbx(VectorFormat vform, 2385 LogicVRegister dst, 2386 const LogicVRegister& tab, 2387 const LogicVRegister& tab2, 2388 const LogicVRegister& tab3, 2389 const LogicVRegister& ind); 2390 LogicVRegister tbx(VectorFormat vform, 2391 LogicVRegister dst, 2392 const LogicVRegister& tab, 2393 const LogicVRegister& tab2, 2394 const LogicVRegister& tab3, 2395 const LogicVRegister& tab4, 2396 const LogicVRegister& ind); 2397 LogicVRegister uaddl(VectorFormat vform, 2398 LogicVRegister dst, 2399 const LogicVRegister& src1, 2400 const LogicVRegister& src2); 2401 LogicVRegister uaddl2(VectorFormat vform, 2402 LogicVRegister dst, 2403 const LogicVRegister& src1, 2404 const LogicVRegister& src2); 2405 LogicVRegister uaddw(VectorFormat vform, 2406 LogicVRegister dst, 2407 const LogicVRegister& src1, 2408 const LogicVRegister& src2); 2409 LogicVRegister uaddw2(VectorFormat vform, 2410 LogicVRegister dst, 2411 const LogicVRegister& src1, 2412 const LogicVRegister& src2); 2413 LogicVRegister saddl(VectorFormat vform, 2414 LogicVRegister dst, 2415 const LogicVRegister& src1, 2416 const LogicVRegister& src2); 2417 LogicVRegister saddl2(VectorFormat vform, 2418 LogicVRegister dst, 2419 const LogicVRegister& src1, 2420 const LogicVRegister& src2); 2421 LogicVRegister saddw(VectorFormat vform, 2422 LogicVRegister dst, 2423 const LogicVRegister& src1, 2424 const LogicVRegister& src2); 2425 LogicVRegister saddw2(VectorFormat vform, 2426 LogicVRegister dst, 2427 const LogicVRegister& src1, 2428 const LogicVRegister& src2); 2429 LogicVRegister usubl(VectorFormat vform, 2430 LogicVRegister dst, 2431 const LogicVRegister& src1, 2432 const LogicVRegister& src2); 2433 LogicVRegister usubl2(VectorFormat vform, 2434 LogicVRegister dst, 2435 const LogicVRegister& src1, 2436 const LogicVRegister& src2); 2437 LogicVRegister usubw(VectorFormat vform, 2438 LogicVRegister dst, 2439 const LogicVRegister& src1, 2440 const LogicVRegister& src2); 2441 LogicVRegister usubw2(VectorFormat vform, 2442 LogicVRegister dst, 2443 const LogicVRegister& src1, 2444 const LogicVRegister& src2); 2445 LogicVRegister ssubl(VectorFormat vform, 2446 LogicVRegister dst, 2447 const LogicVRegister& src1, 2448 const LogicVRegister& src2); 2449 LogicVRegister ssubl2(VectorFormat vform, 2450 LogicVRegister dst, 2451 const LogicVRegister& src1, 2452 const LogicVRegister& src2); 2453 LogicVRegister ssubw(VectorFormat vform, 2454 LogicVRegister dst, 2455 const LogicVRegister& src1, 2456 const LogicVRegister& src2); 2457 LogicVRegister ssubw2(VectorFormat vform, 2458 LogicVRegister dst, 2459 const LogicVRegister& src1, 2460 const LogicVRegister& src2); 2461 LogicVRegister uminmax(VectorFormat vform, 2462 LogicVRegister dst, 2463 const LogicVRegister& src1, 2464 const LogicVRegister& src2, 2465 bool max); 2466 LogicVRegister umax(VectorFormat vform, 2467 LogicVRegister dst, 2468 const LogicVRegister& src1, 2469 const LogicVRegister& src2); 2470 LogicVRegister umin(VectorFormat vform, 2471 LogicVRegister dst, 2472 const LogicVRegister& src1, 2473 const LogicVRegister& src2); 2474 LogicVRegister uminmaxp(VectorFormat vform, 2475 LogicVRegister dst, 2476 const LogicVRegister& src1, 2477 const LogicVRegister& src2, 2478 bool max); 2479 LogicVRegister umaxp(VectorFormat vform, 2480 LogicVRegister dst, 2481 const LogicVRegister& src1, 2482 const LogicVRegister& src2); 2483 LogicVRegister uminp(VectorFormat vform, 2484 LogicVRegister dst, 2485 const LogicVRegister& src1, 2486 const LogicVRegister& src2); 2487 LogicVRegister uminmaxv(VectorFormat vform, 2488 LogicVRegister dst, 2489 const LogicVRegister& src, 2490 bool max); 2491 LogicVRegister umaxv(VectorFormat vform, 2492 LogicVRegister dst, 2493 const LogicVRegister& src); 2494 LogicVRegister uminv(VectorFormat vform, 2495 LogicVRegister dst, 2496 const LogicVRegister& src); 2497 LogicVRegister trn1(VectorFormat vform, 2498 LogicVRegister dst, 2499 const LogicVRegister& src1, 2500 const LogicVRegister& src2); 2501 LogicVRegister trn2(VectorFormat vform, 2502 LogicVRegister dst, 2503 const LogicVRegister& src1, 2504 const LogicVRegister& src2); 2505 LogicVRegister zip1(VectorFormat vform, 2506 LogicVRegister dst, 2507 const LogicVRegister& src1, 2508 const LogicVRegister& src2); 2509 LogicVRegister zip2(VectorFormat vform, 2510 LogicVRegister dst, 2511 const LogicVRegister& src1, 2512 const LogicVRegister& src2); 2513 LogicVRegister uzp1(VectorFormat vform, 2514 LogicVRegister dst, 2515 const LogicVRegister& src1, 2516 const LogicVRegister& src2); 2517 LogicVRegister uzp2(VectorFormat vform, 2518 LogicVRegister dst, 2519 const LogicVRegister& src1, 2520 const LogicVRegister& src2); 2521 LogicVRegister shl(VectorFormat vform, 2522 LogicVRegister dst, 2523 const LogicVRegister& src, 2524 int shift); 2525 LogicVRegister scvtf(VectorFormat vform, 2526 LogicVRegister dst, 2527 const LogicVRegister& src, 2528 int fbits, 2529 FPRounding rounding_mode); 2530 LogicVRegister ucvtf(VectorFormat vform, 2531 LogicVRegister dst, 2532 const LogicVRegister& src, 2533 int fbits, 2534 FPRounding rounding_mode); 2535 LogicVRegister sshll(VectorFormat vform, 2536 LogicVRegister dst, 2537 const LogicVRegister& src, 2538 int shift); 2539 LogicVRegister sshll2(VectorFormat vform, 2540 LogicVRegister dst, 2541 const LogicVRegister& src, 2542 int shift); 2543 LogicVRegister shll(VectorFormat vform, 2544 LogicVRegister dst, 2545 const LogicVRegister& src); 2546 LogicVRegister shll2(VectorFormat vform, 2547 LogicVRegister dst, 2548 const LogicVRegister& src); 2549 LogicVRegister ushll(VectorFormat vform, 2550 LogicVRegister dst, 2551 const LogicVRegister& src, 2552 int shift); 2553 LogicVRegister ushll2(VectorFormat vform, 2554 LogicVRegister dst, 2555 const LogicVRegister& src, 2556 int shift); 2557 LogicVRegister sli(VectorFormat vform, 2558 LogicVRegister dst, 2559 const LogicVRegister& src, 2560 int shift); 2561 LogicVRegister sri(VectorFormat vform, 2562 LogicVRegister dst, 2563 const LogicVRegister& src, 2564 int shift); 2565 LogicVRegister sshr(VectorFormat vform, 2566 LogicVRegister dst, 2567 const LogicVRegister& src, 2568 int shift); 2569 LogicVRegister ushr(VectorFormat vform, 2570 LogicVRegister dst, 2571 const LogicVRegister& src, 2572 int shift); 2573 LogicVRegister ssra(VectorFormat vform, 2574 LogicVRegister dst, 2575 const LogicVRegister& src, 2576 int shift); 2577 LogicVRegister usra(VectorFormat vform, 2578 LogicVRegister dst, 2579 const LogicVRegister& src, 2580 int shift); 2581 LogicVRegister srsra(VectorFormat vform, 2582 LogicVRegister dst, 2583 const LogicVRegister& src, 2584 int shift); 2585 LogicVRegister ursra(VectorFormat vform, 2586 LogicVRegister dst, 2587 const LogicVRegister& src, 2588 int shift); 2589 LogicVRegister suqadd(VectorFormat vform, 2590 LogicVRegister dst, 2591 const LogicVRegister& src); 2592 LogicVRegister usqadd(VectorFormat vform, 2593 LogicVRegister dst, 2594 const LogicVRegister& src); 2595 LogicVRegister sqshl(VectorFormat vform, 2596 LogicVRegister dst, 2597 const LogicVRegister& src, 2598 int shift); 2599 LogicVRegister uqshl(VectorFormat vform, 2600 LogicVRegister dst, 2601 const LogicVRegister& src, 2602 int shift); 2603 LogicVRegister sqshlu(VectorFormat vform, 2604 LogicVRegister dst, 2605 const LogicVRegister& src, 2606 int shift); 2607 LogicVRegister abs(VectorFormat vform, 2608 LogicVRegister dst, 2609 const LogicVRegister& src); 2610 LogicVRegister neg(VectorFormat vform, 2611 LogicVRegister dst, 2612 const LogicVRegister& src); 2613 LogicVRegister extractnarrow(VectorFormat vform, 2614 LogicVRegister dst, 2615 bool dstIsSigned, 2616 const LogicVRegister& src, 2617 bool srcIsSigned); 2618 LogicVRegister xtn(VectorFormat vform, 2619 LogicVRegister dst, 2620 const LogicVRegister& src); 2621 LogicVRegister sqxtn(VectorFormat vform, 2622 LogicVRegister dst, 2623 const LogicVRegister& src); 2624 LogicVRegister uqxtn(VectorFormat vform, 2625 LogicVRegister dst, 2626 const LogicVRegister& src); 2627 LogicVRegister sqxtun(VectorFormat vform, 2628 LogicVRegister dst, 2629 const LogicVRegister& src); 2630 LogicVRegister absdiff(VectorFormat vform, 2631 LogicVRegister dst, 2632 const LogicVRegister& src1, 2633 const LogicVRegister& src2, 2634 bool issigned); 2635 LogicVRegister saba(VectorFormat vform, 2636 LogicVRegister dst, 2637 const LogicVRegister& src1, 2638 const LogicVRegister& src2); 2639 LogicVRegister uaba(VectorFormat vform, 2640 LogicVRegister dst, 2641 const LogicVRegister& src1, 2642 const LogicVRegister& src2); 2643 LogicVRegister shrn(VectorFormat vform, 2644 LogicVRegister dst, 2645 const LogicVRegister& src, 2646 int shift); 2647 LogicVRegister shrn2(VectorFormat vform, 2648 LogicVRegister dst, 2649 const LogicVRegister& src, 2650 int shift); 2651 LogicVRegister rshrn(VectorFormat vform, 2652 LogicVRegister dst, 2653 const LogicVRegister& src, 2654 int shift); 2655 LogicVRegister rshrn2(VectorFormat vform, 2656 LogicVRegister dst, 2657 const LogicVRegister& src, 2658 int shift); 2659 LogicVRegister uqshrn(VectorFormat vform, 2660 LogicVRegister dst, 2661 const LogicVRegister& src, 2662 int shift); 2663 LogicVRegister uqshrn2(VectorFormat vform, 2664 LogicVRegister dst, 2665 const LogicVRegister& src, 2666 int shift); 2667 LogicVRegister uqrshrn(VectorFormat vform, 2668 LogicVRegister dst, 2669 const LogicVRegister& src, 2670 int shift); 2671 LogicVRegister uqrshrn2(VectorFormat vform, 2672 LogicVRegister dst, 2673 const LogicVRegister& src, 2674 int shift); 2675 LogicVRegister sqshrn(VectorFormat vform, 2676 LogicVRegister dst, 2677 const LogicVRegister& src, 2678 int shift); 2679 LogicVRegister sqshrn2(VectorFormat vform, 2680 LogicVRegister dst, 2681 const LogicVRegister& src, 2682 int shift); 2683 LogicVRegister sqrshrn(VectorFormat vform, 2684 LogicVRegister dst, 2685 const LogicVRegister& src, 2686 int shift); 2687 LogicVRegister sqrshrn2(VectorFormat vform, 2688 LogicVRegister dst, 2689 const LogicVRegister& src, 2690 int shift); 2691 LogicVRegister sqshrun(VectorFormat vform, 2692 LogicVRegister dst, 2693 const LogicVRegister& src, 2694 int shift); 2695 LogicVRegister sqshrun2(VectorFormat vform, 2696 LogicVRegister dst, 2697 const LogicVRegister& src, 2698 int shift); 2699 LogicVRegister sqrshrun(VectorFormat vform, 2700 LogicVRegister dst, 2701 const LogicVRegister& src, 2702 int shift); 2703 LogicVRegister sqrshrun2(VectorFormat vform, 2704 LogicVRegister dst, 2705 const LogicVRegister& src, 2706 int shift); 2707 LogicVRegister sqrdmulh(VectorFormat vform, 2708 LogicVRegister dst, 2709 const LogicVRegister& src1, 2710 const LogicVRegister& src2, 2711 bool round = true); 2712 LogicVRegister sqdmulh(VectorFormat vform, 2713 LogicVRegister dst, 2714 const LogicVRegister& src1, 2715 const LogicVRegister& src2); 2716#define NEON_3VREG_LOGIC_LIST(V) \ 2717 V(addhn) \ 2718 V(addhn2) \ 2719 V(raddhn) \ 2720 V(raddhn2) \ 2721 V(subhn) \ 2722 V(subhn2) \ 2723 V(rsubhn) \ 2724 V(rsubhn2) \ 2725 V(pmull) \ 2726 V(pmull2) \ 2727 V(sabal) \ 2728 V(sabal2) \ 2729 V(uabal) \ 2730 V(uabal2) \ 2731 V(sabdl) \ 2732 V(sabdl2) \ 2733 V(uabdl) \ 2734 V(uabdl2) \ 2735 V(smull) \ 2736 V(smull2) \ 2737 V(umull) \ 2738 V(umull2) \ 2739 V(smlal) \ 2740 V(smlal2) \ 2741 V(umlal) \ 2742 V(umlal2) \ 2743 V(smlsl) \ 2744 V(smlsl2) \ 2745 V(umlsl) \ 2746 V(umlsl2) \ 2747 V(sqdmlal) \ 2748 V(sqdmlal2) \ 2749 V(sqdmlsl) \ 2750 V(sqdmlsl2) \ 2751 V(sqdmull) \ 2752 V(sqdmull2) 2753 2754#define DEFINE_LOGIC_FUNC(FXN) \ 2755 LogicVRegister FXN(VectorFormat vform, \ 2756 LogicVRegister dst, \ 2757 const LogicVRegister& src1, \ 2758 const LogicVRegister& src2); 2759 NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC) 2760#undef DEFINE_LOGIC_FUNC 2761 2762#define NEON_FP3SAME_LIST(V) \ 2763 V(fadd, FPAdd, false) \ 2764 V(fsub, FPSub, true) \ 2765 V(fmul, FPMul, true) \ 2766 V(fmulx, FPMulx, true) \ 2767 V(fdiv, FPDiv, true) \ 2768 V(fmax, FPMax, false) \ 2769 V(fmin, FPMin, false) \ 2770 V(fmaxnm, FPMaxNM, false) \ 2771 V(fminnm, FPMinNM, false) 2772 2773#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \ 2774 template <typename T> \ 2775 LogicVRegister FN(VectorFormat vform, \ 2776 LogicVRegister dst, \ 2777 const LogicVRegister& src1, \ 2778 const LogicVRegister& src2); \ 2779 LogicVRegister FN(VectorFormat vform, \ 2780 LogicVRegister dst, \ 2781 const LogicVRegister& src1, \ 2782 const LogicVRegister& src2); 2783 NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP) 2784#undef DECLARE_NEON_FP_VECTOR_OP 2785 2786#define NEON_FPPAIRWISE_LIST(V) \ 2787 V(faddp, fadd, FPAdd) \ 2788 V(fmaxp, fmax, FPMax) \ 2789 V(fmaxnmp, fmaxnm, FPMaxNM) \ 2790 V(fminp, fmin, FPMin) \ 2791 V(fminnmp, fminnm, FPMinNM) 2792 2793#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP) \ 2794 LogicVRegister FNP(VectorFormat vform, \ 2795 LogicVRegister dst, \ 2796 const LogicVRegister& src1, \ 2797 const LogicVRegister& src2); \ 2798 LogicVRegister FNP(VectorFormat vform, \ 2799 LogicVRegister dst, \ 2800 const LogicVRegister& src); 2801 NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP) 2802#undef DECLARE_NEON_FP_PAIR_OP 2803 2804 template <typename T> 2805 LogicVRegister frecps(VectorFormat vform, 2806 LogicVRegister dst, 2807 const LogicVRegister& src1, 2808 const LogicVRegister& src2); 2809 LogicVRegister frecps(VectorFormat vform, 2810 LogicVRegister dst, 2811 const LogicVRegister& src1, 2812 const LogicVRegister& src2); 2813 template <typename T> 2814 LogicVRegister frsqrts(VectorFormat vform, 2815 LogicVRegister dst, 2816 const LogicVRegister& src1, 2817 const LogicVRegister& src2); 2818 LogicVRegister frsqrts(VectorFormat vform, 2819 LogicVRegister dst, 2820 const LogicVRegister& src1, 2821 const LogicVRegister& src2); 2822 template <typename T> 2823 LogicVRegister fmla(VectorFormat vform, 2824 LogicVRegister dst, 2825 const LogicVRegister& src1, 2826 const LogicVRegister& src2); 2827 LogicVRegister fmla(VectorFormat vform, 2828 LogicVRegister dst, 2829 const LogicVRegister& src1, 2830 const LogicVRegister& src2); 2831 template <typename T> 2832 LogicVRegister fmls(VectorFormat vform, 2833 LogicVRegister dst, 2834 const LogicVRegister& src1, 2835 const LogicVRegister& src2); 2836 LogicVRegister fmls(VectorFormat vform, 2837 LogicVRegister dst, 2838 const LogicVRegister& src1, 2839 const LogicVRegister& src2); 2840 LogicVRegister fnmul(VectorFormat vform, 2841 LogicVRegister dst, 2842 const LogicVRegister& src1, 2843 const LogicVRegister& src2); 2844 2845 template <typename T> 2846 LogicVRegister fcmp(VectorFormat vform, 2847 LogicVRegister dst, 2848 const LogicVRegister& src1, 2849 const LogicVRegister& src2, 2850 Condition cond); 2851 LogicVRegister fcmp(VectorFormat vform, 2852 LogicVRegister dst, 2853 const LogicVRegister& src1, 2854 const LogicVRegister& src2, 2855 Condition cond); 2856 LogicVRegister fabscmp(VectorFormat vform, 2857 LogicVRegister dst, 2858 const LogicVRegister& src1, 2859 const LogicVRegister& src2, 2860 Condition cond); 2861 LogicVRegister fcmp_zero(VectorFormat vform, 2862 LogicVRegister dst, 2863 const LogicVRegister& src, 2864 Condition cond); 2865 2866 template <typename T> 2867 LogicVRegister fneg(VectorFormat vform, 2868 LogicVRegister dst, 2869 const LogicVRegister& src); 2870 LogicVRegister fneg(VectorFormat vform, 2871 LogicVRegister dst, 2872 const LogicVRegister& src); 2873 template <typename T> 2874 LogicVRegister frecpx(VectorFormat vform, 2875 LogicVRegister dst, 2876 const LogicVRegister& src); 2877 LogicVRegister frecpx(VectorFormat vform, 2878 LogicVRegister dst, 2879 const LogicVRegister& src); 2880 template <typename T> 2881 LogicVRegister fabs_(VectorFormat vform, 2882 LogicVRegister dst, 2883 const LogicVRegister& src); 2884 LogicVRegister fabs_(VectorFormat vform, 2885 LogicVRegister dst, 2886 const LogicVRegister& src); 2887 LogicVRegister fabd(VectorFormat vform, 2888 LogicVRegister dst, 2889 const LogicVRegister& src1, 2890 const LogicVRegister& src2); 2891 LogicVRegister frint(VectorFormat vform, 2892 LogicVRegister dst, 2893 const LogicVRegister& src, 2894 FPRounding rounding_mode, 2895 bool inexact_exception = false); 2896 LogicVRegister fcvts(VectorFormat vform, 2897 LogicVRegister dst, 2898 const LogicVRegister& src, 2899 FPRounding rounding_mode, 2900 int fbits = 0); 2901 LogicVRegister fcvtu(VectorFormat vform, 2902 LogicVRegister dst, 2903 const LogicVRegister& src, 2904 FPRounding rounding_mode, 2905 int fbits = 0); 2906 LogicVRegister fcvtl(VectorFormat vform, 2907 LogicVRegister dst, 2908 const LogicVRegister& src); 2909 LogicVRegister fcvtl2(VectorFormat vform, 2910 LogicVRegister dst, 2911 const LogicVRegister& src); 2912 LogicVRegister fcvtn(VectorFormat vform, 2913 LogicVRegister dst, 2914 const LogicVRegister& src); 2915 LogicVRegister fcvtn2(VectorFormat vform, 2916 LogicVRegister dst, 2917 const LogicVRegister& src); 2918 LogicVRegister fcvtxn(VectorFormat vform, 2919 LogicVRegister dst, 2920 const LogicVRegister& src); 2921 LogicVRegister fcvtxn2(VectorFormat vform, 2922 LogicVRegister dst, 2923 const LogicVRegister& src); 2924 LogicVRegister fsqrt(VectorFormat vform, 2925 LogicVRegister dst, 2926 const LogicVRegister& src); 2927 LogicVRegister frsqrte(VectorFormat vform, 2928 LogicVRegister dst, 2929 const LogicVRegister& src); 2930 LogicVRegister frecpe(VectorFormat vform, 2931 LogicVRegister dst, 2932 const LogicVRegister& src, 2933 FPRounding rounding); 2934 LogicVRegister ursqrte(VectorFormat vform, 2935 LogicVRegister dst, 2936 const LogicVRegister& src); 2937 LogicVRegister urecpe(VectorFormat vform, 2938 LogicVRegister dst, 2939 const LogicVRegister& src); 2940 2941 typedef float (Simulator::*FPMinMaxOp)(float a, float b); 2942 2943 LogicVRegister fminmaxv(VectorFormat vform, 2944 LogicVRegister dst, 2945 const LogicVRegister& src, 2946 FPMinMaxOp Op); 2947 2948 LogicVRegister fminv(VectorFormat vform, 2949 LogicVRegister dst, 2950 const LogicVRegister& src); 2951 LogicVRegister fmaxv(VectorFormat vform, 2952 LogicVRegister dst, 2953 const LogicVRegister& src); 2954 LogicVRegister fminnmv(VectorFormat vform, 2955 LogicVRegister dst, 2956 const LogicVRegister& src); 2957 LogicVRegister fmaxnmv(VectorFormat vform, 2958 LogicVRegister dst, 2959 const LogicVRegister& src); 2960 2961 static const uint32_t CRC32_POLY = 0x04C11DB7; 2962 static const uint32_t CRC32C_POLY = 0x1EDC6F41; 2963 uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly); 2964 template <typename T> 2965 uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly); 2966 uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly); 2967 2968 void SysOp_W(int op, int64_t val); 2969 2970 template <typename T> 2971 T FPRecipSqrtEstimate(T op); 2972 template <typename T> 2973 T FPRecipEstimate(T op, FPRounding rounding); 2974 template <typename T, typename R> 2975 R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding); 2976 2977 void FPCompare(double val0, double val1, FPTrapFlags trap); 2978 double FPRoundInt(double value, FPRounding round_mode); 2979 double FPToDouble(float value); 2980 float FPToFloat(double value, FPRounding round_mode); 2981 float FPToFloat(float16 value); 2982 float16 FPToFloat16(float value, FPRounding round_mode); 2983 float16 FPToFloat16(double value, FPRounding round_mode); 2984 double recip_sqrt_estimate(double a); 2985 double recip_estimate(double a); 2986 double FPRecipSqrtEstimate(double a); 2987 double FPRecipEstimate(double a); 2988 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); 2989 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); 2990 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); 2991 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); 2992 int32_t FPToInt32(double value, FPRounding rmode); 2993 int64_t FPToInt64(double value, FPRounding rmode); 2994 uint32_t FPToUInt32(double value, FPRounding rmode); 2995 uint64_t FPToUInt64(double value, FPRounding rmode); 2996 2997 template <typename T> 2998 T FPAdd(T op1, T op2); 2999 3000 template <typename T> 3001 T FPDiv(T op1, T op2); 3002 3003 template <typename T> 3004 T FPMax(T a, T b); 3005 3006 template <typename T> 3007 T FPMaxNM(T a, T b); 3008 3009 template <typename T> 3010 T FPMin(T a, T b); 3011 3012 template <typename T> 3013 T FPMinNM(T a, T b); 3014 3015 template <typename T> 3016 T FPMul(T op1, T op2); 3017 3018 template <typename T> 3019 T FPMulx(T op1, T op2); 3020 3021 template <typename T> 3022 T FPMulAdd(T a, T op1, T op2); 3023 3024 template <typename T> 3025 T FPSqrt(T op); 3026 3027 template <typename T> 3028 T FPSub(T op1, T op2); 3029 3030 template <typename T> 3031 T FPRecipStepFused(T op1, T op2); 3032 3033 template <typename T> 3034 T FPRSqrtStepFused(T op1, T op2); 3035 3036 // This doesn't do anything at the moment. We'll need it if we want support 3037 // for cumulative exception bits or floating-point exceptions. 3038 void FPProcessException() {} 3039 3040 bool FPProcessNaNs(const Instruction* instr); 3041 3042 // Pseudo Printf instruction 3043 void DoPrintf(const Instruction* instr); 3044 3045// Simulate a runtime call. 3046#ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT 3047 VIXL_NO_RETURN_IN_DEBUG_MODE 3048#endif 3049 void DoRuntimeCall(const Instruction* instr); 3050 3051 // Processor state --------------------------------------- 3052 3053 // Simulated monitors for exclusive access instructions. 3054 SimExclusiveLocalMonitor local_monitor_; 3055 SimExclusiveGlobalMonitor global_monitor_; 3056 3057 // Output stream. 3058 FILE* stream_; 3059 PrintDisassembler* print_disasm_; 3060 3061 // Instruction statistics instrumentation. 3062 Instrument* instrumentation_; 3063 3064 // General purpose registers. Register 31 is the stack pointer. 3065 SimRegister registers_[kNumberOfRegisters]; 3066 3067 // Vector registers 3068 SimVRegister vregisters_[kNumberOfVRegisters]; 3069 3070 // Program Status Register. 3071 // bits[31, 27]: Condition flags N, Z, C, and V. 3072 // (Negative, Zero, Carry, Overflow) 3073 SimSystemRegister nzcv_; 3074 3075 // Floating-Point Control Register 3076 SimSystemRegister fpcr_; 3077 3078 // Only a subset of FPCR features are supported by the simulator. This helper 3079 // checks that the FPCR settings are supported. 3080 // 3081 // This is checked when floating-point instructions are executed, not when 3082 // FPCR is set. This allows generated code to modify FPCR for external 3083 // functions, or to save and restore it when entering and leaving generated 3084 // code. 3085 void AssertSupportedFPCR() { 3086 // No flush-to-zero support. 3087 VIXL_ASSERT(ReadFpcr().GetFZ() == 0); 3088 // Ties-to-even rounding only. 3089 VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven); 3090 3091 // The simulator does not support half-precision operations so 3092 // GetFpcr().AHP() is irrelevant, and is not checked here. 3093 } 3094 3095 static int CalcNFlag(uint64_t result, unsigned reg_size) { 3096 return (result >> (reg_size - 1)) & 1; 3097 } 3098 3099 static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; } 3100 3101 static const uint32_t kConditionFlagsMask = 0xf0000000; 3102 3103 // Stack 3104 byte* stack_; 3105 static const int stack_protection_size_ = 256; 3106 // 2 KB stack. 3107 static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_; 3108 byte* stack_limit_; 3109 3110 Decoder* decoder_; 3111 // Indicates if the pc has been modified by the instruction and should not be 3112 // automatically incremented. 3113 bool pc_modified_; 3114 const Instruction* pc_; 3115 3116 static const char* xreg_names[]; 3117 static const char* wreg_names[]; 3118 static const char* sreg_names[]; 3119 static const char* dreg_names[]; 3120 static const char* vreg_names[]; 3121 3122 private: 3123 template <typename T> 3124 static T FPDefaultNaN(); 3125 3126 // Standard NaN processing. 3127 template <typename T> 3128 T FPProcessNaN(T op) { 3129 VIXL_ASSERT(std::isnan(op)); 3130 if (IsSignallingNaN(op)) { 3131 FPProcessException(); 3132 } 3133 return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 3134 } 3135 3136 template <typename T> 3137 T FPProcessNaNs(T op1, T op2) { 3138 if (IsSignallingNaN(op1)) { 3139 return FPProcessNaN(op1); 3140 } else if (IsSignallingNaN(op2)) { 3141 return FPProcessNaN(op2); 3142 } else if (std::isnan(op1)) { 3143 VIXL_ASSERT(IsQuietNaN(op1)); 3144 return FPProcessNaN(op1); 3145 } else if (std::isnan(op2)) { 3146 VIXL_ASSERT(IsQuietNaN(op2)); 3147 return FPProcessNaN(op2); 3148 } else { 3149 return 0.0; 3150 } 3151 } 3152 3153 template <typename T> 3154 T FPProcessNaNs3(T op1, T op2, T op3) { 3155 if (IsSignallingNaN(op1)) { 3156 return FPProcessNaN(op1); 3157 } else if (IsSignallingNaN(op2)) { 3158 return FPProcessNaN(op2); 3159 } else if (IsSignallingNaN(op3)) { 3160 return FPProcessNaN(op3); 3161 } else if (std::isnan(op1)) { 3162 VIXL_ASSERT(IsQuietNaN(op1)); 3163 return FPProcessNaN(op1); 3164 } else if (std::isnan(op2)) { 3165 VIXL_ASSERT(IsQuietNaN(op2)); 3166 return FPProcessNaN(op2); 3167 } else if (std::isnan(op3)) { 3168 VIXL_ASSERT(IsQuietNaN(op3)); 3169 return FPProcessNaN(op3); 3170 } else { 3171 return 0.0; 3172 } 3173 } 3174 3175 bool coloured_trace_; 3176 3177 // A set of TraceParameters flags. 3178 int trace_parameters_; 3179 3180 // Indicates whether the instruction instrumentation is active. 3181 bool instruction_stats_; 3182 3183 // Indicates whether the exclusive-access warning has been printed. 3184 bool print_exclusive_access_warning_; 3185 void PrintExclusiveAccessWarning(); 3186}; 3187 3188#if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L 3189// Base case of the recursive template used to emulate C++14 3190// `std::index_sequence`. 3191template <size_t... I> 3192struct Simulator::emulated_make_index_sequence_helper<0, I...> 3193 : Simulator::emulated_index_sequence<I...> {}; 3194#endif 3195 3196} // namespace aarch64 3197} // namespace vixl 3198 3199#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 3200 3201#endif // VIXL_AARCH64_SIMULATOR_AARCH64_H_ 3202