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