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