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