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