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