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