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