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 #ifdef VIXL_INCLUDE_SIMULATOR
28 
29 #include <cmath>
30 #include "vixl/a64/simulator-a64.h"
31 
32 namespace vixl {
33 
FPDefaultNaN()34 template<> double Simulator::FPDefaultNaN<double>() {
35   return kFP64DefaultNaN;
36 }
37 
38 
FPDefaultNaN()39 template<> float Simulator::FPDefaultNaN<float>() {
40   return kFP32DefaultNaN;
41 }
42 
43 // See FPRound for a description of this function.
FPRoundToDouble(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)44 static inline double FPRoundToDouble(int64_t sign, int64_t exponent,
45                                      uint64_t mantissa, FPRounding round_mode) {
46   int64_t bits =
47       FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign,
48                                                                  exponent,
49                                                                  mantissa,
50                                                                  round_mode);
51   return rawbits_to_double(bits);
52 }
53 
54 
55 // See FPRound for a description of this function.
FPRoundToFloat(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)56 static inline float FPRoundToFloat(int64_t sign, int64_t exponent,
57                                    uint64_t mantissa, FPRounding round_mode) {
58   int32_t bits =
59       FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign,
60                                                                exponent,
61                                                                mantissa,
62                                                                round_mode);
63   return rawbits_to_float(bits);
64 }
65 
66 
67 // See FPRound for a description of this function.
FPRoundToFloat16(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)68 static inline float16 FPRoundToFloat16(int64_t sign,
69                                        int64_t exponent,
70                                        uint64_t mantissa,
71                                        FPRounding round_mode) {
72   return FPRound<float16, kFloat16ExponentBits, kFloat16MantissaBits>(
73       sign, exponent, mantissa, round_mode);
74 }
75 
76 
FixedToDouble(int64_t src,int fbits,FPRounding round)77 double Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) {
78   if (src >= 0) {
79     return UFixedToDouble(src, fbits, round);
80   } else {
81     // This works for all negative values, including INT64_MIN.
82     return -UFixedToDouble(-src, fbits, round);
83   }
84 }
85 
86 
UFixedToDouble(uint64_t src,int fbits,FPRounding round)87 double Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) {
88   // An input of 0 is a special case because the result is effectively
89   // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
90   if (src == 0) {
91     return 0.0;
92   }
93 
94   // Calculate the exponent. The highest significant bit will have the value
95   // 2^exponent.
96   const int highest_significant_bit = 63 - CountLeadingZeros(src);
97   const int64_t exponent = highest_significant_bit - fbits;
98 
99   return FPRoundToDouble(0, exponent, src, round);
100 }
101 
102 
FixedToFloat(int64_t src,int fbits,FPRounding round)103 float Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) {
104   if (src >= 0) {
105     return UFixedToFloat(src, fbits, round);
106   } else {
107     // This works for all negative values, including INT64_MIN.
108     return -UFixedToFloat(-src, fbits, round);
109   }
110 }
111 
112 
UFixedToFloat(uint64_t src,int fbits,FPRounding round)113 float Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) {
114   // An input of 0 is a special case because the result is effectively
115   // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
116   if (src == 0) {
117     return 0.0f;
118   }
119 
120   // Calculate the exponent. The highest significant bit will have the value
121   // 2^exponent.
122   const int highest_significant_bit = 63 - CountLeadingZeros(src);
123   const int32_t exponent = highest_significant_bit - fbits;
124 
125   return FPRoundToFloat(0, exponent, src, round);
126 }
127 
128 
FPToDouble(float value)129 double Simulator::FPToDouble(float value) {
130   switch (std::fpclassify(value)) {
131     case FP_NAN: {
132       if (IsSignallingNaN(value)) {
133         FPProcessException();
134       }
135       if (DN()) return kFP64DefaultNaN;
136 
137       // Convert NaNs as the processor would:
138       //  - The sign is propagated.
139       //  - The payload (mantissa) is transferred entirely, except that the top
140       //    bit is forced to '1', making the result a quiet NaN. The unused
141       //    (low-order) payload bits are set to 0.
142       uint32_t raw = float_to_rawbits(value);
143 
144       uint64_t sign = raw >> 31;
145       uint64_t exponent = (1 << 11) - 1;
146       uint64_t payload = unsigned_bitextract_64(21, 0, raw);
147       payload <<= (52 - 23);  // The unused low-order bits should be 0.
148       payload |= (UINT64_C(1) << 51);  // Force a quiet NaN.
149 
150       return rawbits_to_double((sign << 63) | (exponent << 52) | payload);
151     }
152 
153     case FP_ZERO:
154     case FP_NORMAL:
155     case FP_SUBNORMAL:
156     case FP_INFINITE: {
157       // All other inputs are preserved in a standard cast, because every value
158       // representable using an IEEE-754 float is also representable using an
159       // IEEE-754 double.
160       return static_cast<double>(value);
161     }
162   }
163 
164   VIXL_UNREACHABLE();
165   return static_cast<double>(value);
166 }
167 
168 
FPToFloat(float16 value)169 float Simulator::FPToFloat(float16 value) {
170   uint32_t sign = value >> 15;
171   uint32_t exponent = unsigned_bitextract_32(
172       kFloat16MantissaBits + kFloat16ExponentBits - 1, kFloat16MantissaBits,
173       value);
174   uint32_t mantissa = unsigned_bitextract_32(
175       kFloat16MantissaBits - 1, 0, value);
176 
177   switch (float16classify(value)) {
178     case FP_ZERO:
179       return (sign == 0) ? 0.0f : -0.0f;
180 
181     case FP_INFINITE:
182       return (sign == 0) ? kFP32PositiveInfinity : kFP32NegativeInfinity;
183 
184     case FP_SUBNORMAL: {
185       // Calculate shift required to put mantissa into the most-significant bits
186       // of the destination mantissa.
187       int shift = CountLeadingZeros(mantissa << (32 - 10));
188 
189       // Shift mantissa and discard implicit '1'.
190       mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits) + shift + 1;
191       mantissa &= (1 << kFloatMantissaBits) - 1;
192 
193       // Adjust the exponent for the shift applied, and rebias.
194       exponent = exponent - shift + (-15 + 127);
195       break;
196     }
197 
198     case FP_NAN:
199       if (IsSignallingNaN(value)) {
200         FPProcessException();
201       }
202       if (DN()) return kFP32DefaultNaN;
203 
204       // Convert NaNs as the processor would:
205       //  - The sign is propagated.
206       //  - The payload (mantissa) is transferred entirely, except that the top
207       //    bit is forced to '1', making the result a quiet NaN. The unused
208       //    (low-order) payload bits are set to 0.
209       exponent = (1 << kFloatExponentBits) - 1;
210 
211       // Increase bits in mantissa, making low-order bits 0.
212       mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
213       mantissa |= 1 << 22;  // Force a quiet NaN.
214       break;
215 
216     case FP_NORMAL:
217       // Increase bits in mantissa, making low-order bits 0.
218       mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
219 
220       // Change exponent bias.
221       exponent += (-15 + 127);
222       break;
223 
224     default: VIXL_UNREACHABLE();
225   }
226   return rawbits_to_float((sign << 31) |
227                           (exponent << kFloatMantissaBits) |
228                           mantissa);
229 }
230 
231 
FPToFloat16(float value,FPRounding round_mode)232 float16 Simulator::FPToFloat16(float value, FPRounding round_mode) {
233   // Only the FPTieEven rounding mode is implemented.
234   VIXL_ASSERT(round_mode == FPTieEven);
235   USE(round_mode);
236 
237   uint32_t raw = float_to_rawbits(value);
238   int32_t sign = raw >> 31;
239   int32_t exponent = unsigned_bitextract_32(30, 23, raw) - 127;
240   uint32_t mantissa = unsigned_bitextract_32(22, 0, raw);
241 
242   switch (std::fpclassify(value)) {
243     case FP_NAN: {
244       if (IsSignallingNaN(value)) {
245         FPProcessException();
246       }
247       if (DN()) return kFP16DefaultNaN;
248 
249       // Convert NaNs as the processor would:
250       //  - The sign is propagated.
251       //  - The payload (mantissa) is transferred as much as possible, except
252       //    that the top bit is forced to '1', making the result a quiet NaN.
253       float16 result = (sign == 0) ? kFP16PositiveInfinity
254                                    : kFP16NegativeInfinity;
255       result |= mantissa >> (kFloatMantissaBits - kFloat16MantissaBits);
256       result |= (1 << 9);  // Force a quiet NaN;
257       return result;
258     }
259 
260     case FP_ZERO:
261       return (sign == 0) ? 0 : 0x8000;
262 
263     case FP_INFINITE:
264       return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
265 
266     case FP_NORMAL:
267     case FP_SUBNORMAL: {
268       // Convert float-to-half as the processor would, assuming that FPCR.FZ
269       // (flush-to-zero) is not set.
270 
271       // Add the implicit '1' bit to the mantissa.
272       mantissa += (1 << 23);
273       return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
274     }
275   }
276 
277   VIXL_UNREACHABLE();
278   return 0;
279 }
280 
281 
FPToFloat16(double value,FPRounding round_mode)282 float16 Simulator::FPToFloat16(double value, FPRounding round_mode) {
283   // Only the FPTieEven rounding mode is implemented.
284   VIXL_ASSERT(round_mode == FPTieEven);
285   USE(round_mode);
286 
287   uint64_t raw = double_to_rawbits(value);
288   int32_t sign = raw >> 63;
289   int64_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023;
290   uint64_t mantissa = unsigned_bitextract_64(51, 0, raw);
291 
292   switch (std::fpclassify(value)) {
293     case FP_NAN: {
294       if (IsSignallingNaN(value)) {
295         FPProcessException();
296       }
297       if (DN()) return kFP16DefaultNaN;
298 
299       // Convert NaNs as the processor would:
300       //  - The sign is propagated.
301       //  - The payload (mantissa) is transferred as much as possible, except
302       //    that the top bit is forced to '1', making the result a quiet NaN.
303       float16 result = (sign == 0) ? kFP16PositiveInfinity
304                                    : kFP16NegativeInfinity;
305       result |= mantissa >> (kDoubleMantissaBits - kFloat16MantissaBits);
306       result |= (1 << 9);  // Force a quiet NaN;
307       return result;
308     }
309 
310     case FP_ZERO:
311       return (sign == 0) ? 0 : 0x8000;
312 
313     case FP_INFINITE:
314       return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
315 
316     case FP_NORMAL:
317     case FP_SUBNORMAL: {
318       // Convert double-to-half as the processor would, assuming that FPCR.FZ
319       // (flush-to-zero) is not set.
320 
321       // Add the implicit '1' bit to the mantissa.
322       mantissa += (UINT64_C(1) << 52);
323       return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
324     }
325   }
326 
327   VIXL_UNREACHABLE();
328   return 0;
329 }
330 
331 
FPToFloat(double value,FPRounding round_mode)332 float Simulator::FPToFloat(double value, FPRounding round_mode) {
333   // Only the FPTieEven rounding mode is implemented.
334   VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
335   USE(round_mode);
336 
337   switch (std::fpclassify(value)) {
338     case FP_NAN: {
339       if (IsSignallingNaN(value)) {
340         FPProcessException();
341       }
342       if (DN()) return kFP32DefaultNaN;
343 
344       // Convert NaNs as the processor would:
345       //  - The sign is propagated.
346       //  - The payload (mantissa) is transferred as much as possible, except
347       //    that the top bit is forced to '1', making the result a quiet NaN.
348       uint64_t raw = double_to_rawbits(value);
349 
350       uint32_t sign = raw >> 63;
351       uint32_t exponent = (1 << 8) - 1;
352       uint32_t payload =
353           static_cast<uint32_t>(unsigned_bitextract_64(50, 52 - 23, raw));
354       payload |= (1 << 22);   // Force a quiet NaN.
355 
356       return rawbits_to_float((sign << 31) | (exponent << 23) | payload);
357     }
358 
359     case FP_ZERO:
360     case FP_INFINITE: {
361       // In a C++ cast, any value representable in the target type will be
362       // unchanged. This is always the case for +/-0.0 and infinities.
363       return static_cast<float>(value);
364     }
365 
366     case FP_NORMAL:
367     case FP_SUBNORMAL: {
368       // Convert double-to-float as the processor would, assuming that FPCR.FZ
369       // (flush-to-zero) is not set.
370       uint64_t raw = double_to_rawbits(value);
371       // Extract the IEEE-754 double components.
372       uint32_t sign = raw >> 63;
373       // Extract the exponent and remove the IEEE-754 encoding bias.
374       int32_t exponent =
375           static_cast<int32_t>(unsigned_bitextract_64(62, 52, raw)) - 1023;
376       // Extract the mantissa and add the implicit '1' bit.
377       uint64_t mantissa = unsigned_bitextract_64(51, 0, raw);
378       if (std::fpclassify(value) == FP_NORMAL) {
379         mantissa |= (UINT64_C(1) << 52);
380       }
381       return FPRoundToFloat(sign, exponent, mantissa, round_mode);
382     }
383   }
384 
385   VIXL_UNREACHABLE();
386   return value;
387 }
388 
389 
ld1(VectorFormat vform,LogicVRegister dst,uint64_t addr)390 void Simulator::ld1(VectorFormat vform,
391                     LogicVRegister dst,
392                     uint64_t addr) {
393   dst.ClearForWrite(vform);
394   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
395     dst.ReadUintFromMem(vform, i, addr);
396     addr += LaneSizeInBytesFromFormat(vform);
397   }
398 }
399 
400 
ld1(VectorFormat vform,LogicVRegister dst,int index,uint64_t addr)401 void Simulator::ld1(VectorFormat vform,
402                     LogicVRegister dst,
403                     int index,
404                     uint64_t addr) {
405   dst.ReadUintFromMem(vform, index, addr);
406 }
407 
408 
ld1r(VectorFormat vform,LogicVRegister dst,uint64_t addr)409 void Simulator::ld1r(VectorFormat vform,
410                      LogicVRegister dst,
411                      uint64_t addr) {
412   dst.ClearForWrite(vform);
413   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
414     dst.ReadUintFromMem(vform, i, addr);
415   }
416 }
417 
418 
ld2(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,uint64_t addr1)419 void Simulator::ld2(VectorFormat vform,
420                     LogicVRegister dst1,
421                     LogicVRegister dst2,
422                     uint64_t addr1) {
423   dst1.ClearForWrite(vform);
424   dst2.ClearForWrite(vform);
425   int esize = LaneSizeInBytesFromFormat(vform);
426   uint64_t addr2 = addr1 + esize;
427   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
428     dst1.ReadUintFromMem(vform, i, addr1);
429     dst2.ReadUintFromMem(vform, i, addr2);
430     addr1 += 2 * esize;
431     addr2 += 2 * esize;
432   }
433 }
434 
435 
ld2(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,int index,uint64_t addr1)436 void Simulator::ld2(VectorFormat vform,
437                     LogicVRegister dst1,
438                     LogicVRegister dst2,
439                     int index,
440                     uint64_t addr1) {
441   dst1.ClearForWrite(vform);
442   dst2.ClearForWrite(vform);
443   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
444   dst1.ReadUintFromMem(vform, index, addr1);
445   dst2.ReadUintFromMem(vform, index, addr2);
446 }
447 
448 
ld2r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,uint64_t addr)449 void Simulator::ld2r(VectorFormat vform,
450                      LogicVRegister dst1,
451                      LogicVRegister dst2,
452                      uint64_t addr) {
453   dst1.ClearForWrite(vform);
454   dst2.ClearForWrite(vform);
455   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
456   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
457     dst1.ReadUintFromMem(vform, i, addr);
458     dst2.ReadUintFromMem(vform, i, addr2);
459   }
460 }
461 
462 
ld3(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr1)463 void Simulator::ld3(VectorFormat vform,
464                     LogicVRegister dst1,
465                     LogicVRegister dst2,
466                     LogicVRegister dst3,
467                     uint64_t addr1) {
468   dst1.ClearForWrite(vform);
469   dst2.ClearForWrite(vform);
470   dst3.ClearForWrite(vform);
471   int esize = LaneSizeInBytesFromFormat(vform);
472   uint64_t addr2 = addr1 + esize;
473   uint64_t addr3 = addr2 + esize;
474   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
475     dst1.ReadUintFromMem(vform, i, addr1);
476     dst2.ReadUintFromMem(vform, i, addr2);
477     dst3.ReadUintFromMem(vform, i, addr3);
478     addr1 += 3 * esize;
479     addr2 += 3 * esize;
480     addr3 += 3 * esize;
481   }
482 }
483 
484 
ld3(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,int index,uint64_t addr1)485 void Simulator::ld3(VectorFormat vform,
486                     LogicVRegister dst1,
487                     LogicVRegister dst2,
488                     LogicVRegister dst3,
489                     int index,
490                     uint64_t addr1) {
491   dst1.ClearForWrite(vform);
492   dst2.ClearForWrite(vform);
493   dst3.ClearForWrite(vform);
494   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
495   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
496   dst1.ReadUintFromMem(vform, index, addr1);
497   dst2.ReadUintFromMem(vform, index, addr2);
498   dst3.ReadUintFromMem(vform, index, addr3);
499 }
500 
501 
ld3r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr)502 void Simulator::ld3r(VectorFormat vform,
503                      LogicVRegister dst1,
504                      LogicVRegister dst2,
505                      LogicVRegister dst3,
506                      uint64_t addr) {
507   dst1.ClearForWrite(vform);
508   dst2.ClearForWrite(vform);
509   dst3.ClearForWrite(vform);
510   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
511   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
512   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
513     dst1.ReadUintFromMem(vform, i, addr);
514     dst2.ReadUintFromMem(vform, i, addr2);
515     dst3.ReadUintFromMem(vform, i, addr3);
516   }
517 }
518 
519 
ld4(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr1)520 void Simulator::ld4(VectorFormat vform,
521                     LogicVRegister dst1,
522                     LogicVRegister dst2,
523                     LogicVRegister dst3,
524                     LogicVRegister dst4,
525                     uint64_t addr1) {
526   dst1.ClearForWrite(vform);
527   dst2.ClearForWrite(vform);
528   dst3.ClearForWrite(vform);
529   dst4.ClearForWrite(vform);
530   int esize = LaneSizeInBytesFromFormat(vform);
531   uint64_t addr2 = addr1 + esize;
532   uint64_t addr3 = addr2 + esize;
533   uint64_t addr4 = addr3 + esize;
534   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
535     dst1.ReadUintFromMem(vform, i, addr1);
536     dst2.ReadUintFromMem(vform, i, addr2);
537     dst3.ReadUintFromMem(vform, i, addr3);
538     dst4.ReadUintFromMem(vform, i, addr4);
539     addr1 += 4 * esize;
540     addr2 += 4 * esize;
541     addr3 += 4 * esize;
542     addr4 += 4 * esize;
543   }
544 }
545 
546 
ld4(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,int index,uint64_t addr1)547 void Simulator::ld4(VectorFormat vform,
548                     LogicVRegister dst1,
549                     LogicVRegister dst2,
550                     LogicVRegister dst3,
551                     LogicVRegister dst4,
552                     int index,
553                     uint64_t addr1) {
554   dst1.ClearForWrite(vform);
555   dst2.ClearForWrite(vform);
556   dst3.ClearForWrite(vform);
557   dst4.ClearForWrite(vform);
558   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
559   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
560   uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
561   dst1.ReadUintFromMem(vform, index, addr1);
562   dst2.ReadUintFromMem(vform, index, addr2);
563   dst3.ReadUintFromMem(vform, index, addr3);
564   dst4.ReadUintFromMem(vform, index, addr4);
565 }
566 
567 
ld4r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr)568 void Simulator::ld4r(VectorFormat vform,
569                      LogicVRegister dst1,
570                      LogicVRegister dst2,
571                      LogicVRegister dst3,
572                      LogicVRegister dst4,
573                      uint64_t addr) {
574   dst1.ClearForWrite(vform);
575   dst2.ClearForWrite(vform);
576   dst3.ClearForWrite(vform);
577   dst4.ClearForWrite(vform);
578   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
579   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
580   uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
581   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
582     dst1.ReadUintFromMem(vform, i, addr);
583     dst2.ReadUintFromMem(vform, i, addr2);
584     dst3.ReadUintFromMem(vform, i, addr3);
585     dst4.ReadUintFromMem(vform, i, addr4);
586   }
587 }
588 
589 
st1(VectorFormat vform,LogicVRegister src,uint64_t addr)590 void Simulator::st1(VectorFormat vform,
591                     LogicVRegister src,
592                     uint64_t addr) {
593   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
594     src.WriteUintToMem(vform, i, addr);
595     addr += LaneSizeInBytesFromFormat(vform);
596   }
597 }
598 
599 
st1(VectorFormat vform,LogicVRegister src,int index,uint64_t addr)600 void Simulator::st1(VectorFormat vform,
601                     LogicVRegister src,
602                     int index,
603                     uint64_t addr) {
604   src.WriteUintToMem(vform, index, addr);
605 }
606 
607 
st2(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,uint64_t addr)608 void Simulator::st2(VectorFormat vform,
609                     LogicVRegister dst,
610                     LogicVRegister dst2,
611                     uint64_t addr) {
612   int esize = LaneSizeInBytesFromFormat(vform);
613   uint64_t addr2 = addr + esize;
614   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
615     dst.WriteUintToMem(vform, i, addr);
616     dst2.WriteUintToMem(vform, i, addr2);
617     addr += 2 * esize;
618     addr2 += 2 * esize;
619   }
620 }
621 
622 
st2(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,int index,uint64_t addr)623 void Simulator::st2(VectorFormat vform,
624                     LogicVRegister dst,
625                     LogicVRegister dst2,
626                     int index,
627                     uint64_t addr) {
628   int esize = LaneSizeInBytesFromFormat(vform);
629   dst.WriteUintToMem(vform, index, addr);
630   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
631 }
632 
633 
st3(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr)634 void Simulator::st3(VectorFormat vform,
635                     LogicVRegister dst,
636                     LogicVRegister dst2,
637                     LogicVRegister dst3,
638                     uint64_t addr) {
639   int esize = LaneSizeInBytesFromFormat(vform);
640   uint64_t addr2 = addr + esize;
641   uint64_t addr3 = addr2 + esize;
642   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
643     dst.WriteUintToMem(vform, i, addr);
644     dst2.WriteUintToMem(vform, i, addr2);
645     dst3.WriteUintToMem(vform, i, addr3);
646     addr += 3 * esize;
647     addr2 += 3 * esize;
648     addr3 += 3 * esize;
649   }
650 }
651 
652 
st3(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,int index,uint64_t addr)653 void Simulator::st3(VectorFormat vform,
654                     LogicVRegister dst,
655                     LogicVRegister dst2,
656                     LogicVRegister dst3,
657                     int index,
658                     uint64_t addr) {
659   int esize = LaneSizeInBytesFromFormat(vform);
660   dst.WriteUintToMem(vform, index, addr);
661   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
662   dst3.WriteUintToMem(vform, index, addr + 2 * esize);
663 }
664 
665 
st4(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr)666 void Simulator::st4(VectorFormat vform,
667                     LogicVRegister dst,
668                     LogicVRegister dst2,
669                     LogicVRegister dst3,
670                     LogicVRegister dst4,
671                     uint64_t addr) {
672   int esize = LaneSizeInBytesFromFormat(vform);
673   uint64_t addr2 = addr + esize;
674   uint64_t addr3 = addr2 + esize;
675   uint64_t addr4 = addr3 + esize;
676   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
677     dst.WriteUintToMem(vform, i, addr);
678     dst2.WriteUintToMem(vform, i, addr2);
679     dst3.WriteUintToMem(vform, i, addr3);
680     dst4.WriteUintToMem(vform, i, addr4);
681     addr += 4 * esize;
682     addr2 += 4 * esize;
683     addr3 += 4 * esize;
684     addr4 += 4 * esize;
685   }
686 }
687 
688 
st4(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,int index,uint64_t addr)689 void Simulator::st4(VectorFormat vform,
690                     LogicVRegister dst,
691                     LogicVRegister dst2,
692                     LogicVRegister dst3,
693                     LogicVRegister dst4,
694                     int index,
695                     uint64_t addr) {
696   int esize = LaneSizeInBytesFromFormat(vform);
697   dst.WriteUintToMem(vform, index, addr);
698   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
699   dst3.WriteUintToMem(vform, index, addr + 2 * esize);
700   dst4.WriteUintToMem(vform, index, addr + 3 * esize);
701 }
702 
703 
cmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)704 LogicVRegister Simulator::cmp(VectorFormat vform,
705                               LogicVRegister dst,
706                               const LogicVRegister& src1,
707                               const LogicVRegister& src2,
708                               Condition cond) {
709   dst.ClearForWrite(vform);
710   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
711     int64_t  sa = src1.Int(vform, i);
712     int64_t  sb = src2.Int(vform, i);
713     uint64_t ua = src1.Uint(vform, i);
714     uint64_t ub = src2.Uint(vform, i);
715     bool result = false;
716     switch (cond) {
717       case eq: result = (ua == ub); break;
718       case ge: result = (sa >= sb); break;
719       case gt: result = (sa > sb) ; break;
720       case hi: result = (ua > ub) ; break;
721       case hs: result = (ua >= ub); break;
722       case lt: result = (sa < sb) ; break;
723       case le: result = (sa <= sb); break;
724       default: VIXL_UNREACHABLE(); break;
725     }
726     dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
727   }
728   return dst;
729 }
730 
731 
cmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,int imm,Condition cond)732 LogicVRegister Simulator::cmp(VectorFormat vform,
733                               LogicVRegister dst,
734                               const LogicVRegister& src1,
735                               int imm,
736                               Condition cond) {
737   SimVRegister temp;
738   LogicVRegister imm_reg = dup_immediate(vform, temp, imm);
739   return cmp(vform, dst, src1, imm_reg, cond);
740 }
741 
742 
cmptst(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)743 LogicVRegister Simulator::cmptst(VectorFormat vform,
744                                  LogicVRegister dst,
745                                  const LogicVRegister& src1,
746                                  const LogicVRegister& src2) {
747   dst.ClearForWrite(vform);
748   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
749     uint64_t ua = src1.Uint(vform, i);
750     uint64_t ub = src2.Uint(vform, i);
751     dst.SetUint(vform, i, ((ua & ub) != 0) ? MaxUintFromFormat(vform) : 0);
752   }
753   return dst;
754 }
755 
756 
add(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)757 LogicVRegister Simulator::add(VectorFormat vform,
758                               LogicVRegister dst,
759                               const LogicVRegister& src1,
760                               const LogicVRegister& src2) {
761   dst.ClearForWrite(vform);
762   // TODO(all): consider assigning the result of LaneCountFromFormat to a local.
763   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
764     // Test for unsigned saturation.
765     uint64_t ua = src1.UintLeftJustified(vform, i);
766     uint64_t ub = src2.UintLeftJustified(vform, i);
767     uint64_t ur = ua + ub;
768     if (ur < ua) {
769       dst.SetUnsignedSat(i, true);
770     }
771 
772     // Test for signed saturation.
773     int64_t sa = src1.IntLeftJustified(vform, i);
774     int64_t sb = src2.IntLeftJustified(vform, i);
775     int64_t sr = sa + sb;
776     // If the signs of the operands are the same, but different from the result,
777     // there was an overflow.
778     if (((sa >= 0) == (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
779       dst.SetSignedSat(i, sa >= 0);
780     }
781 
782     dst.SetInt(vform, i, src1.Int(vform, i) + src2.Int(vform, i));
783   }
784   return dst;
785 }
786 
787 
addp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)788 LogicVRegister Simulator::addp(VectorFormat vform,
789                                LogicVRegister dst,
790                                const LogicVRegister& src1,
791                                const LogicVRegister& src2) {
792   SimVRegister temp1, temp2;
793   uzp1(vform, temp1, src1, src2);
794   uzp2(vform, temp2, src1, src2);
795   add(vform, dst, temp1, temp2);
796   return dst;
797 }
798 
799 
mla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)800 LogicVRegister Simulator::mla(VectorFormat vform,
801                               LogicVRegister dst,
802                               const LogicVRegister& src1,
803                               const LogicVRegister& src2) {
804   SimVRegister temp;
805   mul(vform, temp, src1, src2);
806   add(vform, dst, dst, temp);
807   return dst;
808 }
809 
810 
mls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)811 LogicVRegister Simulator::mls(VectorFormat vform,
812                               LogicVRegister dst,
813                               const LogicVRegister& src1,
814                               const LogicVRegister& src2) {
815   SimVRegister temp;
816   mul(vform, temp, src1, src2);
817   sub(vform, dst, dst, temp);
818   return dst;
819 }
820 
821 
mul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)822 LogicVRegister Simulator::mul(VectorFormat vform,
823                               LogicVRegister dst,
824                               const LogicVRegister& src1,
825                               const LogicVRegister& src2) {
826   dst.ClearForWrite(vform);
827   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
828     dst.SetUint(vform, i, src1.Uint(vform, i) * src2.Uint(vform, i));
829   }
830   return dst;
831 }
832 
833 
mul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)834 LogicVRegister Simulator::mul(VectorFormat vform,
835                               LogicVRegister dst,
836                               const LogicVRegister& src1,
837                               const LogicVRegister& src2,
838                               int index) {
839   SimVRegister temp;
840   VectorFormat indexform = VectorFormatFillQ(vform);
841   return mul(vform, dst, src1, dup_element(indexform, temp, src2, index));
842 }
843 
844 
mla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)845 LogicVRegister Simulator::mla(VectorFormat vform,
846                               LogicVRegister dst,
847                               const LogicVRegister& src1,
848                               const LogicVRegister& src2,
849                               int index) {
850   SimVRegister temp;
851   VectorFormat indexform = VectorFormatFillQ(vform);
852   return mla(vform, dst, src1, dup_element(indexform, temp, src2, index));
853 }
854 
855 
mls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)856 LogicVRegister Simulator::mls(VectorFormat vform,
857                               LogicVRegister dst,
858                               const LogicVRegister& src1,
859                               const LogicVRegister& src2,
860                               int index) {
861   SimVRegister temp;
862   VectorFormat indexform = VectorFormatFillQ(vform);
863   return mls(vform, dst, src1, dup_element(indexform, temp, src2, index));
864 }
865 
866 
smull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)867 LogicVRegister Simulator::smull(VectorFormat vform,
868                                 LogicVRegister dst,
869                                 const LogicVRegister& src1,
870                                 const LogicVRegister& src2,
871                                 int index) {
872   SimVRegister temp;
873   VectorFormat indexform =
874                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
875   return smull(vform, dst, src1, dup_element(indexform, temp, src2, index));
876 }
877 
878 
smull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)879 LogicVRegister Simulator::smull2(VectorFormat vform,
880                                 LogicVRegister dst,
881                                 const LogicVRegister& src1,
882                                 const LogicVRegister& src2,
883                                 int index) {
884   SimVRegister temp;
885   VectorFormat indexform =
886                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
887   return smull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
888 }
889 
890 
umull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)891 LogicVRegister Simulator::umull(VectorFormat vform,
892                                 LogicVRegister dst,
893                                 const LogicVRegister& src1,
894                                 const LogicVRegister& src2,
895                                 int index) {
896   SimVRegister temp;
897   VectorFormat indexform =
898                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
899   return umull(vform, dst, src1, dup_element(indexform, temp, src2, index));
900 }
901 
902 
umull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)903 LogicVRegister Simulator::umull2(VectorFormat vform,
904                                 LogicVRegister dst,
905                                 const LogicVRegister& src1,
906                                 const LogicVRegister& src2,
907                                 int index) {
908   SimVRegister temp;
909   VectorFormat indexform =
910                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
911   return umull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
912 }
913 
914 
smlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)915 LogicVRegister Simulator::smlal(VectorFormat vform,
916                                 LogicVRegister dst,
917                                 const LogicVRegister& src1,
918                                 const LogicVRegister& src2,
919                                 int index) {
920   SimVRegister temp;
921   VectorFormat indexform =
922                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
923   return smlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
924 }
925 
926 
smlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)927 LogicVRegister Simulator::smlal2(VectorFormat vform,
928                                 LogicVRegister dst,
929                                 const LogicVRegister& src1,
930                                 const LogicVRegister& src2,
931                                 int index) {
932   SimVRegister temp;
933   VectorFormat indexform =
934                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
935   return smlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
936 }
937 
938 
umlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)939 LogicVRegister Simulator::umlal(VectorFormat vform,
940                                 LogicVRegister dst,
941                                 const LogicVRegister& src1,
942                                 const LogicVRegister& src2,
943                                 int index) {
944   SimVRegister temp;
945   VectorFormat indexform =
946                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
947   return umlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
948 }
949 
950 
umlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)951 LogicVRegister Simulator::umlal2(VectorFormat vform,
952                                 LogicVRegister dst,
953                                 const LogicVRegister& src1,
954                                 const LogicVRegister& src2,
955                                 int index) {
956   SimVRegister temp;
957   VectorFormat indexform =
958                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
959   return umlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
960 }
961 
962 
smlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)963 LogicVRegister Simulator::smlsl(VectorFormat vform,
964                                 LogicVRegister dst,
965                                 const LogicVRegister& src1,
966                                 const LogicVRegister& src2,
967                                 int index) {
968   SimVRegister temp;
969   VectorFormat indexform =
970                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
971   return smlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
972 }
973 
974 
smlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)975 LogicVRegister Simulator::smlsl2(VectorFormat vform,
976                                 LogicVRegister dst,
977                                 const LogicVRegister& src1,
978                                 const LogicVRegister& src2,
979                                 int index) {
980   SimVRegister temp;
981   VectorFormat indexform =
982                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
983   return smlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
984 }
985 
986 
umlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)987 LogicVRegister Simulator::umlsl(VectorFormat vform,
988                                 LogicVRegister dst,
989                                 const LogicVRegister& src1,
990                                 const LogicVRegister& src2,
991                                 int index) {
992   SimVRegister temp;
993   VectorFormat indexform =
994                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
995   return umlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
996 }
997 
998 
umlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)999 LogicVRegister Simulator::umlsl2(VectorFormat vform,
1000                                 LogicVRegister dst,
1001                                 const LogicVRegister& src1,
1002                                 const LogicVRegister& src2,
1003                                 int index) {
1004   SimVRegister temp;
1005   VectorFormat indexform =
1006                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1007   return umlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
1008 }
1009 
1010 
sqdmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1011 LogicVRegister Simulator::sqdmull(VectorFormat vform,
1012                                   LogicVRegister dst,
1013                                   const LogicVRegister& src1,
1014                                   const LogicVRegister& src2,
1015                                   int index) {
1016   SimVRegister temp;
1017   VectorFormat indexform =
1018       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1019   return sqdmull(vform, dst, src1, dup_element(indexform, temp, src2, index));
1020 }
1021 
1022 
sqdmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1023 LogicVRegister Simulator::sqdmull2(VectorFormat vform,
1024                                   LogicVRegister dst,
1025                                   const LogicVRegister& src1,
1026                                   const LogicVRegister& src2,
1027                                   int index) {
1028   SimVRegister temp;
1029   VectorFormat indexform =
1030       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1031   return sqdmull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
1032 }
1033 
1034 
sqdmlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1035 LogicVRegister Simulator::sqdmlal(VectorFormat vform,
1036                                   LogicVRegister dst,
1037                                   const LogicVRegister& src1,
1038                                   const LogicVRegister& src2,
1039                                   int index) {
1040   SimVRegister temp;
1041   VectorFormat indexform =
1042       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1043   return sqdmlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
1044 }
1045 
1046 
sqdmlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1047 LogicVRegister Simulator::sqdmlal2(VectorFormat vform,
1048                                   LogicVRegister dst,
1049                                   const LogicVRegister& src1,
1050                                   const LogicVRegister& src2,
1051                                   int index) {
1052   SimVRegister temp;
1053   VectorFormat indexform =
1054       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1055   return sqdmlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
1056 }
1057 
1058 
sqdmlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1059 LogicVRegister Simulator::sqdmlsl(VectorFormat vform,
1060                                   LogicVRegister dst,
1061                                   const LogicVRegister& src1,
1062                                   const LogicVRegister& src2,
1063                                   int index) {
1064   SimVRegister temp;
1065   VectorFormat indexform =
1066       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1067   return sqdmlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
1068 }
1069 
1070 
sqdmlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1071 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
1072                                   LogicVRegister dst,
1073                                   const LogicVRegister& src1,
1074                                   const LogicVRegister& src2,
1075                                   int index) {
1076   SimVRegister temp;
1077   VectorFormat indexform =
1078       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
1079   return sqdmlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
1080 }
1081 
1082 
sqdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1083 LogicVRegister Simulator::sqdmulh(VectorFormat vform,
1084                                   LogicVRegister dst,
1085                                   const LogicVRegister& src1,
1086                                   const LogicVRegister& src2,
1087                                   int index) {
1088   SimVRegister temp;
1089   VectorFormat indexform = VectorFormatFillQ(vform);
1090   return sqdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
1091 }
1092 
1093 
sqrdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)1094 LogicVRegister Simulator::sqrdmulh(VectorFormat vform,
1095                                   LogicVRegister dst,
1096                                   const LogicVRegister& src1,
1097                                   const LogicVRegister& src2,
1098                                   int index) {
1099   SimVRegister temp;
1100   VectorFormat indexform = VectorFormatFillQ(vform);
1101   return sqrdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
1102 }
1103 
1104 
PolynomialMult(uint8_t op1,uint8_t op2)1105 uint16_t Simulator::PolynomialMult(uint8_t op1, uint8_t op2) {
1106   uint16_t result = 0;
1107   uint16_t extended_op2 = op2;
1108   for (int i = 0; i < 8; ++i) {
1109     if ((op1 >> i) & 1) {
1110       result = result ^ (extended_op2 << i);
1111     }
1112   }
1113   return result;
1114 }
1115 
1116 
pmul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1117 LogicVRegister Simulator::pmul(VectorFormat vform,
1118                                LogicVRegister dst,
1119                                const LogicVRegister& src1,
1120                                const LogicVRegister& src2) {
1121   dst.ClearForWrite(vform);
1122   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1123     dst.SetUint(vform, i,
1124                 PolynomialMult(src1.Uint(vform, i), src2.Uint(vform, i)));
1125   }
1126   return dst;
1127 }
1128 
1129 
pmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1130 LogicVRegister Simulator::pmull(VectorFormat vform,
1131                                LogicVRegister dst,
1132                                const LogicVRegister& src1,
1133                                const LogicVRegister& src2) {
1134   VectorFormat vform_src = VectorFormatHalfWidth(vform);
1135   dst.ClearForWrite(vform);
1136   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1137     dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, i),
1138                                          src2.Uint(vform_src, i)));
1139   }
1140   return dst;
1141 }
1142 
1143 
pmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1144 LogicVRegister Simulator::pmull2(VectorFormat vform,
1145                                 LogicVRegister dst,
1146                                 const LogicVRegister& src1,
1147                                 const LogicVRegister& src2) {
1148   VectorFormat vform_src = VectorFormatHalfWidthDoubleLanes(vform);
1149   dst.ClearForWrite(vform);
1150   int lane_count = LaneCountFromFormat(vform);
1151   for (int i = 0; i < lane_count; i++) {
1152     dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, lane_count + i),
1153                                          src2.Uint(vform_src, lane_count + i)));
1154   }
1155   return dst;
1156 }
1157 
1158 
sub(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1159 LogicVRegister Simulator::sub(VectorFormat vform,
1160                               LogicVRegister dst,
1161                               const LogicVRegister& src1,
1162                               const LogicVRegister& src2) {
1163   dst.ClearForWrite(vform);
1164   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1165     // Test for unsigned saturation.
1166     if (src2.Uint(vform, i) > src1.Uint(vform, i)) {
1167       dst.SetUnsignedSat(i, false);
1168     }
1169 
1170     // Test for signed saturation.
1171     int64_t sa = src1.IntLeftJustified(vform, i);
1172     int64_t sb = src2.IntLeftJustified(vform, i);
1173     int64_t sr = sa - sb;
1174     // If the signs of the operands are different, and the sign of the first
1175     // operand doesn't match the result, there was an overflow.
1176     if (((sa >= 0) != (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
1177       dst.SetSignedSat(i, sr < 0);
1178     }
1179 
1180     dst.SetInt(vform, i, src1.Int(vform, i) - src2.Int(vform, i));
1181   }
1182   return dst;
1183 }
1184 
1185 
and_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1186 LogicVRegister Simulator::and_(VectorFormat vform,
1187                                LogicVRegister dst,
1188                                const LogicVRegister& src1,
1189                                const LogicVRegister& src2) {
1190   dst.ClearForWrite(vform);
1191   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1192     dst.SetUint(vform, i, src1.Uint(vform, i) & src2.Uint(vform, i));
1193   }
1194   return dst;
1195 }
1196 
1197 
orr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1198 LogicVRegister Simulator::orr(VectorFormat vform,
1199                               LogicVRegister dst,
1200                               const LogicVRegister& src1,
1201                               const LogicVRegister& src2) {
1202   dst.ClearForWrite(vform);
1203   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1204     dst.SetUint(vform, i, src1.Uint(vform, i) | src2.Uint(vform, i));
1205   }
1206   return dst;
1207 }
1208 
1209 
orn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1210 LogicVRegister Simulator::orn(VectorFormat vform,
1211                               LogicVRegister dst,
1212                               const LogicVRegister& src1,
1213                               const LogicVRegister& src2) {
1214   dst.ClearForWrite(vform);
1215   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1216     dst.SetUint(vform, i, src1.Uint(vform, i) | ~src2.Uint(vform, i));
1217   }
1218   return dst;
1219 }
1220 
1221 
eor(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1222 LogicVRegister Simulator::eor(VectorFormat vform,
1223                               LogicVRegister dst,
1224                               const LogicVRegister& src1,
1225                               const LogicVRegister& src2) {
1226   dst.ClearForWrite(vform);
1227   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1228     dst.SetUint(vform, i, src1.Uint(vform, i) ^ src2.Uint(vform, i));
1229   }
1230   return dst;
1231 }
1232 
1233 
bic(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1234 LogicVRegister Simulator::bic(VectorFormat vform,
1235                               LogicVRegister dst,
1236                               const LogicVRegister& src1,
1237                               const LogicVRegister& src2) {
1238   dst.ClearForWrite(vform);
1239   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1240     dst.SetUint(vform, i, src1.Uint(vform, i) & ~src2.Uint(vform, i));
1241   }
1242   return dst;
1243 }
1244 
1245 
bic(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,uint64_t imm)1246 LogicVRegister Simulator::bic(VectorFormat vform,
1247                               LogicVRegister dst,
1248                               const LogicVRegister& src,
1249                               uint64_t imm) {
1250   uint64_t result[16];
1251   int laneCount = LaneCountFromFormat(vform);
1252   for (int i = 0; i < laneCount; ++i) {
1253     result[i] = src.Uint(vform, i) & ~imm;
1254   }
1255   dst.ClearForWrite(vform);
1256   for (int i = 0; i < laneCount; ++i) {
1257     dst.SetUint(vform, i, result[i]);
1258   }
1259   return dst;
1260 }
1261 
1262 
bif(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1263 LogicVRegister Simulator::bif(VectorFormat vform,
1264                               LogicVRegister dst,
1265                               const LogicVRegister& src1,
1266                               const LogicVRegister& src2) {
1267   dst.ClearForWrite(vform);
1268   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1269     uint64_t operand1 = dst.Uint(vform, i);
1270     uint64_t operand2 = ~src2.Uint(vform, i);
1271     uint64_t operand3 = src1.Uint(vform, i);
1272     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1273     dst.SetUint(vform, i, result);
1274   }
1275   return dst;
1276 }
1277 
1278 
bit(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1279 LogicVRegister Simulator::bit(VectorFormat vform,
1280                               LogicVRegister dst,
1281                               const LogicVRegister& src1,
1282                               const LogicVRegister& src2) {
1283   dst.ClearForWrite(vform);
1284   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1285     uint64_t operand1 = dst.Uint(vform, i);
1286     uint64_t operand2 = src2.Uint(vform, i);
1287     uint64_t operand3 = src1.Uint(vform, i);
1288     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1289     dst.SetUint(vform, i, result);
1290   }
1291   return dst;
1292 }
1293 
1294 
bsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1295 LogicVRegister Simulator::bsl(VectorFormat vform,
1296                               LogicVRegister dst,
1297                               const LogicVRegister& src1,
1298                               const LogicVRegister& src2) {
1299   dst.ClearForWrite(vform);
1300   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1301     uint64_t operand1 = src2.Uint(vform, i);
1302     uint64_t operand2 = dst.Uint(vform, i);
1303     uint64_t operand3 = src1.Uint(vform, i);
1304     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1305     dst.SetUint(vform, i, result);
1306   }
1307   return dst;
1308 }
1309 
1310 
sminmax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool max)1311 LogicVRegister Simulator::sminmax(VectorFormat vform,
1312                                   LogicVRegister dst,
1313                                   const LogicVRegister& src1,
1314                                   const LogicVRegister& src2,
1315                                   bool max) {
1316   dst.ClearForWrite(vform);
1317   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1318     int64_t src1_val = src1.Int(vform, i);
1319     int64_t src2_val = src2.Int(vform, i);
1320     int64_t dst_val;
1321     if (max == true) {
1322       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1323     } else {
1324       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1325     }
1326     dst.SetInt(vform, i, dst_val);
1327   }
1328   return dst;
1329 }
1330 
1331 
smax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1332 LogicVRegister Simulator::smax(VectorFormat vform,
1333                                LogicVRegister dst,
1334                                const LogicVRegister& src1,
1335                                const LogicVRegister& src2) {
1336   return sminmax(vform, dst, src1, src2, true);
1337 }
1338 
1339 
smin(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1340 LogicVRegister Simulator::smin(VectorFormat vform,
1341                                LogicVRegister dst,
1342                                const LogicVRegister& src1,
1343                                const LogicVRegister& src2) {
1344   return sminmax(vform, dst, src1, src2, false);
1345 }
1346 
1347 
sminmaxp(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,bool max)1348 LogicVRegister Simulator::sminmaxp(VectorFormat vform,
1349                                    LogicVRegister dst,
1350                                    int dst_index,
1351                                    const LogicVRegister& src,
1352                                    bool max) {
1353   for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
1354     int64_t src1_val = src.Int(vform, i);
1355     int64_t src2_val = src.Int(vform, i + 1);
1356     int64_t dst_val;
1357     if (max == true) {
1358       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1359     } else {
1360       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1361     }
1362     dst.SetInt(vform, dst_index + (i >> 1), dst_val);
1363   }
1364   return dst;
1365 }
1366 
1367 
smaxp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1368 LogicVRegister Simulator::smaxp(VectorFormat vform,
1369                                 LogicVRegister dst,
1370                                 const LogicVRegister& src1,
1371                                 const LogicVRegister& src2) {
1372   dst.ClearForWrite(vform);
1373   sminmaxp(vform, dst, 0, src1, true);
1374   sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
1375   return dst;
1376 }
1377 
1378 
sminp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1379 LogicVRegister Simulator::sminp(VectorFormat vform,
1380                                 LogicVRegister dst,
1381                                 const LogicVRegister& src1,
1382                                 const LogicVRegister& src2) {
1383   dst.ClearForWrite(vform);
1384   sminmaxp(vform, dst, 0, src1, false);
1385   sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
1386   return dst;
1387 }
1388 
1389 
addp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1390 LogicVRegister Simulator::addp(VectorFormat vform,
1391                                LogicVRegister dst,
1392                                const LogicVRegister& src) {
1393   VIXL_ASSERT(vform == kFormatD);
1394 
1395   int64_t dst_val = src.Int(kFormat2D, 0) + src.Int(kFormat2D, 1);
1396   dst.ClearForWrite(vform);
1397   dst.SetInt(vform, 0, dst_val);
1398   return dst;
1399 }
1400 
1401 
addv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1402 LogicVRegister Simulator::addv(VectorFormat vform,
1403                                LogicVRegister dst,
1404                                const LogicVRegister& src) {
1405   VectorFormat vform_dst
1406     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
1407 
1408 
1409   int64_t dst_val = 0;
1410   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1411     dst_val += src.Int(vform, i);
1412   }
1413 
1414   dst.ClearForWrite(vform_dst);
1415   dst.SetInt(vform_dst, 0, dst_val);
1416   return dst;
1417 }
1418 
1419 
saddlv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1420 LogicVRegister Simulator::saddlv(VectorFormat vform,
1421                                  LogicVRegister dst,
1422                                  const LogicVRegister& src) {
1423   VectorFormat vform_dst
1424     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1425 
1426   int64_t dst_val = 0;
1427   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1428     dst_val += src.Int(vform, i);
1429   }
1430 
1431   dst.ClearForWrite(vform_dst);
1432   dst.SetInt(vform_dst, 0, dst_val);
1433   return dst;
1434 }
1435 
1436 
uaddlv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1437 LogicVRegister Simulator::uaddlv(VectorFormat vform,
1438                                  LogicVRegister dst,
1439                                  const LogicVRegister& src) {
1440   VectorFormat vform_dst
1441     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1442 
1443   uint64_t dst_val = 0;
1444   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1445     dst_val += src.Uint(vform, i);
1446   }
1447 
1448   dst.ClearForWrite(vform_dst);
1449   dst.SetUint(vform_dst, 0, dst_val);
1450   return dst;
1451 }
1452 
1453 
sminmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool max)1454 LogicVRegister Simulator::sminmaxv(VectorFormat vform,
1455                                    LogicVRegister dst,
1456                                    const LogicVRegister& src,
1457                                    bool max) {
1458   dst.ClearForWrite(vform);
1459   int64_t dst_val = max ? INT64_MIN : INT64_MAX;
1460   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1461     dst.SetInt(vform, i, 0);
1462     int64_t src_val = src.Int(vform, i);
1463     if (max == true) {
1464       dst_val = (src_val > dst_val) ? src_val : dst_val;
1465     } else {
1466       dst_val = (src_val < dst_val) ? src_val : dst_val;
1467     }
1468   }
1469   dst.SetInt(vform, 0, dst_val);
1470   return dst;
1471 }
1472 
1473 
smaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1474 LogicVRegister Simulator::smaxv(VectorFormat vform,
1475                                 LogicVRegister dst,
1476                                 const LogicVRegister& src) {
1477   sminmaxv(vform, dst, src, true);
1478   return dst;
1479 }
1480 
1481 
sminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1482 LogicVRegister Simulator::sminv(VectorFormat vform,
1483                                 LogicVRegister dst,
1484                                 const LogicVRegister& src) {
1485   sminmaxv(vform, dst, src, false);
1486   return dst;
1487 }
1488 
1489 
uminmax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool max)1490 LogicVRegister Simulator::uminmax(VectorFormat vform,
1491                                   LogicVRegister dst,
1492                                   const LogicVRegister& src1,
1493                                   const LogicVRegister& src2,
1494                                   bool max) {
1495   dst.ClearForWrite(vform);
1496   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1497     uint64_t src1_val = src1.Uint(vform, i);
1498     uint64_t src2_val = src2.Uint(vform, i);
1499     uint64_t dst_val;
1500     if (max == true) {
1501       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1502     } else {
1503       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1504     }
1505     dst.SetUint(vform, i, dst_val);
1506   }
1507   return dst;
1508 }
1509 
1510 
umax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1511 LogicVRegister Simulator::umax(VectorFormat vform,
1512                                LogicVRegister dst,
1513                                const LogicVRegister& src1,
1514                                const LogicVRegister& src2) {
1515   return uminmax(vform, dst, src1, src2, true);
1516 }
1517 
1518 
umin(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1519 LogicVRegister Simulator::umin(VectorFormat vform,
1520                                LogicVRegister dst,
1521                                const LogicVRegister& src1,
1522                                const LogicVRegister& src2) {
1523   return uminmax(vform, dst, src1, src2, false);
1524 }
1525 
1526 
uminmaxp(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,bool max)1527 LogicVRegister Simulator::uminmaxp(VectorFormat vform,
1528                                    LogicVRegister dst,
1529                                    int dst_index,
1530                                    const LogicVRegister& src,
1531                                    bool max) {
1532   for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
1533     uint64_t src1_val = src.Uint(vform, i);
1534     uint64_t src2_val = src.Uint(vform, i + 1);
1535     uint64_t dst_val;
1536     if (max == true) {
1537       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1538     } else {
1539       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1540     }
1541     dst.SetUint(vform, dst_index + (i >> 1), dst_val);
1542   }
1543   return dst;
1544 }
1545 
1546 
umaxp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1547 LogicVRegister Simulator::umaxp(VectorFormat vform,
1548                                 LogicVRegister dst,
1549                                 const LogicVRegister& src1,
1550                                 const LogicVRegister& src2) {
1551   dst.ClearForWrite(vform);
1552   uminmaxp(vform, dst, 0, src1, true);
1553   uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
1554   return dst;
1555 }
1556 
1557 
uminp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1558 LogicVRegister Simulator::uminp(VectorFormat vform,
1559                                 LogicVRegister dst,
1560                                 const LogicVRegister& src1,
1561                                 const LogicVRegister& src2) {
1562   dst.ClearForWrite(vform);
1563   uminmaxp(vform, dst, 0, src1, false);
1564   uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
1565   return dst;
1566 }
1567 
1568 
uminmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool max)1569 LogicVRegister Simulator::uminmaxv(VectorFormat vform,
1570                                    LogicVRegister dst,
1571                                    const LogicVRegister& src,
1572                                    bool max) {
1573   dst.ClearForWrite(vform);
1574   uint64_t dst_val = max ? 0 : UINT64_MAX;
1575   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1576     dst.SetUint(vform, i, 0);
1577     uint64_t src_val = src.Uint(vform, i);
1578     if (max == true) {
1579       dst_val = (src_val > dst_val) ? src_val : dst_val;
1580     } else {
1581       dst_val = (src_val < dst_val) ? src_val : dst_val;
1582     }
1583   }
1584   dst.SetUint(vform, 0, dst_val);
1585   return dst;
1586 }
1587 
1588 
umaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1589 LogicVRegister Simulator::umaxv(VectorFormat vform,
1590                                 LogicVRegister dst,
1591                                 const LogicVRegister& src) {
1592   uminmaxv(vform, dst, src, true);
1593   return dst;
1594 }
1595 
1596 
uminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1597 LogicVRegister Simulator::uminv(VectorFormat vform,
1598                                 LogicVRegister dst,
1599                                 const LogicVRegister& src) {
1600   uminmaxv(vform, dst, src, false);
1601   return dst;
1602 }
1603 
1604 
shl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1605 LogicVRegister Simulator::shl(VectorFormat vform,
1606                               LogicVRegister dst,
1607                               const LogicVRegister& src,
1608                               int shift) {
1609   VIXL_ASSERT(shift >= 0);
1610   SimVRegister temp;
1611   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1612   return ushl(vform, dst, src, shiftreg);
1613 }
1614 
1615 
sshll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1616 LogicVRegister Simulator::sshll(VectorFormat vform,
1617                                 LogicVRegister dst,
1618                                 const LogicVRegister& src,
1619                                 int shift) {
1620   VIXL_ASSERT(shift >= 0);
1621   SimVRegister temp1, temp2;
1622   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1623   LogicVRegister extendedreg = sxtl(vform, temp2, src);
1624   return sshl(vform, dst, extendedreg, shiftreg);
1625 }
1626 
1627 
sshll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1628 LogicVRegister Simulator::sshll2(VectorFormat vform,
1629                                  LogicVRegister dst,
1630                                  const LogicVRegister& src,
1631                                  int shift) {
1632   VIXL_ASSERT(shift >= 0);
1633   SimVRegister temp1, temp2;
1634   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1635   LogicVRegister extendedreg = sxtl2(vform, temp2, src);
1636   return sshl(vform, dst, extendedreg, shiftreg);
1637 }
1638 
1639 
shll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1640 LogicVRegister Simulator::shll(VectorFormat vform,
1641                                LogicVRegister dst,
1642                                const LogicVRegister& src) {
1643   int shift = LaneSizeInBitsFromFormat(vform) / 2;
1644   return sshll(vform, dst, src, shift);
1645 }
1646 
1647 
shll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1648 LogicVRegister Simulator::shll2(VectorFormat vform,
1649                                 LogicVRegister dst,
1650                                 const LogicVRegister& src) {
1651   int shift = LaneSizeInBitsFromFormat(vform) / 2;
1652   return sshll2(vform, dst, src, shift);
1653 }
1654 
1655 
ushll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1656 LogicVRegister Simulator::ushll(VectorFormat vform,
1657                                 LogicVRegister dst,
1658                                 const LogicVRegister& src,
1659                                 int shift) {
1660   VIXL_ASSERT(shift >= 0);
1661   SimVRegister temp1, temp2;
1662   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1663   LogicVRegister extendedreg = uxtl(vform, temp2, src);
1664   return ushl(vform, dst, extendedreg, shiftreg);
1665 }
1666 
1667 
ushll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1668 LogicVRegister Simulator::ushll2(VectorFormat vform,
1669                                  LogicVRegister dst,
1670                                  const LogicVRegister& src,
1671                                  int shift) {
1672   VIXL_ASSERT(shift >= 0);
1673   SimVRegister temp1, temp2;
1674   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1675   LogicVRegister extendedreg = uxtl2(vform, temp2, src);
1676   return ushl(vform, dst, extendedreg, shiftreg);
1677 }
1678 
1679 
sli(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1680 LogicVRegister Simulator::sli(VectorFormat vform,
1681                               LogicVRegister dst,
1682                               const LogicVRegister& src,
1683                               int shift) {
1684   dst.ClearForWrite(vform);
1685   int laneCount = LaneCountFromFormat(vform);
1686   for (int i = 0; i < laneCount; i++) {
1687     uint64_t src_lane = src.Uint(vform, i);
1688     uint64_t dst_lane = dst.Uint(vform, i);
1689     uint64_t shifted = src_lane << shift;
1690     uint64_t mask = MaxUintFromFormat(vform) << shift;
1691     dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
1692   }
1693   return dst;
1694 }
1695 
1696 
sqshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1697 LogicVRegister Simulator::sqshl(VectorFormat vform,
1698                                 LogicVRegister dst,
1699                                 const LogicVRegister& src,
1700                                 int shift) {
1701   VIXL_ASSERT(shift >= 0);
1702   SimVRegister temp;
1703   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1704   return sshl(vform, dst, src, shiftreg).SignedSaturate(vform);
1705 }
1706 
1707 
uqshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1708 LogicVRegister Simulator::uqshl(VectorFormat vform,
1709                                 LogicVRegister dst,
1710                                 const LogicVRegister& src,
1711                                 int shift) {
1712   VIXL_ASSERT(shift >= 0);
1713   SimVRegister temp;
1714   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1715   return ushl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1716 }
1717 
1718 
sqshlu(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1719 LogicVRegister Simulator::sqshlu(VectorFormat vform,
1720                                  LogicVRegister dst,
1721                                  const LogicVRegister& src,
1722                                  int shift) {
1723   VIXL_ASSERT(shift >= 0);
1724   SimVRegister temp;
1725   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1726   return sshl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1727 }
1728 
1729 
sri(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1730 LogicVRegister Simulator::sri(VectorFormat vform,
1731                               LogicVRegister dst,
1732                               const LogicVRegister& src,
1733                               int shift) {
1734   dst.ClearForWrite(vform);
1735   int laneCount = LaneCountFromFormat(vform);
1736   VIXL_ASSERT((shift > 0) &&
1737               (shift <= static_cast<int>(LaneSizeInBitsFromFormat(vform))));
1738   for (int i = 0; i < laneCount; i++) {
1739     uint64_t src_lane = src.Uint(vform, i);
1740     uint64_t dst_lane = dst.Uint(vform, i);
1741     uint64_t shifted;
1742     uint64_t mask;
1743     if (shift == 64) {
1744       shifted = 0;
1745       mask = 0;
1746     } else {
1747       shifted = src_lane >> shift;
1748       mask = MaxUintFromFormat(vform) >> shift;
1749     }
1750     dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
1751   }
1752   return dst;
1753 }
1754 
1755 
ushr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1756 LogicVRegister Simulator::ushr(VectorFormat vform,
1757                                LogicVRegister dst,
1758                                const LogicVRegister& src,
1759                                int shift) {
1760   VIXL_ASSERT(shift >= 0);
1761   SimVRegister temp;
1762   LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1763   return ushl(vform, dst, src, shiftreg);
1764 }
1765 
1766 
sshr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1767 LogicVRegister Simulator::sshr(VectorFormat vform,
1768                                LogicVRegister dst,
1769                                const LogicVRegister& src,
1770                                int shift) {
1771   VIXL_ASSERT(shift >= 0);
1772   SimVRegister temp;
1773   LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1774   return sshl(vform, dst, src, shiftreg);
1775 }
1776 
1777 
ssra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1778 LogicVRegister Simulator::ssra(VectorFormat vform,
1779                                LogicVRegister dst,
1780                                const LogicVRegister& src,
1781                                int shift) {
1782   SimVRegister temp;
1783   LogicVRegister shifted_reg = sshr(vform, temp, src, shift);
1784   return add(vform, dst, dst, shifted_reg);
1785 }
1786 
1787 
usra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1788 LogicVRegister Simulator::usra(VectorFormat vform,
1789                                LogicVRegister dst,
1790                                const LogicVRegister& src,
1791                                int shift) {
1792   SimVRegister temp;
1793   LogicVRegister shifted_reg = ushr(vform, temp, src, shift);
1794   return add(vform, dst, dst, shifted_reg);
1795 }
1796 
1797 
srsra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1798 LogicVRegister Simulator::srsra(VectorFormat vform,
1799                                 LogicVRegister dst,
1800                                 const LogicVRegister& src,
1801                                 int shift) {
1802   SimVRegister temp;
1803   LogicVRegister shifted_reg = sshr(vform, temp, src, shift).Round(vform);
1804   return add(vform, dst, dst, shifted_reg);
1805 }
1806 
1807 
ursra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1808 LogicVRegister Simulator::ursra(VectorFormat vform,
1809                                 LogicVRegister dst,
1810                                 const LogicVRegister& src,
1811                                 int shift) {
1812   SimVRegister temp;
1813   LogicVRegister shifted_reg = ushr(vform, temp, src, shift).Round(vform);
1814   return add(vform, dst, dst, shifted_reg);
1815 }
1816 
1817 
cls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1818 LogicVRegister Simulator::cls(VectorFormat vform,
1819                               LogicVRegister dst,
1820                               const LogicVRegister& src) {
1821   uint64_t result[16];
1822   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1823   int laneCount = LaneCountFromFormat(vform);
1824   for (int i = 0; i < laneCount; i++) {
1825     result[i] = CountLeadingSignBits(src.Int(vform, i), laneSizeInBits);
1826   }
1827 
1828   dst.ClearForWrite(vform);
1829   for (int i = 0; i < laneCount; ++i) {
1830     dst.SetUint(vform, i, result[i]);
1831   }
1832   return dst;
1833 }
1834 
1835 
clz(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1836 LogicVRegister Simulator::clz(VectorFormat vform,
1837                               LogicVRegister dst,
1838                               const LogicVRegister& src) {
1839   uint64_t result[16];
1840   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1841   int laneCount = LaneCountFromFormat(vform);
1842   for (int i = 0; i < laneCount; i++) {
1843     result[i] = CountLeadingZeros(src.Uint(vform, i), laneSizeInBits);
1844   }
1845 
1846   dst.ClearForWrite(vform);
1847   for (int i = 0; i < laneCount; ++i) {
1848     dst.SetUint(vform, i, result[i]);
1849   }
1850   return dst;
1851 }
1852 
1853 
cnt(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1854 LogicVRegister Simulator::cnt(VectorFormat vform,
1855                               LogicVRegister dst,
1856                               const LogicVRegister& src) {
1857   uint64_t result[16];
1858   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1859   int laneCount = LaneCountFromFormat(vform);
1860   for (int i = 0; i < laneCount; i++) {
1861     uint64_t value = src.Uint(vform, i);
1862     result[i] = 0;
1863     for (int j = 0; j < laneSizeInBits; j++) {
1864       result[i] += (value & 1);
1865       value >>= 1;
1866     }
1867   }
1868 
1869   dst.ClearForWrite(vform);
1870   for (int i = 0; i < laneCount; ++i) {
1871     dst.SetUint(vform, i, result[i]);
1872   }
1873   return dst;
1874 }
1875 
1876 
sshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1877 LogicVRegister Simulator::sshl(VectorFormat vform,
1878                                LogicVRegister dst,
1879                                const LogicVRegister& src1,
1880                                const LogicVRegister& src2) {
1881   dst.ClearForWrite(vform);
1882   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1883     int8_t shift_val = src2.Int(vform, i);
1884     int64_t lj_src_val = src1.IntLeftJustified(vform, i);
1885 
1886     // Set signed saturation state.
1887     if ((shift_val > CountLeadingSignBits(lj_src_val)) &&
1888         (lj_src_val != 0)) {
1889       dst.SetSignedSat(i, lj_src_val >= 0);
1890     }
1891 
1892     // Set unsigned saturation state.
1893     if (lj_src_val < 0) {
1894       dst.SetUnsignedSat(i, false);
1895     } else if ((shift_val > CountLeadingZeros(lj_src_val)) &&
1896                (lj_src_val != 0)) {
1897       dst.SetUnsignedSat(i, true);
1898     }
1899 
1900     int64_t src_val = src1.Int(vform, i);
1901     if (shift_val > 63) {
1902       dst.SetInt(vform, i, 0);
1903     } else if (shift_val < -63) {
1904       dst.SetRounding(i, src_val < 0);
1905       dst.SetInt(vform, i, (src_val < 0) ? -1 : 0);
1906     } else {
1907       if (shift_val < 0) {
1908         // Set rounding state. Rounding only needed on right shifts.
1909         if (((src_val >> (-shift_val - 1)) & 1) == 1) {
1910           dst.SetRounding(i, true);
1911         }
1912         src_val >>= -shift_val;
1913       } else {
1914         src_val <<= shift_val;
1915       }
1916       dst.SetInt(vform, i, src_val);
1917     }
1918   }
1919   return dst;
1920 }
1921 
1922 
ushl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1923 LogicVRegister Simulator::ushl(VectorFormat vform,
1924                                LogicVRegister dst,
1925                                const LogicVRegister& src1,
1926                                const LogicVRegister& src2) {
1927   dst.ClearForWrite(vform);
1928   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1929     int8_t shift_val = src2.Int(vform, i);
1930     uint64_t lj_src_val = src1.UintLeftJustified(vform, i);
1931 
1932     // Set saturation state.
1933     if ((shift_val > CountLeadingZeros(lj_src_val)) && (lj_src_val != 0)) {
1934       dst.SetUnsignedSat(i, true);
1935     }
1936 
1937     uint64_t src_val = src1.Uint(vform, i);
1938     if ((shift_val > 63) || (shift_val < -64)) {
1939       dst.SetUint(vform, i, 0);
1940     } else {
1941       if (shift_val < 0) {
1942         // Set rounding state. Rounding only needed on right shifts.
1943         if (((src_val >> (-shift_val - 1)) & 1) == 1) {
1944           dst.SetRounding(i, true);
1945         }
1946 
1947         if (shift_val == -64) {
1948           src_val = 0;
1949         } else {
1950           src_val >>= -shift_val;
1951         }
1952       } else {
1953         src_val <<= shift_val;
1954       }
1955       dst.SetUint(vform, i, src_val);
1956     }
1957   }
1958   return dst;
1959 }
1960 
1961 
neg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1962 LogicVRegister Simulator::neg(VectorFormat vform,
1963                               LogicVRegister dst,
1964                               const LogicVRegister& src) {
1965   dst.ClearForWrite(vform);
1966   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1967     // Test for signed saturation.
1968     int64_t sa = src.Int(vform, i);
1969     if (sa == MinIntFromFormat(vform)) {
1970       dst.SetSignedSat(i, true);
1971     }
1972     dst.SetInt(vform, i, -sa);
1973   }
1974   return dst;
1975 }
1976 
1977 
suqadd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1978 LogicVRegister Simulator::suqadd(VectorFormat vform,
1979                                  LogicVRegister dst,
1980                                  const LogicVRegister& src) {
1981   dst.ClearForWrite(vform);
1982   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1983     int64_t  sa = dst.IntLeftJustified(vform, i);
1984     uint64_t ub = src.UintLeftJustified(vform, i);
1985     int64_t  sr = sa + ub;
1986 
1987     if (sr < sa) {  // Test for signed positive saturation.
1988       dst.SetInt(vform, i, MaxIntFromFormat(vform));
1989     } else {
1990       dst.SetInt(vform, i, dst.Int(vform, i) + src.Int(vform, i));
1991     }
1992   }
1993   return dst;
1994 }
1995 
1996 
usqadd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1997 LogicVRegister Simulator::usqadd(VectorFormat vform,
1998                                  LogicVRegister dst,
1999                                  const LogicVRegister& src) {
2000   dst.ClearForWrite(vform);
2001   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2002     uint64_t  ua = dst.UintLeftJustified(vform, i);
2003     int64_t   sb = src.IntLeftJustified(vform, i);
2004     uint64_t  ur = ua + sb;
2005 
2006     if ((sb > 0) && (ur <= ua)) {
2007       dst.SetUint(vform, i, MaxUintFromFormat(vform));  // Positive saturation.
2008     } else if ((sb < 0) && (ur >= ua)) {
2009       dst.SetUint(vform, i, 0);                         // Negative saturation.
2010     } else {
2011       dst.SetUint(vform, i, dst.Uint(vform, i) + src.Int(vform, i));
2012     }
2013   }
2014   return dst;
2015 }
2016 
2017 
abs(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2018 LogicVRegister Simulator::abs(VectorFormat vform,
2019                               LogicVRegister dst,
2020                               const LogicVRegister& src) {
2021   dst.ClearForWrite(vform);
2022   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2023     // Test for signed saturation.
2024     int64_t sa = src.Int(vform, i);
2025     if (sa == MinIntFromFormat(vform)) {
2026       dst.SetSignedSat(i, true);
2027     }
2028     if (sa < 0) {
2029       dst.SetInt(vform, i, -sa);
2030     } else {
2031       dst.SetInt(vform, i, sa);
2032     }
2033   }
2034   return dst;
2035 }
2036 
2037 
extractnarrow(VectorFormat dstform,LogicVRegister dst,bool dstIsSigned,const LogicVRegister & src,bool srcIsSigned)2038 LogicVRegister Simulator::extractnarrow(VectorFormat dstform,
2039                                         LogicVRegister dst,
2040                                         bool dstIsSigned,
2041                                         const LogicVRegister& src,
2042                                         bool srcIsSigned) {
2043   bool upperhalf = false;
2044   VectorFormat srcform = kFormatUndefined;
2045   int64_t  ssrc[8];
2046   uint64_t usrc[8];
2047 
2048   switch (dstform) {
2049     case kFormat8B : upperhalf = false; srcform = kFormat8H; break;
2050     case kFormat16B: upperhalf = true;  srcform = kFormat8H; break;
2051     case kFormat4H : upperhalf = false; srcform = kFormat4S; break;
2052     case kFormat8H : upperhalf = true;  srcform = kFormat4S; break;
2053     case kFormat2S : upperhalf = false; srcform = kFormat2D; break;
2054     case kFormat4S : upperhalf = true;  srcform = kFormat2D; break;
2055     case kFormatB  : upperhalf = false; srcform = kFormatH;  break;
2056     case kFormatH  : upperhalf = false; srcform = kFormatS;  break;
2057     case kFormatS  : upperhalf = false; srcform = kFormatD;  break;
2058     default:VIXL_UNIMPLEMENTED();
2059   }
2060 
2061   for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
2062     ssrc[i] = src.Int(srcform, i);
2063     usrc[i] = src.Uint(srcform, i);
2064   }
2065 
2066   int offset;
2067   if (upperhalf) {
2068     offset = LaneCountFromFormat(dstform) / 2;
2069   } else {
2070     offset = 0;
2071     dst.ClearForWrite(dstform);
2072   }
2073 
2074   for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
2075     // Test for signed saturation
2076     if (ssrc[i] > MaxIntFromFormat(dstform)) {
2077       dst.SetSignedSat(offset + i, true);
2078     } else if (ssrc[i] < MinIntFromFormat(dstform)) {
2079       dst.SetSignedSat(offset + i, false);
2080     }
2081 
2082     // Test for unsigned saturation
2083     if (srcIsSigned) {
2084       if (ssrc[i] > static_cast<int64_t>(MaxUintFromFormat(dstform))) {
2085         dst.SetUnsignedSat(offset + i, true);
2086       } else if (ssrc[i] < 0) {
2087         dst.SetUnsignedSat(offset + i, false);
2088       }
2089     } else {
2090       if (usrc[i] > MaxUintFromFormat(dstform)) {
2091         dst.SetUnsignedSat(offset + i, true);
2092       }
2093     }
2094 
2095     int64_t result;
2096     if (srcIsSigned) {
2097       result = ssrc[i] & MaxUintFromFormat(dstform);
2098     } else {
2099       result = usrc[i] & MaxUintFromFormat(dstform);
2100     }
2101 
2102     if (dstIsSigned) {
2103       dst.SetInt(dstform, offset + i, result);
2104     } else {
2105       dst.SetUint(dstform, offset + i, result);
2106     }
2107   }
2108   return dst;
2109 }
2110 
2111 
xtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2112 LogicVRegister Simulator::xtn(VectorFormat vform,
2113                               LogicVRegister dst,
2114                               const LogicVRegister& src) {
2115   return extractnarrow(vform, dst, true, src, true);
2116 }
2117 
2118 
sqxtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2119 LogicVRegister Simulator::sqxtn(VectorFormat vform,
2120                                 LogicVRegister dst,
2121                                 const LogicVRegister& src) {
2122   return extractnarrow(vform, dst, true, src, true).SignedSaturate(vform);
2123 }
2124 
2125 
sqxtun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2126 LogicVRegister Simulator::sqxtun(VectorFormat vform,
2127                                  LogicVRegister dst,
2128                                  const LogicVRegister& src) {
2129   return extractnarrow(vform, dst, false, src, true).UnsignedSaturate(vform);
2130 }
2131 
2132 
uqxtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2133 LogicVRegister Simulator::uqxtn(VectorFormat vform,
2134                                 LogicVRegister dst,
2135                                 const LogicVRegister& src) {
2136   return extractnarrow(vform, dst, false, src, false).UnsignedSaturate(vform);
2137 }
2138 
2139 
absdiff(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool issigned)2140 LogicVRegister Simulator::absdiff(VectorFormat vform,
2141                                   LogicVRegister dst,
2142                                   const LogicVRegister& src1,
2143                                   const LogicVRegister& src2,
2144                                   bool issigned) {
2145   dst.ClearForWrite(vform);
2146   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2147     if (issigned) {
2148       int64_t sr = src1.Int(vform, i) - src2.Int(vform, i);
2149       sr = sr > 0 ? sr : -sr;
2150       dst.SetInt(vform, i, sr);
2151     } else {
2152       int64_t sr = src1.Uint(vform, i) - src2.Uint(vform, i);
2153       sr = sr > 0 ? sr : -sr;
2154       dst.SetUint(vform, i, sr);
2155     }
2156   }
2157   return dst;
2158 }
2159 
2160 
saba(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2161 LogicVRegister Simulator::saba(VectorFormat vform,
2162                                LogicVRegister dst,
2163                                const LogicVRegister& src1,
2164                                const LogicVRegister& src2) {
2165   SimVRegister temp;
2166   dst.ClearForWrite(vform);
2167   absdiff(vform, temp, src1, src2, true);
2168   add(vform, dst, dst, temp);
2169   return dst;
2170 }
2171 
2172 
uaba(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2173 LogicVRegister Simulator::uaba(VectorFormat vform,
2174                                LogicVRegister dst,
2175                                const LogicVRegister& src1,
2176                                const LogicVRegister& src2) {
2177   SimVRegister temp;
2178   dst.ClearForWrite(vform);
2179   absdiff(vform, temp, src1, src2, false);
2180   add(vform, dst, dst, temp);
2181   return dst;
2182 }
2183 
2184 
not_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2185 LogicVRegister Simulator::not_(VectorFormat vform,
2186                                LogicVRegister dst,
2187                                const LogicVRegister& src) {
2188   dst.ClearForWrite(vform);
2189   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2190     dst.SetUint(vform, i, ~src.Uint(vform, i));
2191   }
2192   return dst;
2193 }
2194 
2195 
rbit(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2196 LogicVRegister Simulator::rbit(VectorFormat vform,
2197                                LogicVRegister dst,
2198                                const LogicVRegister& src) {
2199   uint64_t result[16];
2200   int laneCount = LaneCountFromFormat(vform);
2201   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
2202   uint64_t reversed_value;
2203   uint64_t value;
2204   for (int i = 0; i < laneCount; i++) {
2205     value = src.Uint(vform, i);
2206     reversed_value = 0;
2207     for (int j = 0; j < laneSizeInBits; j++) {
2208       reversed_value = (reversed_value << 1) | (value & 1);
2209       value >>= 1;
2210     }
2211     result[i] = reversed_value;
2212   }
2213 
2214   dst.ClearForWrite(vform);
2215   for (int i = 0; i < laneCount; ++i) {
2216     dst.SetUint(vform, i, result[i]);
2217   }
2218   return dst;
2219 }
2220 
2221 
rev(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int revSize)2222 LogicVRegister Simulator::rev(VectorFormat vform,
2223                               LogicVRegister dst,
2224                               const LogicVRegister& src,
2225                               int revSize) {
2226   uint64_t result[16];
2227   int laneCount = LaneCountFromFormat(vform);
2228   int laneSize = LaneSizeInBytesFromFormat(vform);
2229   int lanesPerLoop =  revSize / laneSize;
2230   for (int i = 0; i < laneCount; i += lanesPerLoop) {
2231     for (int j = 0; j < lanesPerLoop; j++) {
2232       result[i + lanesPerLoop - 1 - j] = src.Uint(vform, i + j);
2233     }
2234   }
2235   dst.ClearForWrite(vform);
2236   for (int i = 0; i < laneCount; ++i) {
2237     dst.SetUint(vform, i, result[i]);
2238   }
2239   return dst;
2240 }
2241 
2242 
rev16(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2243 LogicVRegister Simulator::rev16(VectorFormat vform,
2244                                 LogicVRegister dst,
2245                                 const LogicVRegister& src) {
2246   return rev(vform, dst, src, 2);
2247 }
2248 
2249 
rev32(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2250 LogicVRegister Simulator::rev32(VectorFormat vform,
2251                                 LogicVRegister dst,
2252                                 const LogicVRegister& src) {
2253   return rev(vform, dst, src, 4);
2254 }
2255 
2256 
rev64(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2257 LogicVRegister Simulator::rev64(VectorFormat vform,
2258                                 LogicVRegister dst,
2259                                 const LogicVRegister& src) {
2260   return rev(vform, dst, src, 8);
2261 }
2262 
2263 
addlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool is_signed,bool do_accumulate)2264 LogicVRegister Simulator::addlp(VectorFormat vform,
2265                                  LogicVRegister dst,
2266                                  const LogicVRegister& src,
2267                                  bool is_signed,
2268                                  bool do_accumulate) {
2269   VectorFormat vformsrc = VectorFormatHalfWidthDoubleLanes(vform);
2270 
2271   int64_t  sr[16];
2272   uint64_t ur[16];
2273 
2274   int laneCount = LaneCountFromFormat(vform);
2275   for (int i = 0; i < laneCount; ++i) {
2276     if (is_signed) {
2277       sr[i] = src.Int(vformsrc, 2 * i) + src.Int(vformsrc, 2 * i + 1);
2278     } else {
2279       ur[i] = src.Uint(vformsrc, 2 * i) + src.Uint(vformsrc, 2 * i + 1);
2280     }
2281   }
2282 
2283   dst.ClearForWrite(vform);
2284   for (int i = 0; i < laneCount; ++i) {
2285     if (do_accumulate) {
2286       if (is_signed) {
2287         dst.SetInt(vform, i, dst.Int(vform, i) + sr[i]);
2288       } else {
2289         dst.SetUint(vform, i, dst.Uint(vform, i) + ur[i]);
2290       }
2291     } else {
2292       if (is_signed) {
2293         dst.SetInt(vform, i, sr[i]);
2294       } else {
2295         dst.SetUint(vform, i, ur[i]);
2296       }
2297     }
2298   }
2299 
2300   return dst;
2301 }
2302 
2303 
saddlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2304 LogicVRegister Simulator::saddlp(VectorFormat vform,
2305                                  LogicVRegister dst,
2306                                  const LogicVRegister& src) {
2307   return addlp(vform, dst, src, true, false);
2308 }
2309 
2310 
uaddlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2311 LogicVRegister Simulator::uaddlp(VectorFormat vform,
2312                                  LogicVRegister dst,
2313                                  const LogicVRegister& src) {
2314   return addlp(vform, dst, src, false, false);
2315 }
2316 
2317 
sadalp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2318 LogicVRegister Simulator::sadalp(VectorFormat vform,
2319                                  LogicVRegister dst,
2320                                  const LogicVRegister& src) {
2321   return addlp(vform, dst, src, true, true);
2322 }
2323 
2324 
uadalp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2325 LogicVRegister Simulator::uadalp(VectorFormat vform,
2326                                  LogicVRegister dst,
2327                                  const LogicVRegister& src) {
2328   return addlp(vform, dst, src, false, true);
2329 }
2330 
2331 
ext(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)2332 LogicVRegister Simulator::ext(VectorFormat vform,
2333                               LogicVRegister dst,
2334                               const LogicVRegister& src1,
2335                               const LogicVRegister& src2,
2336                               int index) {
2337   uint8_t result[16];
2338   int laneCount = LaneCountFromFormat(vform);
2339   for (int i = 0; i < laneCount - index; ++i) {
2340     result[i] = src1.Uint(vform, i + index);
2341   }
2342   for (int i = 0; i < index; ++i) {
2343     result[laneCount - index + i] = src2.Uint(vform, i);
2344   }
2345   dst.ClearForWrite(vform);
2346   for (int i = 0; i < laneCount; ++i) {
2347     dst.SetUint(vform, i, result[i]);
2348   }
2349   return dst;
2350 }
2351 
2352 
dup_element(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int src_index)2353 LogicVRegister Simulator::dup_element(VectorFormat vform,
2354                                       LogicVRegister dst,
2355                                       const LogicVRegister& src,
2356                                       int src_index) {
2357   int laneCount = LaneCountFromFormat(vform);
2358   uint64_t value = src.Uint(vform, src_index);
2359   dst.ClearForWrite(vform);
2360   for (int i = 0; i < laneCount; ++i) {
2361     dst.SetUint(vform, i, value);
2362   }
2363   return dst;
2364 }
2365 
2366 
dup_immediate(VectorFormat vform,LogicVRegister dst,uint64_t imm)2367 LogicVRegister Simulator::dup_immediate(VectorFormat vform,
2368                                         LogicVRegister dst,
2369                                         uint64_t imm) {
2370   int laneCount = LaneCountFromFormat(vform);
2371   uint64_t value = imm & MaxUintFromFormat(vform);
2372   dst.ClearForWrite(vform);
2373   for (int i = 0; i < laneCount; ++i) {
2374     dst.SetUint(vform, i, value);
2375   }
2376   return dst;
2377 }
2378 
2379 
ins_element(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,int src_index)2380 LogicVRegister Simulator::ins_element(VectorFormat vform,
2381                                       LogicVRegister dst,
2382                                       int dst_index,
2383                                       const LogicVRegister& src,
2384                                       int src_index) {
2385   dst.SetUint(vform, dst_index, src.Uint(vform, src_index));
2386   return dst;
2387 }
2388 
2389 
ins_immediate(VectorFormat vform,LogicVRegister dst,int dst_index,uint64_t imm)2390 LogicVRegister Simulator::ins_immediate(VectorFormat vform,
2391                                         LogicVRegister dst,
2392                                         int dst_index,
2393                                         uint64_t imm) {
2394   uint64_t value = imm & MaxUintFromFormat(vform);
2395   dst.SetUint(vform, dst_index, value);
2396   return dst;
2397 }
2398 
2399 
movi(VectorFormat vform,LogicVRegister dst,uint64_t imm)2400 LogicVRegister Simulator::movi(VectorFormat vform,
2401                                LogicVRegister dst,
2402                                uint64_t imm) {
2403   int laneCount = LaneCountFromFormat(vform);
2404   dst.ClearForWrite(vform);
2405   for (int i = 0; i < laneCount; ++i) {
2406     dst.SetUint(vform, i, imm);
2407   }
2408   return dst;
2409 }
2410 
2411 
mvni(VectorFormat vform,LogicVRegister dst,uint64_t imm)2412 LogicVRegister Simulator::mvni(VectorFormat vform,
2413                                LogicVRegister dst,
2414                                uint64_t imm) {
2415   int laneCount = LaneCountFromFormat(vform);
2416   dst.ClearForWrite(vform);
2417   for (int i = 0; i < laneCount; ++i) {
2418     dst.SetUint(vform, i, ~imm);
2419   }
2420   return dst;
2421 }
2422 
2423 
orr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,uint64_t imm)2424 LogicVRegister Simulator::orr(VectorFormat vform,
2425                               LogicVRegister dst,
2426                               const LogicVRegister& src,
2427                               uint64_t imm) {
2428   uint64_t result[16];
2429   int laneCount = LaneCountFromFormat(vform);
2430   for (int i = 0; i < laneCount; ++i) {
2431     result[i] = src.Uint(vform, i) | imm;
2432   }
2433   dst.ClearForWrite(vform);
2434   for (int i = 0; i < laneCount; ++i) {
2435     dst.SetUint(vform, i, result[i]);
2436   }
2437   return dst;
2438 }
2439 
2440 
uxtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2441 LogicVRegister Simulator::uxtl(VectorFormat vform,
2442                                LogicVRegister dst,
2443                                const LogicVRegister& src) {
2444   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2445 
2446   dst.ClearForWrite(vform);
2447   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2448     dst.SetUint(vform, i, src.Uint(vform_half, i));
2449   }
2450   return dst;
2451 }
2452 
2453 
sxtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2454 LogicVRegister Simulator::sxtl(VectorFormat vform,
2455                                LogicVRegister dst,
2456                                const LogicVRegister& src) {
2457   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2458 
2459   dst.ClearForWrite(vform);
2460   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2461     dst.SetInt(vform, i, src.Int(vform_half, i));
2462   }
2463   return dst;
2464 }
2465 
2466 
uxtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2467 LogicVRegister Simulator::uxtl2(VectorFormat vform,
2468                                 LogicVRegister dst,
2469                                 const LogicVRegister& src) {
2470   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2471   int lane_count = LaneCountFromFormat(vform);
2472 
2473   dst.ClearForWrite(vform);
2474   for (int i = 0; i < lane_count; i++) {
2475     dst.SetUint(vform, i, src.Uint(vform_half, lane_count + i));
2476   }
2477   return dst;
2478 }
2479 
2480 
sxtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2481 LogicVRegister Simulator::sxtl2(VectorFormat vform,
2482                                 LogicVRegister dst,
2483                                 const LogicVRegister& src) {
2484   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2485   int lane_count = LaneCountFromFormat(vform);
2486 
2487   dst.ClearForWrite(vform);
2488   for (int i = 0; i < lane_count; i++) {
2489     dst.SetInt(vform, i, src.Int(vform_half, lane_count + i));
2490   }
2491   return dst;
2492 }
2493 
2494 
shrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2495 LogicVRegister Simulator::shrn(VectorFormat vform,
2496                                LogicVRegister dst,
2497                                const LogicVRegister& src,
2498                                int shift) {
2499   SimVRegister temp;
2500   VectorFormat vform_src = VectorFormatDoubleWidth(vform);
2501   VectorFormat vform_dst = vform;
2502   LogicVRegister shifted_src = ushr(vform_src, temp, src, shift);
2503   return extractnarrow(vform_dst, dst, false, shifted_src, false);
2504 }
2505 
2506 
shrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2507 LogicVRegister Simulator::shrn2(VectorFormat vform,
2508                                 LogicVRegister dst,
2509                                 const LogicVRegister& src,
2510                                 int shift) {
2511   SimVRegister temp;
2512   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2513   VectorFormat vformdst = vform;
2514   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift);
2515   return extractnarrow(vformdst, dst, false, shifted_src, false);
2516 }
2517 
2518 
rshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2519 LogicVRegister Simulator::rshrn(VectorFormat vform,
2520                                 LogicVRegister dst,
2521                                 const LogicVRegister& src,
2522                                 int shift) {
2523   SimVRegister temp;
2524   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2525   VectorFormat vformdst = vform;
2526   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2527   return extractnarrow(vformdst, dst, false, shifted_src, false);
2528 }
2529 
2530 
rshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2531 LogicVRegister Simulator::rshrn2(VectorFormat vform,
2532                                  LogicVRegister dst,
2533                                  const LogicVRegister& src,
2534                                  int shift) {
2535   SimVRegister temp;
2536   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2537   VectorFormat vformdst = vform;
2538   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2539   return extractnarrow(vformdst, dst, false, shifted_src, false);
2540 }
2541 
2542 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & ind)2543 LogicVRegister Simulator::tbl(VectorFormat vform,
2544                               LogicVRegister dst,
2545                               const LogicVRegister& tab,
2546                               const LogicVRegister& ind) {
2547     movi(vform, dst, 0);
2548     return tbx(vform, dst, tab, ind);
2549 }
2550 
2551 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & ind)2552 LogicVRegister Simulator::tbl(VectorFormat vform,
2553                               LogicVRegister dst,
2554                               const LogicVRegister& tab,
2555                               const LogicVRegister& tab2,
2556                               const LogicVRegister& ind) {
2557     movi(vform, dst, 0);
2558     return tbx(vform, dst, tab, tab2, ind);
2559 }
2560 
2561 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & ind)2562 LogicVRegister Simulator::tbl(VectorFormat vform,
2563                               LogicVRegister dst,
2564                               const LogicVRegister& tab,
2565                               const LogicVRegister& tab2,
2566                               const LogicVRegister& tab3,
2567                               const LogicVRegister& ind) {
2568     movi(vform, dst, 0);
2569     return tbx(vform, dst, tab, tab2, tab3, ind);
2570 }
2571 
2572 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & tab4,const LogicVRegister & ind)2573 LogicVRegister Simulator::tbl(VectorFormat vform,
2574                               LogicVRegister dst,
2575                               const LogicVRegister& tab,
2576                               const LogicVRegister& tab2,
2577                               const LogicVRegister& tab3,
2578                               const LogicVRegister& tab4,
2579                               const LogicVRegister& ind) {
2580     movi(vform, dst, 0);
2581     return tbx(vform, dst, tab, tab2, tab3, tab4, ind);
2582 }
2583 
2584 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & ind)2585 LogicVRegister Simulator::tbx(VectorFormat vform,
2586                               LogicVRegister dst,
2587                               const LogicVRegister& tab,
2588                               const LogicVRegister& ind) {
2589   dst.ClearForWrite(vform);
2590   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2591     uint64_t j = ind.Uint(vform, i);
2592     switch (j >> 4) {
2593       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2594     }
2595   }
2596   return dst;
2597 }
2598 
2599 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & ind)2600 LogicVRegister Simulator::tbx(VectorFormat vform,
2601                               LogicVRegister dst,
2602                               const LogicVRegister& tab,
2603                               const LogicVRegister& tab2,
2604                               const LogicVRegister& ind) {
2605   dst.ClearForWrite(vform);
2606   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2607     uint64_t j = ind.Uint(vform, i);
2608     switch (j >> 4) {
2609       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2610       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2611     }
2612   }
2613   return dst;
2614 }
2615 
2616 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & ind)2617 LogicVRegister Simulator::tbx(VectorFormat vform,
2618                               LogicVRegister dst,
2619                               const LogicVRegister& tab,
2620                               const LogicVRegister& tab2,
2621                               const LogicVRegister& tab3,
2622                               const LogicVRegister& ind) {
2623   dst.ClearForWrite(vform);
2624   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2625     uint64_t j = ind.Uint(vform, i);
2626     switch (j >> 4) {
2627       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2628       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2629       case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
2630     }
2631   }
2632   return dst;
2633 }
2634 
2635 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & tab4,const LogicVRegister & ind)2636 LogicVRegister Simulator::tbx(VectorFormat vform,
2637                               LogicVRegister dst,
2638                               const LogicVRegister& tab,
2639                               const LogicVRegister& tab2,
2640                               const LogicVRegister& tab3,
2641                               const LogicVRegister& tab4,
2642                               const LogicVRegister& ind) {
2643   dst.ClearForWrite(vform);
2644   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2645     uint64_t j = ind.Uint(vform, i);
2646     switch (j >> 4) {
2647       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2648       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2649       case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
2650       case 3: dst.SetUint(vform, i, tab4.Uint(kFormat16B, j & 15)); break;
2651     }
2652   }
2653   return dst;
2654 }
2655 
2656 
uqshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2657 LogicVRegister Simulator::uqshrn(VectorFormat vform,
2658                                  LogicVRegister dst,
2659                                  const LogicVRegister& src,
2660                                  int shift) {
2661   return shrn(vform, dst, src, shift).UnsignedSaturate(vform);
2662 }
2663 
2664 
uqshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2665 LogicVRegister Simulator::uqshrn2(VectorFormat vform,
2666                                   LogicVRegister dst,
2667                                   const LogicVRegister& src,
2668                                   int shift) {
2669   return shrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2670 }
2671 
2672 
uqrshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2673 LogicVRegister Simulator::uqrshrn(VectorFormat vform,
2674                                   LogicVRegister dst,
2675                                   const LogicVRegister& src,
2676                                   int shift) {
2677   return rshrn(vform, dst, src, shift).UnsignedSaturate(vform);
2678 }
2679 
2680 
uqrshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2681 LogicVRegister Simulator::uqrshrn2(VectorFormat vform,
2682                                    LogicVRegister dst,
2683                                    const LogicVRegister& src,
2684                                    int shift) {
2685   return rshrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2686 }
2687 
2688 
sqshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2689 LogicVRegister Simulator::sqshrn(VectorFormat vform,
2690                                  LogicVRegister dst,
2691                                  const LogicVRegister& src,
2692                                  int shift) {
2693   SimVRegister temp;
2694   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2695   VectorFormat vformdst = vform;
2696   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2697   return sqxtn(vformdst, dst, shifted_src);
2698 }
2699 
2700 
sqshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2701 LogicVRegister Simulator::sqshrn2(VectorFormat vform,
2702                                   LogicVRegister dst,
2703                                   const LogicVRegister& src,
2704                                   int shift) {
2705   SimVRegister temp;
2706   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2707   VectorFormat vformdst = vform;
2708   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2709   return sqxtn(vformdst, dst, shifted_src);
2710 }
2711 
2712 
sqrshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2713 LogicVRegister Simulator::sqrshrn(VectorFormat vform,
2714                                   LogicVRegister dst,
2715                                   const LogicVRegister& src,
2716                                   int shift) {
2717   SimVRegister temp;
2718   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2719   VectorFormat vformdst = vform;
2720   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2721   return sqxtn(vformdst, dst, shifted_src);
2722 }
2723 
2724 
sqrshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2725 LogicVRegister Simulator::sqrshrn2(VectorFormat vform,
2726                                    LogicVRegister dst,
2727                                    const LogicVRegister& src,
2728                                    int shift) {
2729   SimVRegister temp;
2730   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2731   VectorFormat vformdst = vform;
2732   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2733   return sqxtn(vformdst, dst, shifted_src);
2734 }
2735 
2736 
sqshrun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2737 LogicVRegister Simulator::sqshrun(VectorFormat vform,
2738                                   LogicVRegister dst,
2739                                   const LogicVRegister& src,
2740                                   int shift) {
2741   SimVRegister temp;
2742   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2743   VectorFormat vformdst = vform;
2744   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2745   return sqxtun(vformdst, dst, shifted_src);
2746 }
2747 
2748 
sqshrun2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2749 LogicVRegister Simulator::sqshrun2(VectorFormat vform,
2750                                    LogicVRegister dst,
2751                                    const LogicVRegister& src,
2752                                    int shift) {
2753   SimVRegister temp;
2754   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2755   VectorFormat vformdst = vform;
2756   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2757   return sqxtun(vformdst, dst, shifted_src);
2758 }
2759 
2760 
sqrshrun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2761 LogicVRegister Simulator::sqrshrun(VectorFormat vform,
2762                                    LogicVRegister dst,
2763                                    const LogicVRegister& src,
2764                                    int shift) {
2765   SimVRegister temp;
2766   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2767   VectorFormat vformdst = vform;
2768   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2769   return sqxtun(vformdst, dst, shifted_src);
2770 }
2771 
2772 
sqrshrun2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2773 LogicVRegister Simulator::sqrshrun2(VectorFormat vform,
2774                                     LogicVRegister dst,
2775                                     const LogicVRegister& src,
2776                                     int shift) {
2777   SimVRegister temp;
2778   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2779   VectorFormat vformdst = vform;
2780   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2781   return sqxtun(vformdst, dst, shifted_src);
2782 }
2783 
2784 
uaddl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2785 LogicVRegister Simulator::uaddl(VectorFormat vform,
2786                                 LogicVRegister dst,
2787                                 const LogicVRegister& src1,
2788                                 const LogicVRegister& src2) {
2789   SimVRegister temp1, temp2;
2790   uxtl(vform, temp1, src1);
2791   uxtl(vform, temp2, src2);
2792   add(vform, dst, temp1, temp2);
2793   return dst;
2794 }
2795 
2796 
uaddl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2797 LogicVRegister Simulator::uaddl2(VectorFormat vform,
2798                                  LogicVRegister dst,
2799                                  const LogicVRegister& src1,
2800                                  const LogicVRegister& src2) {
2801   SimVRegister temp1, temp2;
2802   uxtl2(vform, temp1, src1);
2803   uxtl2(vform, temp2, src2);
2804   add(vform, dst, temp1, temp2);
2805   return dst;
2806 }
2807 
2808 
uaddw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2809 LogicVRegister Simulator::uaddw(VectorFormat vform,
2810                                 LogicVRegister dst,
2811                                 const LogicVRegister& src1,
2812                                 const LogicVRegister& src2) {
2813   SimVRegister temp;
2814   uxtl(vform, temp, src2);
2815   add(vform, dst, src1, temp);
2816   return dst;
2817 }
2818 
2819 
uaddw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2820 LogicVRegister Simulator::uaddw2(VectorFormat vform,
2821                                  LogicVRegister dst,
2822                                  const LogicVRegister& src1,
2823                                  const LogicVRegister& src2) {
2824   SimVRegister temp;
2825   uxtl2(vform, temp, src2);
2826   add(vform, dst, src1, temp);
2827   return dst;
2828 }
2829 
2830 
saddl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2831 LogicVRegister Simulator::saddl(VectorFormat vform,
2832                                 LogicVRegister dst,
2833                                 const LogicVRegister& src1,
2834                                 const LogicVRegister& src2) {
2835   SimVRegister temp1, temp2;
2836   sxtl(vform, temp1, src1);
2837   sxtl(vform, temp2, src2);
2838   add(vform, dst, temp1, temp2);
2839   return dst;
2840 }
2841 
2842 
saddl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2843 LogicVRegister Simulator::saddl2(VectorFormat vform,
2844                                  LogicVRegister dst,
2845                                  const LogicVRegister& src1,
2846                                  const LogicVRegister& src2) {
2847   SimVRegister temp1, temp2;
2848   sxtl2(vform, temp1, src1);
2849   sxtl2(vform, temp2, src2);
2850   add(vform, dst, temp1, temp2);
2851   return dst;
2852 }
2853 
2854 
saddw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2855 LogicVRegister Simulator::saddw(VectorFormat vform,
2856                                 LogicVRegister dst,
2857                                 const LogicVRegister& src1,
2858                                 const LogicVRegister& src2) {
2859   SimVRegister temp;
2860   sxtl(vform, temp, src2);
2861   add(vform, dst, src1, temp);
2862   return dst;
2863 }
2864 
2865 
saddw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2866 LogicVRegister Simulator::saddw2(VectorFormat vform,
2867                                  LogicVRegister dst,
2868                                  const LogicVRegister& src1,
2869                                  const LogicVRegister& src2) {
2870   SimVRegister temp;
2871   sxtl2(vform, temp, src2);
2872   add(vform, dst, src1, temp);
2873   return dst;
2874 }
2875 
2876 
usubl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2877 LogicVRegister Simulator::usubl(VectorFormat vform,
2878                                 LogicVRegister dst,
2879                                 const LogicVRegister& src1,
2880                                 const LogicVRegister& src2) {
2881   SimVRegister temp1, temp2;
2882   uxtl(vform, temp1, src1);
2883   uxtl(vform, temp2, src2);
2884   sub(vform, dst, temp1, temp2);
2885   return dst;
2886 }
2887 
2888 
usubl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2889 LogicVRegister Simulator::usubl2(VectorFormat vform,
2890                                  LogicVRegister dst,
2891                                  const LogicVRegister& src1,
2892                                  const LogicVRegister& src2) {
2893   SimVRegister temp1, temp2;
2894   uxtl2(vform, temp1, src1);
2895   uxtl2(vform, temp2, src2);
2896   sub(vform, dst, temp1, temp2);
2897   return dst;
2898 }
2899 
2900 
usubw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2901 LogicVRegister Simulator::usubw(VectorFormat vform,
2902                                 LogicVRegister dst,
2903                                 const LogicVRegister& src1,
2904                                 const LogicVRegister& src2) {
2905   SimVRegister temp;
2906   uxtl(vform, temp, src2);
2907   sub(vform, dst, src1, temp);
2908   return dst;
2909 }
2910 
2911 
usubw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2912 LogicVRegister Simulator::usubw2(VectorFormat vform,
2913                                  LogicVRegister dst,
2914                                  const LogicVRegister& src1,
2915                                  const LogicVRegister& src2) {
2916   SimVRegister temp;
2917   uxtl2(vform, temp, src2);
2918   sub(vform, dst, src1, temp);
2919   return dst;
2920 }
2921 
2922 
ssubl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2923 LogicVRegister Simulator::ssubl(VectorFormat vform,
2924                                 LogicVRegister dst,
2925                                 const LogicVRegister& src1,
2926                                 const LogicVRegister& src2) {
2927   SimVRegister temp1, temp2;
2928   sxtl(vform, temp1, src1);
2929   sxtl(vform, temp2, src2);
2930   sub(vform, dst, temp1, temp2);
2931   return dst;
2932 }
2933 
2934 
ssubl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2935 LogicVRegister Simulator::ssubl2(VectorFormat vform,
2936                                  LogicVRegister dst,
2937                                  const LogicVRegister& src1,
2938                                  const LogicVRegister& src2) {
2939   SimVRegister temp1, temp2;
2940   sxtl2(vform, temp1, src1);
2941   sxtl2(vform, temp2, src2);
2942   sub(vform, dst, temp1, temp2);
2943   return dst;
2944 }
2945 
2946 
ssubw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2947 LogicVRegister Simulator::ssubw(VectorFormat vform,
2948                                 LogicVRegister dst,
2949                                 const LogicVRegister& src1,
2950                                 const LogicVRegister& src2) {
2951   SimVRegister temp;
2952   sxtl(vform, temp, src2);
2953   sub(vform, dst, src1, temp);
2954   return dst;
2955 }
2956 
2957 
ssubw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2958 LogicVRegister Simulator::ssubw2(VectorFormat vform,
2959                                  LogicVRegister dst,
2960                                  const LogicVRegister& src1,
2961                                  const LogicVRegister& src2) {
2962   SimVRegister temp;
2963   sxtl2(vform, temp, src2);
2964   sub(vform, dst, src1, temp);
2965   return dst;
2966 }
2967 
2968 
uabal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2969 LogicVRegister Simulator::uabal(VectorFormat vform,
2970                                 LogicVRegister dst,
2971                                 const LogicVRegister& src1,
2972                                 const LogicVRegister& src2) {
2973   SimVRegister temp1, temp2;
2974   uxtl(vform, temp1, src1);
2975   uxtl(vform, temp2, src2);
2976   uaba(vform, dst, temp1, temp2);
2977   return dst;
2978 }
2979 
2980 
uabal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2981 LogicVRegister Simulator::uabal2(VectorFormat vform,
2982                                  LogicVRegister dst,
2983                                  const LogicVRegister& src1,
2984                                  const LogicVRegister& src2) {
2985   SimVRegister temp1, temp2;
2986   uxtl2(vform, temp1, src1);
2987   uxtl2(vform, temp2, src2);
2988   uaba(vform, dst, temp1, temp2);
2989   return dst;
2990 }
2991 
2992 
sabal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2993 LogicVRegister Simulator::sabal(VectorFormat vform,
2994                                 LogicVRegister dst,
2995                                 const LogicVRegister& src1,
2996                                 const LogicVRegister& src2) {
2997   SimVRegister temp1, temp2;
2998   sxtl(vform, temp1, src1);
2999   sxtl(vform, temp2, src2);
3000   saba(vform, dst, temp1, temp2);
3001   return dst;
3002 }
3003 
3004 
sabal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3005 LogicVRegister Simulator::sabal2(VectorFormat vform,
3006                                  LogicVRegister dst,
3007                                  const LogicVRegister& src1,
3008                                  const LogicVRegister& src2) {
3009   SimVRegister temp1, temp2;
3010   sxtl2(vform, temp1, src1);
3011   sxtl2(vform, temp2, src2);
3012   saba(vform, dst, temp1, temp2);
3013   return dst;
3014 }
3015 
3016 
uabdl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3017 LogicVRegister Simulator::uabdl(VectorFormat vform,
3018                                 LogicVRegister dst,
3019                                 const LogicVRegister& src1,
3020                                 const LogicVRegister& src2) {
3021   SimVRegister temp1, temp2;
3022   uxtl(vform, temp1, src1);
3023   uxtl(vform, temp2, src2);
3024   absdiff(vform, dst, temp1, temp2, false);
3025   return dst;
3026 }
3027 
3028 
uabdl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3029 LogicVRegister Simulator::uabdl2(VectorFormat vform,
3030                                  LogicVRegister dst,
3031                                  const LogicVRegister& src1,
3032                                  const LogicVRegister& src2) {
3033   SimVRegister temp1, temp2;
3034   uxtl2(vform, temp1, src1);
3035   uxtl2(vform, temp2, src2);
3036   absdiff(vform, dst, temp1, temp2, false);
3037   return dst;
3038 }
3039 
3040 
sabdl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3041 LogicVRegister Simulator::sabdl(VectorFormat vform,
3042                                 LogicVRegister dst,
3043                                 const LogicVRegister& src1,
3044                                 const LogicVRegister& src2) {
3045   SimVRegister temp1, temp2;
3046   sxtl(vform, temp1, src1);
3047   sxtl(vform, temp2, src2);
3048   absdiff(vform, dst, temp1, temp2, true);
3049   return dst;
3050 }
3051 
3052 
sabdl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3053 LogicVRegister Simulator::sabdl2(VectorFormat vform,
3054                                  LogicVRegister dst,
3055                                  const LogicVRegister& src1,
3056                                  const LogicVRegister& src2) {
3057   SimVRegister temp1, temp2;
3058   sxtl2(vform, temp1, src1);
3059   sxtl2(vform, temp2, src2);
3060   absdiff(vform, dst, temp1, temp2, true);
3061   return dst;
3062 }
3063 
3064 
umull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3065 LogicVRegister Simulator::umull(VectorFormat vform,
3066                                 LogicVRegister dst,
3067                                 const LogicVRegister& src1,
3068                                 const LogicVRegister& src2) {
3069   SimVRegister temp1, temp2;
3070   uxtl(vform, temp1, src1);
3071   uxtl(vform, temp2, src2);
3072   mul(vform, dst, temp1, temp2);
3073   return dst;
3074 }
3075 
3076 
umull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3077 LogicVRegister Simulator::umull2(VectorFormat vform,
3078                                  LogicVRegister dst,
3079                                  const LogicVRegister& src1,
3080                                  const LogicVRegister& src2) {
3081   SimVRegister temp1, temp2;
3082   uxtl2(vform, temp1, src1);
3083   uxtl2(vform, temp2, src2);
3084   mul(vform, dst, temp1, temp2);
3085   return dst;
3086 }
3087 
3088 
smull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3089 LogicVRegister Simulator::smull(VectorFormat vform,
3090                                 LogicVRegister dst,
3091                                 const LogicVRegister& src1,
3092                                 const LogicVRegister& src2) {
3093   SimVRegister temp1, temp2;
3094   sxtl(vform, temp1, src1);
3095   sxtl(vform, temp2, src2);
3096   mul(vform, dst, temp1, temp2);
3097   return dst;
3098 }
3099 
3100 
smull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3101 LogicVRegister Simulator::smull2(VectorFormat vform,
3102                                  LogicVRegister dst,
3103                                  const LogicVRegister& src1,
3104                                  const LogicVRegister& src2) {
3105   SimVRegister temp1, temp2;
3106   sxtl2(vform, temp1, src1);
3107   sxtl2(vform, temp2, src2);
3108   mul(vform, dst, temp1, temp2);
3109   return dst;
3110 }
3111 
3112 
umlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3113 LogicVRegister Simulator::umlsl(VectorFormat vform,
3114                                 LogicVRegister dst,
3115                                 const LogicVRegister& src1,
3116                                 const LogicVRegister& src2) {
3117   SimVRegister temp1, temp2;
3118   uxtl(vform, temp1, src1);
3119   uxtl(vform, temp2, src2);
3120   mls(vform, dst, temp1, temp2);
3121   return dst;
3122 }
3123 
3124 
umlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3125 LogicVRegister Simulator::umlsl2(VectorFormat vform,
3126                                  LogicVRegister dst,
3127                                  const LogicVRegister& src1,
3128                                  const LogicVRegister& src2) {
3129   SimVRegister temp1, temp2;
3130   uxtl2(vform, temp1, src1);
3131   uxtl2(vform, temp2, src2);
3132   mls(vform, dst, temp1, temp2);
3133   return dst;
3134 }
3135 
3136 
smlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3137 LogicVRegister Simulator::smlsl(VectorFormat vform,
3138                                 LogicVRegister dst,
3139                                 const LogicVRegister& src1,
3140                                 const LogicVRegister& src2) {
3141   SimVRegister temp1, temp2;
3142   sxtl(vform, temp1, src1);
3143   sxtl(vform, temp2, src2);
3144   mls(vform, dst, temp1, temp2);
3145   return dst;
3146 }
3147 
3148 
smlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3149 LogicVRegister Simulator::smlsl2(VectorFormat vform,
3150                                  LogicVRegister dst,
3151                                  const LogicVRegister& src1,
3152                                  const LogicVRegister& src2) {
3153   SimVRegister temp1, temp2;
3154   sxtl2(vform, temp1, src1);
3155   sxtl2(vform, temp2, src2);
3156   mls(vform, dst, temp1, temp2);
3157   return dst;
3158 }
3159 
3160 
umlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3161 LogicVRegister Simulator::umlal(VectorFormat vform,
3162                                 LogicVRegister dst,
3163                                 const LogicVRegister& src1,
3164                                 const LogicVRegister& src2) {
3165   SimVRegister temp1, temp2;
3166   uxtl(vform, temp1, src1);
3167   uxtl(vform, temp2, src2);
3168   mla(vform, dst, temp1, temp2);
3169   return dst;
3170 }
3171 
3172 
umlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3173 LogicVRegister Simulator::umlal2(VectorFormat vform,
3174                                  LogicVRegister dst,
3175                                  const LogicVRegister& src1,
3176                                  const LogicVRegister& src2) {
3177   SimVRegister temp1, temp2;
3178   uxtl2(vform, temp1, src1);
3179   uxtl2(vform, temp2, src2);
3180   mla(vform, dst, temp1, temp2);
3181   return dst;
3182 }
3183 
3184 
smlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3185 LogicVRegister Simulator::smlal(VectorFormat vform,
3186                                 LogicVRegister dst,
3187                                 const LogicVRegister& src1,
3188                                 const LogicVRegister& src2) {
3189   SimVRegister temp1, temp2;
3190   sxtl(vform, temp1, src1);
3191   sxtl(vform, temp2, src2);
3192   mla(vform, dst, temp1, temp2);
3193   return dst;
3194 }
3195 
3196 
smlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3197 LogicVRegister Simulator::smlal2(VectorFormat vform,
3198                                  LogicVRegister dst,
3199                                  const LogicVRegister& src1,
3200                                  const LogicVRegister& src2) {
3201   SimVRegister temp1, temp2;
3202   sxtl2(vform, temp1, src1);
3203   sxtl2(vform, temp2, src2);
3204   mla(vform, dst, temp1, temp2);
3205   return dst;
3206 }
3207 
3208 
sqdmlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3209 LogicVRegister Simulator::sqdmlal(VectorFormat vform,
3210                                   LogicVRegister dst,
3211                                   const LogicVRegister& src1,
3212                                   const LogicVRegister& src2) {
3213   SimVRegister temp;
3214   LogicVRegister product = sqdmull(vform, temp, src1, src2);
3215   return add(vform, dst, dst, product).SignedSaturate(vform);
3216 }
3217 
3218 
sqdmlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3219 LogicVRegister Simulator::sqdmlal2(VectorFormat vform,
3220                                   LogicVRegister dst,
3221                                   const LogicVRegister& src1,
3222                                   const LogicVRegister& src2) {
3223   SimVRegister temp;
3224   LogicVRegister product = sqdmull2(vform, temp, src1, src2);
3225   return add(vform, dst, dst, product).SignedSaturate(vform);
3226 }
3227 
3228 
sqdmlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3229 LogicVRegister Simulator::sqdmlsl(VectorFormat vform,
3230                                   LogicVRegister dst,
3231                                   const LogicVRegister& src1,
3232                                   const LogicVRegister& src2) {
3233   SimVRegister temp;
3234   LogicVRegister product = sqdmull(vform, temp, src1, src2);
3235   return sub(vform, dst, dst, product).SignedSaturate(vform);
3236 }
3237 
3238 
sqdmlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3239 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
3240                                   LogicVRegister dst,
3241                                   const LogicVRegister& src1,
3242                                   const LogicVRegister& src2) {
3243   SimVRegister temp;
3244   LogicVRegister product = sqdmull2(vform, temp, src1, src2);
3245   return sub(vform, dst, dst, product).SignedSaturate(vform);
3246 }
3247 
3248 
sqdmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3249 LogicVRegister Simulator::sqdmull(VectorFormat vform,
3250                                   LogicVRegister dst,
3251                                   const LogicVRegister& src1,
3252                                   const LogicVRegister& src2) {
3253   SimVRegister temp;
3254   LogicVRegister product = smull(vform, temp, src1, src2);
3255   return add(vform, dst, product, product).SignedSaturate(vform);
3256 }
3257 
3258 
sqdmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3259 LogicVRegister Simulator::sqdmull2(VectorFormat vform,
3260                                   LogicVRegister dst,
3261                                   const LogicVRegister& src1,
3262                                   const LogicVRegister& src2) {
3263   SimVRegister temp;
3264   LogicVRegister product = smull2(vform, temp, src1, src2);
3265   return add(vform, dst, product, product).SignedSaturate(vform);
3266 }
3267 
3268 
sqrdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool round)3269 LogicVRegister Simulator::sqrdmulh(VectorFormat vform,
3270                                    LogicVRegister dst,
3271                                    const LogicVRegister& src1,
3272                                    const LogicVRegister& src2,
3273                                    bool round) {
3274   // 2 * INT_32_MIN * INT_32_MIN causes int64_t to overflow.
3275   // To avoid this, we use (src1 * src2 + 1 << (esize - 2)) >> (esize - 1)
3276   // which is same as (2 * src1 * src2 + 1 << (esize - 1)) >> esize.
3277 
3278   int esize = LaneSizeInBitsFromFormat(vform);
3279   int round_const = round ? (1 << (esize - 2)) : 0;
3280   int64_t product;
3281 
3282   dst.ClearForWrite(vform);
3283   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3284     product = src1.Int(vform, i) * src2.Int(vform, i);
3285     product += round_const;
3286     product = product >> (esize - 1);
3287 
3288     if (product > MaxIntFromFormat(vform)) {
3289       product = MaxIntFromFormat(vform);
3290     } else if (product < MinIntFromFormat(vform)) {
3291       product = MinIntFromFormat(vform);
3292     }
3293     dst.SetInt(vform, i, product);
3294   }
3295   return dst;
3296 }
3297 
3298 
sqdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3299 LogicVRegister Simulator::sqdmulh(VectorFormat vform,
3300                                   LogicVRegister dst,
3301                                   const LogicVRegister& src1,
3302                                   const LogicVRegister& src2) {
3303   return sqrdmulh(vform, dst, src1, src2, false);
3304 }
3305 
3306 
addhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3307 LogicVRegister Simulator::addhn(VectorFormat vform,
3308                                 LogicVRegister dst,
3309                                 const LogicVRegister& src1,
3310                                 const LogicVRegister& src2) {
3311   SimVRegister temp;
3312   add(VectorFormatDoubleWidth(vform), temp, src1, src2);
3313   shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3314   return dst;
3315 }
3316 
3317 
addhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3318 LogicVRegister Simulator::addhn2(VectorFormat vform,
3319                                  LogicVRegister dst,
3320                                  const LogicVRegister& src1,
3321                                  const LogicVRegister& src2) {
3322   SimVRegister temp;
3323   add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3324   shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3325   return dst;
3326 }
3327 
3328 
raddhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3329 LogicVRegister Simulator::raddhn(VectorFormat vform,
3330                                  LogicVRegister dst,
3331                                  const LogicVRegister& src1,
3332                                  const LogicVRegister& src2) {
3333   SimVRegister temp;
3334   add(VectorFormatDoubleWidth(vform), temp, src1, src2);
3335   rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3336   return dst;
3337 }
3338 
3339 
raddhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3340 LogicVRegister Simulator::raddhn2(VectorFormat vform,
3341                                   LogicVRegister dst,
3342                                   const LogicVRegister& src1,
3343                                   const LogicVRegister& src2) {
3344   SimVRegister temp;
3345   add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3346   rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3347   return dst;
3348 }
3349 
3350 
subhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3351 LogicVRegister Simulator::subhn(VectorFormat vform,
3352                                 LogicVRegister dst,
3353                                 const LogicVRegister& src1,
3354                                 const LogicVRegister& src2) {
3355   SimVRegister temp;
3356   sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
3357   shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3358   return dst;
3359 }
3360 
3361 
subhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3362 LogicVRegister Simulator::subhn2(VectorFormat vform,
3363                                  LogicVRegister dst,
3364                                  const LogicVRegister& src1,
3365                                  const LogicVRegister& src2) {
3366   SimVRegister temp;
3367   sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3368   shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3369   return dst;
3370 }
3371 
3372 
rsubhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3373 LogicVRegister Simulator::rsubhn(VectorFormat vform,
3374                                  LogicVRegister dst,
3375                                  const LogicVRegister& src1,
3376                                  const LogicVRegister& src2) {
3377   SimVRegister temp;
3378   sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
3379   rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3380   return dst;
3381 }
3382 
3383 
rsubhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3384 LogicVRegister Simulator::rsubhn2(VectorFormat vform,
3385                                   LogicVRegister dst,
3386                                   const LogicVRegister& src1,
3387                                   const LogicVRegister& src2) {
3388   SimVRegister temp;
3389   sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3390   rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3391   return dst;
3392 }
3393 
3394 
trn1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3395 LogicVRegister Simulator::trn1(VectorFormat vform,
3396                                LogicVRegister dst,
3397                                const LogicVRegister& src1,
3398                                const LogicVRegister& src2) {
3399   uint64_t result[16];
3400   int laneCount = LaneCountFromFormat(vform);
3401   int pairs = laneCount / 2;
3402   for (int i = 0; i < pairs; ++i) {
3403     result[2 * i]       = src1.Uint(vform, 2 * i);
3404     result[(2 * i) + 1] = src2.Uint(vform, 2 * i);
3405   }
3406 
3407   dst.ClearForWrite(vform);
3408   for (int i = 0; i < laneCount; ++i) {
3409     dst.SetUint(vform, i, result[i]);
3410   }
3411   return dst;
3412 }
3413 
3414 
trn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3415 LogicVRegister Simulator::trn2(VectorFormat vform,
3416                                LogicVRegister dst,
3417                                const LogicVRegister& src1,
3418                                const LogicVRegister& src2) {
3419   uint64_t result[16];
3420   int laneCount = LaneCountFromFormat(vform);
3421   int pairs = laneCount / 2;
3422   for (int i = 0; i < pairs; ++i) {
3423     result[2 * i]       = src1.Uint(vform, (2 * i) + 1);
3424     result[(2 * i) + 1] = src2.Uint(vform, (2 * i) + 1);
3425   }
3426 
3427   dst.ClearForWrite(vform);
3428   for (int i = 0; i < laneCount; ++i) {
3429     dst.SetUint(vform, i, result[i]);
3430   }
3431   return dst;
3432 }
3433 
3434 
zip1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3435 LogicVRegister Simulator::zip1(VectorFormat vform,
3436                                LogicVRegister dst,
3437                                const LogicVRegister& src1,
3438                                const LogicVRegister& src2) {
3439   uint64_t result[16];
3440   int laneCount = LaneCountFromFormat(vform);
3441   int pairs = laneCount / 2;
3442   for (int i = 0; i < pairs; ++i) {
3443     result[2 * i]       = src1.Uint(vform, i);
3444     result[(2 * i) + 1] = src2.Uint(vform, i);
3445   }
3446 
3447   dst.ClearForWrite(vform);
3448   for (int i = 0; i < laneCount; ++i) {
3449     dst.SetUint(vform, i, result[i]);
3450   }
3451   return dst;
3452 }
3453 
3454 
zip2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3455 LogicVRegister Simulator::zip2(VectorFormat vform,
3456                                LogicVRegister dst,
3457                                const LogicVRegister& src1,
3458                                const LogicVRegister& src2) {
3459   uint64_t result[16];
3460   int laneCount = LaneCountFromFormat(vform);
3461   int pairs = laneCount / 2;
3462   for (int i = 0; i < pairs; ++i) {
3463     result[2 * i]       = src1.Uint(vform, pairs + i);
3464     result[(2 * i) + 1] = src2.Uint(vform, pairs + i);
3465   }
3466 
3467   dst.ClearForWrite(vform);
3468   for (int i = 0; i < laneCount; ++i) {
3469     dst.SetUint(vform, i, result[i]);
3470   }
3471   return dst;
3472 }
3473 
3474 
uzp1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3475 LogicVRegister Simulator::uzp1(VectorFormat vform,
3476                                LogicVRegister dst,
3477                                const LogicVRegister& src1,
3478                                const LogicVRegister& src2) {
3479   uint64_t result[32];
3480   int laneCount = LaneCountFromFormat(vform);
3481   for (int i = 0; i < laneCount; ++i) {
3482     result[i]             = src1.Uint(vform, i);
3483     result[laneCount + i] = src2.Uint(vform, i);
3484   }
3485 
3486   dst.ClearForWrite(vform);
3487   for (int i = 0; i < laneCount; ++i) {
3488     dst.SetUint(vform, i, result[2 * i]);
3489   }
3490   return dst;
3491 }
3492 
3493 
uzp2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3494 LogicVRegister Simulator::uzp2(VectorFormat vform,
3495                                LogicVRegister dst,
3496                                const LogicVRegister& src1,
3497                                const LogicVRegister& src2) {
3498   uint64_t result[32];
3499   int laneCount = LaneCountFromFormat(vform);
3500   for (int i = 0; i < laneCount; ++i) {
3501     result[i]             = src1.Uint(vform, i);
3502     result[laneCount + i] = src2.Uint(vform, i);
3503   }
3504 
3505   dst.ClearForWrite(vform);
3506   for (int i = 0; i < laneCount; ++i) {
3507     dst.SetUint(vform, i, result[ (2 * i) + 1]);
3508   }
3509   return dst;
3510 }
3511 
3512 
3513 template <typename T>
FPAdd(T op1,T op2)3514 T Simulator::FPAdd(T op1, T op2) {
3515   T result = FPProcessNaNs(op1, op2);
3516   if (std::isnan(result)) return result;
3517 
3518   if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
3519     // inf + -inf returns the default NaN.
3520     FPProcessException();
3521     return FPDefaultNaN<T>();
3522   } else {
3523     // Other cases should be handled by standard arithmetic.
3524     return op1 + op2;
3525   }
3526 }
3527 
3528 
3529 template <typename T>
FPSub(T op1,T op2)3530 T Simulator::FPSub(T op1, T op2) {
3531   // NaNs should be handled elsewhere.
3532   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3533 
3534   if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
3535     // inf - inf returns the default NaN.
3536     FPProcessException();
3537     return FPDefaultNaN<T>();
3538   } else {
3539     // Other cases should be handled by standard arithmetic.
3540     return op1 - op2;
3541   }
3542 }
3543 
3544 
3545 template <typename T>
FPMul(T op1,T op2)3546 T Simulator::FPMul(T op1, T op2) {
3547   // NaNs should be handled elsewhere.
3548   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3549 
3550   if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
3551     // inf * 0.0 returns the default NaN.
3552     FPProcessException();
3553     return FPDefaultNaN<T>();
3554   } else {
3555     // Other cases should be handled by standard arithmetic.
3556     return op1 * op2;
3557   }
3558 }
3559 
3560 
3561 template<typename T>
FPMulx(T op1,T op2)3562 T Simulator::FPMulx(T op1, T op2) {
3563   if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
3564     // inf * 0.0 returns +/-2.0.
3565     T two = 2.0;
3566     return copysign(1.0, op1) * copysign(1.0, op2) * two;
3567   }
3568   return FPMul(op1, op2);
3569 }
3570 
3571 
3572 template<typename T>
FPMulAdd(T a,T op1,T op2)3573 T Simulator::FPMulAdd(T a, T op1, T op2) {
3574   T result = FPProcessNaNs3(a, op1, op2);
3575 
3576   T sign_a = copysign(1.0, a);
3577   T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
3578   bool isinf_prod = std::isinf(op1) || std::isinf(op2);
3579   bool operation_generates_nan =
3580       (std::isinf(op1) && (op2 == 0.0)) ||                     // inf * 0.0
3581       (std::isinf(op2) && (op1 == 0.0)) ||                     // 0.0 * inf
3582       (std::isinf(a) && isinf_prod && (sign_a != sign_prod));  // inf - inf
3583 
3584   if (std::isnan(result)) {
3585     // Generated NaNs override quiet NaNs propagated from a.
3586     if (operation_generates_nan && IsQuietNaN(a)) {
3587       FPProcessException();
3588       return FPDefaultNaN<T>();
3589     } else {
3590       return result;
3591     }
3592   }
3593 
3594   // If the operation would produce a NaN, return the default NaN.
3595   if (operation_generates_nan) {
3596     FPProcessException();
3597     return FPDefaultNaN<T>();
3598   }
3599 
3600   // Work around broken fma implementations for exact zero results: The sign of
3601   // exact 0.0 results is positive unless both a and op1 * op2 are negative.
3602   if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
3603     return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
3604   }
3605 
3606   result = FusedMultiplyAdd(op1, op2, a);
3607   VIXL_ASSERT(!std::isnan(result));
3608 
3609   // Work around broken fma implementations for rounded zero results: If a is
3610   // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
3611   if ((a == 0.0) && (result == 0.0)) {
3612     return copysign(0.0, sign_prod);
3613   }
3614 
3615   return result;
3616 }
3617 
3618 
3619 template <typename T>
FPDiv(T op1,T op2)3620 T Simulator::FPDiv(T op1, T op2) {
3621   // NaNs should be handled elsewhere.
3622   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3623 
3624   if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
3625     // inf / inf and 0.0 / 0.0 return the default NaN.
3626     FPProcessException();
3627     return FPDefaultNaN<T>();
3628   } else {
3629     if (op2 == 0.0) FPProcessException();
3630 
3631     // Other cases should be handled by standard arithmetic.
3632     return op1 / op2;
3633   }
3634 }
3635 
3636 
3637 template <typename T>
FPSqrt(T op)3638 T Simulator::FPSqrt(T op) {
3639   if (std::isnan(op)) {
3640     return FPProcessNaN(op);
3641   } else if (op < 0.0) {
3642     FPProcessException();
3643     return FPDefaultNaN<T>();
3644   } else {
3645     return sqrt(op);
3646   }
3647 }
3648 
3649 
3650 template <typename T>
FPMax(T a,T b)3651 T Simulator::FPMax(T a, T b) {
3652   T result = FPProcessNaNs(a, b);
3653   if (std::isnan(result)) return result;
3654 
3655   if ((a == 0.0) && (b == 0.0) &&
3656       (copysign(1.0, a) != copysign(1.0, b))) {
3657     // a and b are zero, and the sign differs: return +0.0.
3658     return 0.0;
3659   } else {
3660     return (a > b) ? a : b;
3661   }
3662 }
3663 
3664 
3665 template <typename T>
FPMaxNM(T a,T b)3666 T Simulator::FPMaxNM(T a, T b) {
3667   if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3668     a = kFP64NegativeInfinity;
3669   } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3670     b = kFP64NegativeInfinity;
3671   }
3672 
3673   T result = FPProcessNaNs(a, b);
3674   return std::isnan(result) ? result : FPMax(a, b);
3675 }
3676 
3677 
3678 template <typename T>
FPMin(T a,T b)3679 T Simulator::FPMin(T a, T b) {
3680   T result = FPProcessNaNs(a, b);
3681   if (std::isnan(result)) return result;
3682 
3683   if ((a == 0.0) && (b == 0.0) &&
3684       (copysign(1.0, a) != copysign(1.0, b))) {
3685     // a and b are zero, and the sign differs: return -0.0.
3686     return -0.0;
3687   } else {
3688     return (a < b) ? a : b;
3689   }
3690 }
3691 
3692 
3693 template <typename T>
FPMinNM(T a,T b)3694 T Simulator::FPMinNM(T a, T b) {
3695   if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3696     a = kFP64PositiveInfinity;
3697   } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3698     b = kFP64PositiveInfinity;
3699   }
3700 
3701   T result = FPProcessNaNs(a, b);
3702   return std::isnan(result) ? result : FPMin(a, b);
3703 }
3704 
3705 
3706 template <typename T>
FPRecipStepFused(T op1,T op2)3707 T Simulator::FPRecipStepFused(T op1, T op2) {
3708   const T two = 2.0;
3709   if ((std::isinf(op1) && (op2 == 0.0))
3710       || ((op1 == 0.0) && (std::isinf(op2)))) {
3711     return two;
3712   } else if (std::isinf(op1) || std::isinf(op2)) {
3713     // Return +inf if signs match, otherwise -inf.
3714     return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3715                                           : kFP64NegativeInfinity;
3716   } else {
3717     return FusedMultiplyAdd(op1, op2, two);
3718   }
3719 }
3720 
3721 
3722 template <typename T>
FPRSqrtStepFused(T op1,T op2)3723 T Simulator::FPRSqrtStepFused(T op1, T op2) {
3724   const T one_point_five = 1.5;
3725   const T two = 2.0;
3726 
3727   if ((std::isinf(op1) && (op2 == 0.0))
3728       || ((op1 == 0.0) && (std::isinf(op2)))) {
3729     return one_point_five;
3730   } else if (std::isinf(op1) || std::isinf(op2)) {
3731     // Return +inf if signs match, otherwise -inf.
3732     return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3733                                           : kFP64NegativeInfinity;
3734   } else {
3735     // The multiply-add-halve operation must be fully fused, so avoid interim
3736     // rounding by checking which operand can be losslessly divided by two
3737     // before doing the multiply-add.
3738     if (std::isnormal(op1 / two)) {
3739       return FusedMultiplyAdd(op1 / two, op2, one_point_five);
3740     } else if (std::isnormal(op2 / two)) {
3741       return FusedMultiplyAdd(op1, op2 / two, one_point_five);
3742     } else {
3743       // Neither operand is normal after halving: the result is dominated by
3744       // the addition term, so just return that.
3745       return one_point_five;
3746     }
3747   }
3748 }
3749 
3750 
FPRoundInt(double value,FPRounding round_mode)3751 double Simulator::FPRoundInt(double value, FPRounding round_mode) {
3752   if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
3753       (value == kFP64NegativeInfinity)) {
3754     return value;
3755   } else if (std::isnan(value)) {
3756     return FPProcessNaN(value);
3757   }
3758 
3759   double int_result = std::floor(value);
3760   double error = value - int_result;
3761   switch (round_mode) {
3762     case FPTieAway: {
3763       // Take care of correctly handling the range ]-0.5, -0.0], which must
3764       // yield -0.0.
3765       if ((-0.5 < value) && (value < 0.0)) {
3766         int_result = -0.0;
3767 
3768       } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
3769         // If the error is greater than 0.5, or is equal to 0.5 and the integer
3770         // result is positive, round up.
3771         int_result++;
3772       }
3773       break;
3774     }
3775     case FPTieEven: {
3776       // Take care of correctly handling the range [-0.5, -0.0], which must
3777       // yield -0.0.
3778       if ((-0.5 <= value) && (value < 0.0)) {
3779         int_result = -0.0;
3780 
3781       // If the error is greater than 0.5, or is equal to 0.5 and the integer
3782       // result is odd, round up.
3783       } else if ((error > 0.5) ||
3784           ((error == 0.5) && (std::fmod(int_result, 2) != 0))) {
3785         int_result++;
3786       }
3787       break;
3788     }
3789     case FPZero: {
3790       // If value>0 then we take floor(value)
3791       // otherwise, ceil(value).
3792       if (value < 0) {
3793          int_result = ceil(value);
3794       }
3795       break;
3796     }
3797     case FPNegativeInfinity: {
3798       // We always use floor(value).
3799       break;
3800     }
3801     case FPPositiveInfinity: {
3802       // Take care of correctly handling the range ]-1.0, -0.0], which must
3803       // yield -0.0.
3804       if ((-1.0 < value) && (value < 0.0)) {
3805         int_result = -0.0;
3806 
3807       // If the error is non-zero, round up.
3808       } else if (error > 0.0) {
3809         int_result++;
3810       }
3811       break;
3812     }
3813     default: VIXL_UNIMPLEMENTED();
3814   }
3815   return int_result;
3816 }
3817 
3818 
FPToInt32(double value,FPRounding rmode)3819 int32_t Simulator::FPToInt32(double value, FPRounding rmode) {
3820   value = FPRoundInt(value, rmode);
3821   if (value >= kWMaxInt) {
3822     return kWMaxInt;
3823   } else if (value < kWMinInt) {
3824     return kWMinInt;
3825   }
3826   return std::isnan(value) ? 0 : static_cast<int32_t>(value);
3827 }
3828 
3829 
FPToInt64(double value,FPRounding rmode)3830 int64_t Simulator::FPToInt64(double value, FPRounding rmode) {
3831   value = FPRoundInt(value, rmode);
3832   if (value >= kXMaxInt) {
3833     return kXMaxInt;
3834   } else if (value < kXMinInt) {
3835     return kXMinInt;
3836   }
3837   return std::isnan(value) ? 0 : static_cast<int64_t>(value);
3838 }
3839 
3840 
FPToUInt32(double value,FPRounding rmode)3841 uint32_t Simulator::FPToUInt32(double value, FPRounding rmode) {
3842   value = FPRoundInt(value, rmode);
3843   if (value >= kWMaxUInt) {
3844     return kWMaxUInt;
3845   } else if (value < 0.0) {
3846     return 0;
3847   }
3848   return std::isnan(value) ? 0 : static_cast<uint32_t>(value);
3849 }
3850 
3851 
FPToUInt64(double value,FPRounding rmode)3852 uint64_t Simulator::FPToUInt64(double value, FPRounding rmode) {
3853   value = FPRoundInt(value, rmode);
3854   if (value >= kXMaxUInt) {
3855     return kXMaxUInt;
3856   } else if (value < 0.0) {
3857     return 0;
3858   }
3859   return std::isnan(value) ? 0 : static_cast<uint64_t>(value);
3860 }
3861 
3862 
3863 #define DEFINE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                \
3864 template <typename T>                                            \
3865 LogicVRegister Simulator::FN(VectorFormat vform,                 \
3866                              LogicVRegister dst,                 \
3867                              const LogicVRegister& src1,         \
3868                              const LogicVRegister& src2) {       \
3869   dst.ClearForWrite(vform);                                      \
3870   for (int i = 0; i < LaneCountFromFormat(vform); i++) {         \
3871     T op1 = src1.Float<T>(i);                                    \
3872     T op2 = src2.Float<T>(i);                                    \
3873     T result;                                                    \
3874     if (PROCNAN) {                                               \
3875       result = FPProcessNaNs(op1, op2);                          \
3876       if (!std::isnan(result)) {                                      \
3877         result = OP(op1, op2);                                   \
3878       }                                                          \
3879     } else {                                                     \
3880       result = OP(op1, op2);                                     \
3881     }                                                            \
3882     dst.SetFloat(i, result);                                     \
3883   }                                                              \
3884   return dst;                                                    \
3885 }                                                                \
3886                                                                  \
3887 LogicVRegister Simulator::FN(VectorFormat vform,                 \
3888                              LogicVRegister dst,                 \
3889                              const LogicVRegister& src1,         \
3890                              const LogicVRegister& src2) {       \
3891   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {            \
3892     FN<float>(vform, dst, src1, src2);                           \
3893   } else {                                                       \
3894     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);   \
3895     FN<double>(vform, dst, src1, src2);                          \
3896   }                                                              \
3897   return dst;                                                    \
3898 }
NEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)3899 NEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)
3900 #undef DEFINE_NEON_FP_VECTOR_OP
3901 
3902 
3903 LogicVRegister Simulator::fnmul(VectorFormat vform,
3904                                 LogicVRegister dst,
3905                                 const LogicVRegister& src1,
3906                                 const LogicVRegister& src2) {
3907   SimVRegister temp;
3908   LogicVRegister product = fmul(vform, temp, src1, src2);
3909   return fneg(vform, dst, product);
3910 }
3911 
3912 
3913 template <typename T>
frecps(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3914 LogicVRegister Simulator::frecps(VectorFormat vform,
3915                                  LogicVRegister dst,
3916                                  const LogicVRegister& src1,
3917                                  const LogicVRegister& src2) {
3918   dst.ClearForWrite(vform);
3919   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3920     T op1 = -src1.Float<T>(i);
3921     T op2 = src2.Float<T>(i);
3922     T result = FPProcessNaNs(op1, op2);
3923     dst.SetFloat(i, std::isnan(result) ? result : FPRecipStepFused(op1, op2));
3924   }
3925   return dst;
3926 }
3927 
3928 
frecps(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3929 LogicVRegister Simulator::frecps(VectorFormat vform,
3930                                  LogicVRegister dst,
3931                                  const LogicVRegister& src1,
3932                                  const LogicVRegister& src2) {
3933   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3934     frecps<float>(vform, dst, src1, src2);
3935   } else {
3936     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3937     frecps<double>(vform, dst, src1, src2);
3938   }
3939   return dst;
3940 }
3941 
3942 
3943 template <typename T>
frsqrts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3944 LogicVRegister Simulator::frsqrts(VectorFormat vform,
3945                                   LogicVRegister dst,
3946                                   const LogicVRegister& src1,
3947                                   const LogicVRegister& src2) {
3948   dst.ClearForWrite(vform);
3949   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3950     T op1 = -src1.Float<T>(i);
3951     T op2 = src2.Float<T>(i);
3952     T result = FPProcessNaNs(op1, op2);
3953     dst.SetFloat(i, std::isnan(result) ? result : FPRSqrtStepFused(op1, op2));
3954   }
3955   return dst;
3956 }
3957 
3958 
frsqrts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3959 LogicVRegister Simulator::frsqrts(VectorFormat vform,
3960                                   LogicVRegister dst,
3961                                   const LogicVRegister& src1,
3962                                   const LogicVRegister& src2) {
3963   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3964     frsqrts<float>(vform, dst, src1, src2);
3965   } else {
3966     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3967     frsqrts<double>(vform, dst, src1, src2);
3968   }
3969   return dst;
3970 }
3971 
3972 
3973 template <typename T>
fcmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)3974 LogicVRegister Simulator::fcmp(VectorFormat vform,
3975                                LogicVRegister dst,
3976                                const LogicVRegister& src1,
3977                                const LogicVRegister& src2,
3978                                Condition cond) {
3979   dst.ClearForWrite(vform);
3980   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3981     bool result = false;
3982     T op1 = src1.Float<T>(i);
3983     T op2 = src2.Float<T>(i);
3984     T nan_result = FPProcessNaNs(op1, op2);
3985     if (!std::isnan(nan_result)) {
3986       switch (cond) {
3987         case eq: result = (op1 == op2); break;
3988         case ge: result = (op1 >= op2); break;
3989         case gt: result = (op1 > op2) ; break;
3990         case le: result = (op1 <= op2); break;
3991         case lt: result = (op1 < op2) ; break;
3992         default: VIXL_UNREACHABLE(); break;
3993       }
3994     }
3995     dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
3996   }
3997   return dst;
3998 }
3999 
4000 
fcmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)4001 LogicVRegister Simulator::fcmp(VectorFormat vform,
4002                                LogicVRegister dst,
4003                                const LogicVRegister& src1,
4004                                const LogicVRegister& src2,
4005                                Condition cond) {
4006   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4007     fcmp<float>(vform, dst, src1, src2, cond);
4008   } else {
4009     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4010     fcmp<double>(vform, dst, src1, src2, cond);
4011   }
4012   return dst;
4013 }
4014 
4015 
fcmp_zero(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,Condition cond)4016 LogicVRegister Simulator::fcmp_zero(VectorFormat vform,
4017                                     LogicVRegister dst,
4018                                     const LogicVRegister& src,
4019                                     Condition cond) {
4020   SimVRegister temp;
4021   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4022     LogicVRegister zero_reg = dup_immediate(vform, temp, float_to_rawbits(0.0));
4023     fcmp<float>(vform, dst, src, zero_reg, cond);
4024   } else {
4025     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4026     LogicVRegister zero_reg = dup_immediate(vform, temp,
4027                                             double_to_rawbits(0.0));
4028     fcmp<double>(vform, dst, src, zero_reg, cond);
4029   }
4030   return dst;
4031 }
4032 
4033 
fabscmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)4034 LogicVRegister Simulator::fabscmp(VectorFormat vform,
4035                                   LogicVRegister dst,
4036                                   const LogicVRegister& src1,
4037                                   const LogicVRegister& src2,
4038                                   Condition cond) {
4039   SimVRegister temp1, temp2;
4040   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4041     LogicVRegister abs_src1 = fabs_<float>(vform, temp1, src1);
4042     LogicVRegister abs_src2 = fabs_<float>(vform, temp2, src2);
4043     fcmp<float>(vform, dst, abs_src1, abs_src2, cond);
4044   } else {
4045     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4046     LogicVRegister abs_src1 = fabs_<double>(vform, temp1, src1);
4047     LogicVRegister abs_src2 = fabs_<double>(vform, temp2, src2);
4048     fcmp<double>(vform, dst, abs_src1, abs_src2, cond);
4049   }
4050   return dst;
4051 }
4052 
4053 
4054 template <typename T>
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4055 LogicVRegister Simulator::fmla(VectorFormat vform,
4056                                LogicVRegister dst,
4057                                const LogicVRegister& src1,
4058                                const LogicVRegister& src2) {
4059   dst.ClearForWrite(vform);
4060   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4061     T op1 = src1.Float<T>(i);
4062     T op2 = src2.Float<T>(i);
4063     T acc = dst.Float<T>(i);
4064     T result = FPMulAdd(acc, op1, op2);
4065     dst.SetFloat(i, result);
4066   }
4067   return dst;
4068 }
4069 
4070 
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4071 LogicVRegister Simulator::fmla(VectorFormat vform,
4072                                LogicVRegister dst,
4073                                const LogicVRegister& src1,
4074                                const LogicVRegister& src2) {
4075   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4076     fmla<float>(vform, dst, src1, src2);
4077   } else {
4078     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4079     fmla<double>(vform, dst, src1, src2);
4080   }
4081   return dst;
4082 }
4083 
4084 
4085 template <typename T>
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4086 LogicVRegister Simulator::fmls(VectorFormat vform,
4087                                LogicVRegister dst,
4088                                const LogicVRegister& src1,
4089                                const LogicVRegister& src2) {
4090   dst.ClearForWrite(vform);
4091   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4092     T op1 = -src1.Float<T>(i);
4093     T op2 = src2.Float<T>(i);
4094     T acc = dst.Float<T>(i);
4095     T result = FPMulAdd(acc, op1, op2);
4096     dst.SetFloat(i, result);
4097   }
4098   return dst;
4099 }
4100 
4101 
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4102 LogicVRegister Simulator::fmls(VectorFormat vform,
4103                                LogicVRegister dst,
4104                                const LogicVRegister& src1,
4105                                const LogicVRegister& src2) {
4106   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4107     fmls<float>(vform, dst, src1, src2);
4108   } else {
4109     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4110     fmls<double>(vform, dst, src1, src2);
4111   }
4112   return dst;
4113 }
4114 
4115 
4116 template <typename T>
fneg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4117 LogicVRegister Simulator::fneg(VectorFormat vform,
4118                                LogicVRegister dst,
4119                                const LogicVRegister& src) {
4120   dst.ClearForWrite(vform);
4121   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4122     T op = src.Float<T>(i);
4123     op = -op;
4124     dst.SetFloat(i, op);
4125   }
4126   return dst;
4127 }
4128 
4129 
fneg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4130 LogicVRegister Simulator::fneg(VectorFormat vform,
4131                                LogicVRegister dst,
4132                                const LogicVRegister& src) {
4133   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4134     fneg<float>(vform, dst, src);
4135   } else {
4136     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4137     fneg<double>(vform, dst, src);
4138   }
4139   return dst;
4140 }
4141 
4142 
4143 template <typename T>
fabs_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4144 LogicVRegister Simulator::fabs_(VectorFormat vform,
4145                                 LogicVRegister dst,
4146                                 const LogicVRegister& src) {
4147   dst.ClearForWrite(vform);
4148   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4149     T op = src.Float<T>(i);
4150     if (copysign(1.0, op) < 0.0) {
4151       op = -op;
4152     }
4153     dst.SetFloat(i, op);
4154   }
4155   return dst;
4156 }
4157 
4158 
fabs_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4159 LogicVRegister Simulator::fabs_(VectorFormat vform,
4160                                 LogicVRegister dst,
4161                                 const LogicVRegister& src) {
4162   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4163     fabs_<float>(vform, dst, src);
4164   } else {
4165     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4166     fabs_<double>(vform, dst, src);
4167   }
4168   return dst;
4169 }
4170 
4171 
fabd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4172 LogicVRegister Simulator::fabd(VectorFormat vform,
4173                                LogicVRegister dst,
4174                                const LogicVRegister& src1,
4175                                const LogicVRegister& src2) {
4176   SimVRegister temp;
4177   fsub(vform, temp, src1, src2);
4178   fabs_(vform, dst, temp);
4179   return dst;
4180 }
4181 
4182 
fsqrt(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4183 LogicVRegister Simulator::fsqrt(VectorFormat vform,
4184                                 LogicVRegister dst,
4185                                 const LogicVRegister& src) {
4186   dst.ClearForWrite(vform);
4187   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4188     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4189       float result = FPSqrt(src.Float<float>(i));
4190       dst.SetFloat(i, result);
4191     }
4192   } else {
4193     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4194     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4195       double result = FPSqrt(src.Float<double>(i));
4196       dst.SetFloat(i, result);
4197     }
4198   }
4199   return dst;
4200 }
4201 
4202 
4203 #define DEFINE_NEON_FP_PAIR_OP(FNP, FN, OP)                          \
4204 LogicVRegister Simulator::FNP(VectorFormat vform,                    \
4205                               LogicVRegister dst,                    \
4206                               const LogicVRegister& src1,            \
4207                               const LogicVRegister& src2) {          \
4208   SimVRegister temp1, temp2;                                         \
4209   uzp1(vform, temp1, src1, src2);                                    \
4210   uzp2(vform, temp2, src1, src2);                                    \
4211   FN(vform, dst, temp1, temp2);                                      \
4212   return dst;                                                        \
4213 }                                                                    \
4214                                                                      \
4215 LogicVRegister Simulator::FNP(VectorFormat vform,                    \
4216                               LogicVRegister dst,                    \
4217                               const LogicVRegister& src) {           \
4218   if (vform == kFormatS) {                                           \
4219     float result = OP(src.Float<float>(0), src.Float<float>(1));     \
4220     dst.SetFloat(0, result);                                         \
4221   } else {                                                           \
4222     VIXL_ASSERT(vform == kFormatD);                                  \
4223     double result = OP(src.Float<double>(0), src.Float<double>(1));  \
4224     dst.SetFloat(0, result);                                         \
4225   }                                                                  \
4226   dst.ClearForWrite(vform);                                          \
4227   return dst;                                                        \
4228 }
NEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)4229 NEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)
4230 #undef DEFINE_NEON_FP_PAIR_OP
4231 
4232 
4233 LogicVRegister Simulator::fminmaxv(VectorFormat vform,
4234                                    LogicVRegister dst,
4235                                    const LogicVRegister& src,
4236                                    FPMinMaxOp Op) {
4237   VIXL_ASSERT(vform == kFormat4S);
4238   USE(vform);
4239   float result1 = (this->*Op)(src.Float<float>(0), src.Float<float>(1));
4240   float result2 = (this->*Op)(src.Float<float>(2), src.Float<float>(3));
4241   float result = (this->*Op)(result1, result2);
4242   dst.ClearForWrite(kFormatS);
4243   dst.SetFloat<float>(0, result);
4244   return dst;
4245 }
4246 
4247 
fmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4248 LogicVRegister Simulator::fmaxv(VectorFormat vform,
4249                                 LogicVRegister dst,
4250                                 const LogicVRegister& src) {
4251   return fminmaxv(vform, dst, src, &Simulator::FPMax);
4252 }
4253 
4254 
fminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4255 LogicVRegister Simulator::fminv(VectorFormat vform,
4256                                 LogicVRegister dst,
4257                                 const LogicVRegister& src) {
4258   return fminmaxv(vform, dst, src, &Simulator::FPMin);
4259 }
4260 
4261 
fmaxnmv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4262 LogicVRegister Simulator::fmaxnmv(VectorFormat vform,
4263                                  LogicVRegister dst,
4264                                  const LogicVRegister& src) {
4265   return fminmaxv(vform, dst, src, &Simulator::FPMaxNM);
4266 }
4267 
4268 
fminnmv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4269 LogicVRegister Simulator::fminnmv(VectorFormat vform,
4270                                   LogicVRegister dst,
4271                                   const LogicVRegister& src) {
4272   return fminmaxv(vform, dst, src, &Simulator::FPMinNM);
4273 }
4274 
4275 
fmul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4276 LogicVRegister Simulator::fmul(VectorFormat vform,
4277                                LogicVRegister dst,
4278                                const LogicVRegister& src1,
4279                                const LogicVRegister& src2,
4280                                int index) {
4281   dst.ClearForWrite(vform);
4282   SimVRegister temp;
4283   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4284     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4285     fmul<float>(vform, dst, src1, index_reg);
4286 
4287   } else {
4288     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4289     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4290     fmul<double>(vform, dst, src1, index_reg);
4291   }
4292   return dst;
4293 }
4294 
4295 
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4296 LogicVRegister Simulator::fmla(VectorFormat vform,
4297                                LogicVRegister dst,
4298                                const LogicVRegister& src1,
4299                                const LogicVRegister& src2,
4300                                int index) {
4301   dst.ClearForWrite(vform);
4302   SimVRegister temp;
4303   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4304     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4305     fmla<float>(vform, dst, src1, index_reg);
4306 
4307   } else {
4308     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4309     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4310     fmla<double>(vform, dst, src1, index_reg);
4311   }
4312   return dst;
4313 }
4314 
4315 
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4316 LogicVRegister Simulator::fmls(VectorFormat vform,
4317                                LogicVRegister dst,
4318                                const LogicVRegister& src1,
4319                                const LogicVRegister& src2,
4320                                int index) {
4321   dst.ClearForWrite(vform);
4322   SimVRegister temp;
4323   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4324     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4325     fmls<float>(vform, dst, src1, index_reg);
4326 
4327   } else {
4328     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4329     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4330     fmls<double>(vform, dst, src1, index_reg);
4331   }
4332   return dst;
4333 }
4334 
4335 
fmulx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4336 LogicVRegister Simulator::fmulx(VectorFormat vform,
4337                                 LogicVRegister dst,
4338                                 const LogicVRegister& src1,
4339                                 const LogicVRegister& src2,
4340                                 int index) {
4341   dst.ClearForWrite(vform);
4342   SimVRegister temp;
4343   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4344     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4345     fmulx<float>(vform, dst, src1, index_reg);
4346 
4347   } else {
4348     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4349     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4350     fmulx<double>(vform, dst, src1, index_reg);
4351   }
4352   return dst;
4353 }
4354 
4355 
frint(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,bool inexact_exception)4356 LogicVRegister Simulator::frint(VectorFormat vform,
4357                                 LogicVRegister dst,
4358                                 const LogicVRegister& src,
4359                                 FPRounding rounding_mode,
4360                                 bool inexact_exception) {
4361   dst.ClearForWrite(vform);
4362   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4363     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4364       float input = src.Float<float>(i);
4365       float rounded = FPRoundInt(input, rounding_mode);
4366       if (inexact_exception && !std::isnan(input) && (input != rounded)) {
4367         FPProcessException();
4368       }
4369       dst.SetFloat<float>(i, rounded);
4370     }
4371   } else {
4372     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4373     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4374       double input = src.Float<double>(i);
4375       double rounded = FPRoundInt(input, rounding_mode);
4376       if (inexact_exception && !std::isnan(input) && (input != rounded)) {
4377         FPProcessException();
4378       }
4379       dst.SetFloat<double>(i, rounded);
4380     }
4381   }
4382   return dst;
4383 }
4384 
4385 
fcvts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,int fbits)4386 LogicVRegister Simulator::fcvts(VectorFormat vform,
4387                                 LogicVRegister dst,
4388                                 const LogicVRegister& src,
4389                                 FPRounding rounding_mode,
4390                                 int fbits) {
4391   dst.ClearForWrite(vform);
4392   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4393     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4394       float op = src.Float<float>(i) * std::pow(2.0f, fbits);
4395       dst.SetInt(vform, i, FPToInt32(op, rounding_mode));
4396     }
4397   } else {
4398     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4399     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4400       double op = src.Float<double>(i) * std::pow(2.0, fbits);
4401       dst.SetInt(vform, i, FPToInt64(op, rounding_mode));
4402     }
4403   }
4404   return dst;
4405 }
4406 
4407 
fcvtu(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,int fbits)4408 LogicVRegister Simulator::fcvtu(VectorFormat vform,
4409                                 LogicVRegister dst,
4410                                 const LogicVRegister& src,
4411                                 FPRounding rounding_mode,
4412                                 int fbits) {
4413   dst.ClearForWrite(vform);
4414   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4415     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4416       float op = src.Float<float>(i) * std::pow(2.0f, fbits);
4417       dst.SetUint(vform, i, FPToUInt32(op, rounding_mode));
4418     }
4419   } else {
4420     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4421     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4422       double op = src.Float<double>(i) * std::pow(2.0, fbits);
4423       dst.SetUint(vform, i, FPToUInt64(op, rounding_mode));
4424     }
4425   }
4426   return dst;
4427 }
4428 
4429 
fcvtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4430 LogicVRegister Simulator::fcvtl(VectorFormat vform,
4431                                 LogicVRegister dst,
4432                                 const LogicVRegister& src) {
4433   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4434     for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
4435       dst.SetFloat(i, FPToFloat(src.Float<float16>(i)));
4436     }
4437   } else {
4438     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4439     for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
4440       dst.SetFloat(i, FPToDouble(src.Float<float>(i)));
4441     }
4442   }
4443   return dst;
4444 }
4445 
4446 
fcvtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4447 LogicVRegister Simulator::fcvtl2(VectorFormat vform,
4448                                  LogicVRegister dst,
4449                                  const LogicVRegister& src) {
4450   int lane_count = LaneCountFromFormat(vform);
4451   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4452     for (int i = 0; i < lane_count; i++) {
4453       dst.SetFloat(i, FPToFloat(src.Float<float16>(i + lane_count)));
4454     }
4455   } else {
4456     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4457     for (int i = 0; i < lane_count; i++) {
4458       dst.SetFloat(i, FPToDouble(src.Float<float>(i + lane_count)));
4459     }
4460   }
4461   return dst;
4462 }
4463 
4464 
fcvtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4465 LogicVRegister Simulator::fcvtn(VectorFormat vform,
4466                                 LogicVRegister dst,
4467                                 const LogicVRegister& src) {
4468   if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
4469     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4470       dst.SetFloat(i, FPToFloat16(src.Float<float>(i), FPTieEven));
4471     }
4472   } else {
4473     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4474     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4475       dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPTieEven));
4476     }
4477   }
4478   return dst;
4479 }
4480 
4481 
fcvtn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4482 LogicVRegister Simulator::fcvtn2(VectorFormat vform,
4483                                  LogicVRegister dst,
4484                                  const LogicVRegister& src) {
4485   int lane_count = LaneCountFromFormat(vform) / 2;
4486   if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
4487     for (int i = lane_count - 1; i >= 0; i--) {
4488       dst.SetFloat(i + lane_count, FPToFloat16(src.Float<float>(i), FPTieEven));
4489     }
4490   } else {
4491     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4492     for (int i = lane_count - 1; i >= 0; i--) {
4493       dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPTieEven));
4494     }
4495   }
4496   return dst;
4497 }
4498 
4499 
fcvtxn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4500 LogicVRegister Simulator::fcvtxn(VectorFormat vform,
4501                                  LogicVRegister dst,
4502                                  const LogicVRegister& src) {
4503   dst.ClearForWrite(vform);
4504   VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4505   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4506     dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPRoundOdd));
4507   }
4508   return dst;
4509 }
4510 
4511 
fcvtxn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4512 LogicVRegister Simulator::fcvtxn2(VectorFormat vform,
4513                                   LogicVRegister dst,
4514                                   const LogicVRegister& src) {
4515   VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4516   int lane_count = LaneCountFromFormat(vform) / 2;
4517   for (int i = lane_count - 1; i >= 0; i--) {
4518     dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPRoundOdd));
4519   }
4520   return dst;
4521 }
4522 
4523 
4524 // Based on reference C function recip_sqrt_estimate from ARM ARM.
recip_sqrt_estimate(double a)4525 double Simulator::recip_sqrt_estimate(double a) {
4526   int q0, q1, s;
4527   double r;
4528   if (a < 0.5) {
4529     q0 = static_cast<int>(a * 512.0);
4530     r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
4531   } else  {
4532     q1 = static_cast<int>(a * 256.0);
4533     r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
4534   }
4535   s = static_cast<int>(256.0 * r + 0.5);
4536   return static_cast<double>(s) / 256.0;
4537 }
4538 
4539 
Bits(uint64_t val,int start_bit,int end_bit)4540 static inline uint64_t Bits(uint64_t val, int start_bit, int end_bit) {
4541   return unsigned_bitextract_64(start_bit, end_bit, val);
4542 }
4543 
4544 
4545 template <typename T>
FPRecipSqrtEstimate(T op)4546 T Simulator::FPRecipSqrtEstimate(T op) {
4547   if (std::isnan(op)) {
4548     return FPProcessNaN(op);
4549   } else if (op == 0.0) {
4550     if (copysign(1.0, op) < 0.0) {
4551       return kFP64NegativeInfinity;
4552     } else {
4553       return kFP64PositiveInfinity;
4554     }
4555   } else if (copysign(1.0, op) < 0.0) {
4556     FPProcessException();
4557     return FPDefaultNaN<T>();
4558   } else if (std::isinf(op)) {
4559     return 0.0;
4560   } else {
4561     uint64_t fraction;
4562     int exp, result_exp;
4563 
4564     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4565       exp = float_exp(op);
4566       fraction = float_mantissa(op);
4567       fraction <<= 29;
4568     } else {
4569       exp = double_exp(op);
4570       fraction = double_mantissa(op);
4571     }
4572 
4573     if (exp == 0) {
4574       while (Bits(fraction, 51, 51) == 0) {
4575         fraction = Bits(fraction, 50, 0) << 1;
4576         exp -= 1;
4577       }
4578       fraction = Bits(fraction, 50, 0) << 1;
4579     }
4580 
4581     double scaled;
4582     if (Bits(exp, 0, 0) == 0) {
4583       scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
4584     } else {
4585       scaled = double_pack(0, 1021, Bits(fraction, 51, 44) << 44);
4586     }
4587 
4588     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4589       result_exp = (380 - exp) / 2;
4590     } else {
4591       result_exp = (3068 - exp) / 2;
4592     }
4593 
4594     uint64_t estimate = double_to_rawbits(recip_sqrt_estimate(scaled));
4595 
4596     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4597       uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4598       uint32_t est_bits = static_cast<uint32_t>(Bits(estimate, 51, 29));
4599       return float_pack(0, exp_bits, est_bits);
4600     } else {
4601       return double_pack(0, Bits(result_exp, 10, 0), Bits(estimate, 51, 0));
4602     }
4603   }
4604 }
4605 
4606 
frsqrte(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4607 LogicVRegister Simulator::frsqrte(VectorFormat vform,
4608                                   LogicVRegister dst,
4609                                   const LogicVRegister& src) {
4610   dst.ClearForWrite(vform);
4611   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4612     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4613       float input = src.Float<float>(i);
4614       dst.SetFloat(i, FPRecipSqrtEstimate<float>(input));
4615     }
4616   } else {
4617     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4618     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4619       double input = src.Float<double>(i);
4620       dst.SetFloat(i, FPRecipSqrtEstimate<double>(input));
4621     }
4622   }
4623   return dst;
4624 }
4625 
4626 template <typename T>
FPRecipEstimate(T op,FPRounding rounding)4627 T Simulator::FPRecipEstimate(T op, FPRounding rounding) {
4628   uint32_t sign;
4629 
4630   if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4631     sign = float_sign(op);
4632   } else {
4633     sign = double_sign(op);
4634   }
4635 
4636   if (std::isnan(op)) {
4637     return FPProcessNaN(op);
4638   } else if (std::isinf(op)) {
4639     return (sign == 1) ? -0.0 : 0.0;
4640   } else if (op == 0.0) {
4641     FPProcessException();  // FPExc_DivideByZero exception.
4642     return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
4643   } else if (((sizeof(T) == sizeof(float)) &&  // NOLINT(runtime/sizeof)
4644               (std::fabs(op) < std::pow(2.0, -128.0))) ||
4645              ((sizeof(T) == sizeof(double)) &&  // NOLINT(runtime/sizeof)
4646               (std::fabs(op) < std::pow(2.0, -1024.0)))) {
4647     bool overflow_to_inf = false;
4648     switch (rounding) {
4649       case FPTieEven: overflow_to_inf = true; break;
4650       case FPPositiveInfinity: overflow_to_inf = (sign == 0); break;
4651       case FPNegativeInfinity: overflow_to_inf = (sign == 1); break;
4652       case FPZero: overflow_to_inf = false; break;
4653       default: break;
4654     }
4655     FPProcessException();  // FPExc_Overflow and FPExc_Inexact.
4656     if (overflow_to_inf) {
4657       return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
4658     } else {
4659       // Return FPMaxNormal(sign).
4660       if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4661         return float_pack(sign, 0xfe, 0x07fffff);
4662       } else {
4663         return double_pack(sign, 0x7fe, 0x0fffffffffffffl);
4664       }
4665     }
4666   } else {
4667     uint64_t fraction;
4668     int exp, result_exp;
4669     uint32_t sign;
4670 
4671     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4672       sign = float_sign(op);
4673       exp = float_exp(op);
4674       fraction = float_mantissa(op);
4675       fraction <<= 29;
4676     } else {
4677       sign = double_sign(op);
4678       exp = double_exp(op);
4679       fraction = double_mantissa(op);
4680     }
4681 
4682     if (exp == 0) {
4683       if (Bits(fraction, 51, 51) == 0) {
4684         exp -= 1;
4685         fraction = Bits(fraction, 49, 0) << 2;
4686       } else {
4687         fraction = Bits(fraction, 50, 0) << 1;
4688       }
4689     }
4690 
4691     double scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
4692 
4693     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4694       result_exp = (253 - exp);  // In range 253-254 = -1 to 253+1 = 254.
4695     } else {
4696       result_exp = (2045 - exp);  // In range 2045-2046 = -1 to 2045+1 = 2046.
4697     }
4698 
4699     double estimate = recip_estimate(scaled);
4700 
4701     fraction = double_mantissa(estimate);
4702     if (result_exp == 0) {
4703       fraction = (UINT64_C(1) << 51) | Bits(fraction, 51, 1);
4704     } else if (result_exp == -1) {
4705       fraction = (UINT64_C(1) << 50) | Bits(fraction, 51, 2);
4706       result_exp = 0;
4707     }
4708     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4709       uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4710       uint32_t frac_bits = static_cast<uint32_t>(Bits(fraction, 51, 29));
4711       return float_pack(sign, exp_bits, frac_bits);
4712     } else {
4713       return double_pack(sign, Bits(result_exp, 10, 0), Bits(fraction, 51, 0));
4714     }
4715   }
4716 }
4717 
4718 
frecpe(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding round)4719 LogicVRegister Simulator::frecpe(VectorFormat vform,
4720                                  LogicVRegister dst,
4721                                  const LogicVRegister& src,
4722                                  FPRounding round) {
4723   dst.ClearForWrite(vform);
4724   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4725     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4726       float input = src.Float<float>(i);
4727       dst.SetFloat(i, FPRecipEstimate<float>(input, round));
4728     }
4729   } else {
4730     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4731     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4732       double input = src.Float<double>(i);
4733       dst.SetFloat(i, FPRecipEstimate<double>(input, round));
4734     }
4735   }
4736   return dst;
4737 }
4738 
4739 
ursqrte(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4740 LogicVRegister Simulator::ursqrte(VectorFormat vform,
4741                                   LogicVRegister dst,
4742                                   const LogicVRegister& src) {
4743   dst.ClearForWrite(vform);
4744   uint64_t operand;
4745   uint32_t result;
4746   double dp_operand, dp_result;
4747   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4748     operand = src.Uint(vform, i);
4749     if (operand <= 0x3FFFFFFF) {
4750       result = 0xFFFFFFFF;
4751     } else {
4752       dp_operand = operand * std::pow(2.0, -32);
4753       dp_result = recip_sqrt_estimate(dp_operand) * std::pow(2.0, 31);
4754       result = static_cast<uint32_t>(dp_result);
4755     }
4756     dst.SetUint(vform, i, result);
4757   }
4758   return dst;
4759 }
4760 
4761 
4762 // Based on reference C function recip_estimate from ARM ARM.
recip_estimate(double a)4763 double Simulator::recip_estimate(double a) {
4764   int q, s;
4765   double r;
4766   q = static_cast<int>(a * 512.0);
4767   r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
4768   s = static_cast<int>(256.0 * r + 0.5);
4769   return static_cast<double>(s) / 256.0;
4770 }
4771 
4772 
urecpe(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4773 LogicVRegister Simulator::urecpe(VectorFormat vform,
4774                                  LogicVRegister dst,
4775                                  const LogicVRegister& src) {
4776   dst.ClearForWrite(vform);
4777   uint64_t operand;
4778   uint32_t result;
4779   double dp_operand, dp_result;
4780   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4781     operand = src.Uint(vform, i);
4782     if (operand <= 0x7FFFFFFF) {
4783       result = 0xFFFFFFFF;
4784     } else {
4785       dp_operand = operand * std::pow(2.0, -32);
4786       dp_result = recip_estimate(dp_operand) * std::pow(2.0, 31);
4787       result = static_cast<uint32_t>(dp_result);
4788     }
4789     dst.SetUint(vform, i, result);
4790   }
4791   return dst;
4792 }
4793 
4794 template <typename T>
frecpx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4795 LogicVRegister Simulator::frecpx(VectorFormat vform,
4796                                  LogicVRegister dst,
4797                                  const LogicVRegister& src) {
4798   dst.ClearForWrite(vform);
4799   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4800     T op = src.Float<T>(i);
4801     T result;
4802     if (std::isnan(op)) {
4803        result = FPProcessNaN(op);
4804     } else {
4805       int exp;
4806       uint32_t sign;
4807       if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4808         sign = float_sign(op);
4809         exp = float_exp(op);
4810         exp = (exp == 0) ? (0xFF - 1) : static_cast<int>(Bits(~exp, 7, 0));
4811         result = float_pack(sign, exp, 0);
4812       } else {
4813         sign = double_sign(op);
4814         exp = double_exp(op);
4815         exp = (exp == 0) ? (0x7FF - 1) : static_cast<int>(Bits(~exp, 10, 0));
4816         result = double_pack(sign, exp, 0);
4817       }
4818     }
4819     dst.SetFloat(i, result);
4820   }
4821   return dst;
4822 }
4823 
4824 
frecpx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4825 LogicVRegister Simulator::frecpx(VectorFormat vform,
4826                                  LogicVRegister dst,
4827                                  const LogicVRegister& src) {
4828   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4829     frecpx<float>(vform, dst, src);
4830   } else {
4831     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4832     frecpx<double>(vform, dst, src);
4833   }
4834   return dst;
4835 }
4836 
scvtf(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int fbits,FPRounding round)4837 LogicVRegister Simulator::scvtf(VectorFormat vform,
4838                                 LogicVRegister dst,
4839                                 const LogicVRegister& src,
4840                                 int fbits,
4841                                 FPRounding round) {
4842   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4843     if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4844       float result = FixedToFloat(src.Int(kFormatS, i), fbits, round);
4845       dst.SetFloat<float>(i, result);
4846     } else {
4847       VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4848       double result = FixedToDouble(src.Int(kFormatD, i), fbits, round);
4849       dst.SetFloat<double>(i, result);
4850     }
4851   }
4852   return dst;
4853 }
4854 
4855 
ucvtf(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int fbits,FPRounding round)4856 LogicVRegister Simulator::ucvtf(VectorFormat vform,
4857                                 LogicVRegister dst,
4858                                 const LogicVRegister& src,
4859                                 int fbits,
4860                                 FPRounding round) {
4861   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4862     if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4863       float result = UFixedToFloat(src.Uint(kFormatS, i), fbits, round);
4864       dst.SetFloat<float>(i, result);
4865     } else {
4866       VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4867       double result = UFixedToDouble(src.Uint(kFormatD, i), fbits, round);
4868       dst.SetFloat<double>(i, result);
4869     }
4870   }
4871   return dst;
4872 }
4873 
4874 
4875 }  // namespace vixl
4876 
4877 #endif  // VIXL_INCLUDE_SIMULATOR
4878