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