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