10cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Copyright 2015, ARM Limited
20cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// All rights reserved.
30cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
40cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Redistribution and use in source and binary forms, with or without
50cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// modification, are permitted provided that the following conditions are met:
60cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
70cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Redistributions of source code must retain the above copyright notice,
80cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     this list of conditions and the following disclaimer.
90cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     this list of conditions and the following disclaimer in the documentation
110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     and/or other materials provided with the distribution.
120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     used to endorse or promote products derived from this software without
140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     specific prior written permission.
150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
279795cffa6b242fddee25847d17136a8da5b5c2d7Phil Wang#ifdef VIXL_INCLUDE_SIMULATOR
289795cffa6b242fddee25847d17136a8da5b5c2d7Phil Wang
290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include <cmath>
300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/simulator-a64.h"
310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlnamespace vixl {
330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
340cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate<> double Simulator::FPDefaultNaN<double>() {
350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return kFP64DefaultNaN;
360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
390cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate<> float Simulator::FPDefaultNaN<float>() {
400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return kFP32DefaultNaN;
410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// See FPRound for a description of this function.
440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlstatic inline double FPRoundToDouble(int64_t sign, int64_t exponent,
450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                     uint64_t mantissa, FPRounding round_mode) {
460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t bits =
470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign,
480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                                 exponent,
490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                                 mantissa,
500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                                 round_mode);
510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rawbits_to_double(bits);
520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// See FPRound for a description of this function.
560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlstatic inline float FPRoundToFloat(int64_t sign, int64_t exponent,
570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   uint64_t mantissa, FPRounding round_mode) {
580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int32_t bits =
590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign,
600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                               exponent,
610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                               mantissa,
620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                               round_mode);
630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rawbits_to_float(bits);
640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// See FPRound for a description of this function.
680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlstatic inline float16 FPRoundToFloat16(int64_t sign,
690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       int64_t exponent,
700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       uint64_t mantissa,
710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       FPRounding round_mode) {
720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FPRound<float16, kFloat16ExponentBits, kFloat16MantissaBits>(
730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sign, exponent, mantissa, round_mode);
740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
770cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) {
780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (src >= 0) {
790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return UFixedToDouble(src, fbits, round);
800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // This works for all negative values, including INT64_MIN.
820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return -UFixedToDouble(-src, fbits, round);
830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
870cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) {
880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // An input of 0 is a special case because the result is effectively
890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (src == 0) {
910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0.0;
920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Calculate the exponent. The highest significant bit will have the value
950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 2^exponent.
960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const int highest_significant_bit = 63 - CountLeadingZeros(src);
970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const int64_t exponent = highest_significant_bit - fbits;
980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FPRoundToDouble(0, exponent, src, round);
1000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) {
1040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (src >= 0) {
1050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return UFixedToFloat(src, fbits, round);
1060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
1070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // This works for all negative values, including INT64_MIN.
1080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return -UFixedToFloat(-src, fbits, round);
1090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
1100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1130cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) {
1140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // An input of 0 is a special case because the result is effectively
1150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
1160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (src == 0) {
1170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0.0f;
1180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
1190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Calculate the exponent. The highest significant bit will have the value
1210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 2^exponent.
1220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const int highest_significant_bit = 63 - CountLeadingZeros(src);
1230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const int32_t exponent = highest_significant_bit - fbits;
1240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FPRoundToFloat(0, exponent, src, round);
1260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1290cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::FPToDouble(float value) {
1300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (std::fpclassify(value)) {
1310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NAN: {
1320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (IsSignallingNaN(value)) {
1330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
1340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
1350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (DN()) return kFP64DefaultNaN;
1360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert NaNs as the processor would:
1380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The sign is propagated.
1390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The payload (mantissa) is transferred entirely, except that the top
1400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    bit is forced to '1', making the result a quiet NaN. The unused
1410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    (low-order) payload bits are set to 0.
1420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint32_t raw = float_to_rawbits(value);
1430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t sign = raw >> 31;
1450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t exponent = (1 << 11) - 1;
1460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t payload = unsigned_bitextract_64(21, 0, raw);
1470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      payload <<= (52 - 23);  // The unused low-order bits should be 0.
1480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      payload |= (UINT64_C(1) << 51);  // Force a quiet NaN.
1490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return rawbits_to_double((sign << 63) | (exponent << 52) | payload);
1510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
1520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_ZERO:
1540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NORMAL:
1550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_SUBNORMAL:
1560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_INFINITE: {
1570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // All other inputs are preserved in a standard cast, because every value
1580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // representable using an IEEE-754 float is also representable using an
1590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // IEEE-754 double.
1600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return static_cast<double>(value);
1610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
1620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
1630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_UNREACHABLE();
1650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return static_cast<double>(value);
1660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat Simulator::FPToFloat(float16 value) {
1700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t sign = value >> 15;
1710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t exponent = unsigned_bitextract_32(
1720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      kFloat16MantissaBits + kFloat16ExponentBits - 1, kFloat16MantissaBits,
1730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      value);
1740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t mantissa = unsigned_bitextract_32(
1750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      kFloat16MantissaBits - 1, 0, value);
1760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (float16classify(value)) {
1780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_ZERO:
1790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? 0.0f : -0.0f;
1800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_INFINITE:
1820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? kFP32PositiveInfinity : kFP32NegativeInfinity;
1830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_SUBNORMAL: {
1850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Calculate shift required to put mantissa into the most-significant bits
1860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // of the destination mantissa.
1870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      int shift = CountLeadingZeros(mantissa << (32 - 10));
1880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Shift mantissa and discard implicit '1'.
1900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits) + shift + 1;
1910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa &= (1 << kFloatMantissaBits) - 1;
1920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Adjust the exponent for the shift applied, and rebias.
1940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exponent = exponent - shift + (-15 + 127);
1950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
1960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
1970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NAN:
1990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (IsSignallingNaN(value)) {
2000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
2010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
2020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (DN()) return kFP32DefaultNaN;
2030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert NaNs as the processor would:
2050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The sign is propagated.
2060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The payload (mantissa) is transferred entirely, except that the top
2070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    bit is forced to '1', making the result a quiet NaN. The unused
2080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    (low-order) payload bits are set to 0.
2090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exponent = (1 << kFloatExponentBits) - 1;
2100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Increase bits in mantissa, making low-order bits 0.
2120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
2130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa |= 1 << 22;  // Force a quiet NaN.
2140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
2150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NORMAL:
2170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Increase bits in mantissa, making low-order bits 0.
2180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
2190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Change exponent bias.
2210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exponent += (-15 + 127);
2220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
2230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default: VIXL_UNREACHABLE();
2250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
2260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rawbits_to_float((sign << 31) |
2270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          (exponent << kFloatMantissaBits) |
2280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          mantissa);
2290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat16 Simulator::FPToFloat16(float value, FPRounding round_mode) {
2330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Only the FPTieEven rounding mode is implemented.
2340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(round_mode == FPTieEven);
2350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(round_mode);
2360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t raw = float_to_rawbits(value);
2380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int32_t sign = raw >> 31;
2390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int32_t exponent = unsigned_bitextract_32(30, 23, raw) - 127;
2400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t mantissa = unsigned_bitextract_32(22, 0, raw);
2410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (std::fpclassify(value)) {
2430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NAN: {
2440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (IsSignallingNaN(value)) {
2450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
2460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
2470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (DN()) return kFP16DefaultNaN;
2480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert NaNs as the processor would:
2500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The sign is propagated.
2510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The payload (mantissa) is transferred as much as possible, except
2520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
2530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float16 result = (sign == 0) ? kFP16PositiveInfinity
2540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   : kFP16NegativeInfinity;
2550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result |= mantissa >> (kFloatMantissaBits - kFloat16MantissaBits);
2560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result |= (1 << 9);  // Force a quiet NaN;
2570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return result;
2580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
2590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_ZERO:
2610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? 0 : 0x8000;
2620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_INFINITE:
2640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
2650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NORMAL:
2670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_SUBNORMAL: {
2680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert float-to-half as the processor would, assuming that FPCR.FZ
2690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // (flush-to-zero) is not set.
2700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Add the implicit '1' bit to the mantissa.
2720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa += (1 << 23);
2730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
2740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
2750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
2760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_UNREACHABLE();
2780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return 0;
2790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2820cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat16 Simulator::FPToFloat16(double value, FPRounding round_mode) {
2830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Only the FPTieEven rounding mode is implemented.
2840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(round_mode == FPTieEven);
2850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(round_mode);
2860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t raw = double_to_rawbits(value);
2880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int32_t sign = raw >> 63;
2890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023;
2900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t mantissa = unsigned_bitextract_64(51, 0, raw);
2910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (std::fpclassify(value)) {
2930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NAN: {
2940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (IsSignallingNaN(value)) {
2950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
2960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
2970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (DN()) return kFP16DefaultNaN;
2980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert NaNs as the processor would:
3000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The sign is propagated.
3010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The payload (mantissa) is transferred as much as possible, except
3020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
3030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float16 result = (sign == 0) ? kFP16PositiveInfinity
3040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   : kFP16NegativeInfinity;
3050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result |= mantissa >> (kDoubleMantissaBits - kFloat16MantissaBits);
3060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result |= (1 << 9);  // Force a quiet NaN;
3070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return result;
3080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
3090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_ZERO:
3110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? 0 : 0x8000;
3120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_INFINITE:
3140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
3150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NORMAL:
3170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_SUBNORMAL: {
3180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert double-to-half as the processor would, assuming that FPCR.FZ
3190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // (flush-to-zero) is not set.
3200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Add the implicit '1' bit to the mantissa.
3220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mantissa += (UINT64_C(1) << 52);
3230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
3240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
3250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
3260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_UNREACHABLE();
3280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return 0;
3290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlfloat Simulator::FPToFloat(double value, FPRounding round_mode) {
3330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Only the FPTieEven rounding mode is implemented.
3340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
3350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(round_mode);
3360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (std::fpclassify(value)) {
3380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NAN: {
3390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (IsSignallingNaN(value)) {
3400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
3410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
3420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (DN()) return kFP32DefaultNaN;
3430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert NaNs as the processor would:
3450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The sign is propagated.
3460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //  - The payload (mantissa) is transferred as much as possible, except
3470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
3480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t raw = double_to_rawbits(value);
3490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint32_t sign = raw >> 63;
3510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint32_t exponent = (1 << 8) - 1;
3525ee436a3a51863de7b5dc9326cf02895248050c2armvixl      uint32_t payload =
3535ee436a3a51863de7b5dc9326cf02895248050c2armvixl          static_cast<uint32_t>(unsigned_bitextract_64(50, 52 - 23, raw));
3540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      payload |= (1 << 22);   // Force a quiet NaN.
3550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return rawbits_to_float((sign << 31) | (exponent << 23) | payload);
3570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
3580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_ZERO:
3600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_INFINITE: {
3610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // In a C++ cast, any value representable in the target type will be
3620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // unchanged. This is always the case for +/-0.0 and infinities.
3630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return static_cast<float>(value);
3640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
3650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_NORMAL:
3670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FP_SUBNORMAL: {
3680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Convert double-to-float as the processor would, assuming that FPCR.FZ
3690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // (flush-to-zero) is not set.
3700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t raw = double_to_rawbits(value);
3710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Extract the IEEE-754 double components.
3720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint32_t sign = raw >> 63;
3730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Extract the exponent and remove the IEEE-754 encoding bias.
3745ee436a3a51863de7b5dc9326cf02895248050c2armvixl      int32_t exponent =
3755ee436a3a51863de7b5dc9326cf02895248050c2armvixl          static_cast<int32_t>(unsigned_bitextract_64(62, 52, raw)) - 1023;
3760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Extract the mantissa and add the implicit '1' bit.
3770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint64_t mantissa = unsigned_bitextract_64(51, 0, raw);
3780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (std::fpclassify(value) == FP_NORMAL) {
3790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        mantissa |= (UINT64_C(1) << 52);
3800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
3810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FPRoundToFloat(sign, exponent, mantissa, round_mode);
3820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
3830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
3840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_UNREACHABLE();
3860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return value;
3870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld1(VectorFormat vform,
3910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
3920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
3930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
3940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.ReadUintFromMem(vform, i, addr);
3960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr += LaneSizeInBytesFromFormat(vform);
3970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
3980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld1(VectorFormat vform,
4020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
4030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
4040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
4050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ReadUintFromMem(vform, index, addr);
4060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld1r(VectorFormat vform,
4100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst,
4110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     uint64_t addr) {
4120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
4130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.ReadUintFromMem(vform, i, addr);
4150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
4160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld2(VectorFormat vform,
4200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
4210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
4220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
4230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
4240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
4250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
4260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + esize;
4270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr1);
4290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
4300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr1 += 2 * esize;
4310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 2 * esize;
4320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
4330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld2(VectorFormat vform,
4370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
4380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
4390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
4400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
4410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
4420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
4430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
4440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ReadUintFromMem(vform, index, addr1);
4450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ReadUintFromMem(vform, index, addr2);
4460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld2r(VectorFormat vform,
4500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst1,
4510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst2,
4520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     uint64_t addr) {
4530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
4540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
4550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
4560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr);
4580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
4590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
4600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld3(VectorFormat vform,
4640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
4650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
4660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
4670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
4680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
4690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
4700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
4710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
4720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + esize;
4730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + esize;
4740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr1);
4760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
4770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.ReadUintFromMem(vform, i, addr3);
4780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr1 += 3 * esize;
4790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 3 * esize;
4800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr3 += 3 * esize;
4810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
4820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld3(VectorFormat vform,
4860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
4870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
4880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
4890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
4900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
4910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
4920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
4930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
4940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
4950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
4960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ReadUintFromMem(vform, index, addr1);
4970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ReadUintFromMem(vform, index, addr2);
4980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ReadUintFromMem(vform, index, addr3);
4990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5020cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld3r(VectorFormat vform,
5030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst1,
5040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst2,
5050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst3,
5060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     uint64_t addr) {
5070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
5080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
5090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
5100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
5110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr);
5140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
5150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.ReadUintFromMem(vform, i, addr3);
5160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld4(VectorFormat vform,
5210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
5220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
5230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
5240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst4,
5250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
5260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
5270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
5280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
5290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst4.ClearForWrite(vform);
5300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
5310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + esize;
5320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + esize;
5330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr4 = addr3 + esize;
5340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr1);
5360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
5370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.ReadUintFromMem(vform, i, addr3);
5380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst4.ReadUintFromMem(vform, i, addr4);
5390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr1 += 4 * esize;
5400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 4 * esize;
5410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr3 += 4 * esize;
5420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr4 += 4 * esize;
5430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld4(VectorFormat vform,
5480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst1,
5490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
5500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
5510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst4,
5520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
5530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr1) {
5540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
5550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
5560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
5570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst4.ClearForWrite(vform);
5580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
5590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
5610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ReadUintFromMem(vform, index, addr1);
5620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ReadUintFromMem(vform, index, addr2);
5630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ReadUintFromMem(vform, index, addr3);
5640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst4.ReadUintFromMem(vform, index, addr4);
5650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::ld4r(VectorFormat vform,
5690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst1,
5700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst2,
5710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst3,
5720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LogicVRegister dst4,
5730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     uint64_t addr) {
5740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst1.ClearForWrite(vform);
5750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.ClearForWrite(vform);
5760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.ClearForWrite(vform);
5770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst4.ClearForWrite(vform);
5780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
5790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
5810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst1.ReadUintFromMem(vform, i, addr);
5830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.ReadUintFromMem(vform, i, addr2);
5840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.ReadUintFromMem(vform, i, addr3);
5850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst4.ReadUintFromMem(vform, i, addr4);
5860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st1(VectorFormat vform,
5910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister src,
5920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
5930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    src.WriteUintToMem(vform, i, addr);
5950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr += LaneSizeInBytesFromFormat(vform);
5960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st1(VectorFormat vform,
6010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister src,
6020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
6030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  src.WriteUintToMem(vform, index, addr);
6050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st2(VectorFormat vform,
6090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + esize;
6140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.WriteUintToMem(vform, i, addr);
6160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.WriteUintToMem(vform, i, addr2);
6170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr += 2 * esize;
6180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 2 * esize;
6190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
6200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st2(VectorFormat vform,
6240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
6270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.WriteUintToMem(vform, index, addr);
6300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
6310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st3(VectorFormat vform,
6350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
6380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + esize;
6410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + esize;
6420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.WriteUintToMem(vform, i, addr);
6440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.WriteUintToMem(vform, i, addr2);
6450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.WriteUintToMem(vform, i, addr3);
6460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr += 3 * esize;
6470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 3 * esize;
6480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr3 += 3 * esize;
6490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
6500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st3(VectorFormat vform,
6540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
6570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
6580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.WriteUintToMem(vform, index, addr);
6610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
6620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.WriteUintToMem(vform, index, addr + 2 * esize);
6630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st4(VectorFormat vform,
6670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
6700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst4,
6710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr2 = addr + esize;
6740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr3 = addr2 + esize;
6750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t addr4 = addr3 + esize;
6760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.WriteUintToMem(vform, i, addr);
6780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst2.WriteUintToMem(vform, i, addr2);
6790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst3.WriteUintToMem(vform, i, addr3);
6800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst4.WriteUintToMem(vform, i, addr4);
6810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr += 4 * esize;
6820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr2 += 4 * esize;
6830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr3 += 4 * esize;
6840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr4 += 4 * esize;
6850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
6860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Simulator::st4(VectorFormat vform,
6900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst,
6910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst2,
6920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst3,
6930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LogicVRegister dst4,
6940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index,
6950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    uint64_t addr) {
6960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBytesFromFormat(vform);
6970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.WriteUintToMem(vform, index, addr);
6980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
6990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst3.WriteUintToMem(vform, index, addr + 2 * esize);
7000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst4.WriteUintToMem(vform, index, addr + 3 * esize);
7010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::cmp(VectorFormat vform,
7050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
7060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
7070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2,
7080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              Condition cond) {
7090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
7100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t  sa = src1.Int(vform, i);
7120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t  sb = src2.Int(vform, i);
7130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ua = src1.Uint(vform, i);
7140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ub = src2.Uint(vform, i);
7150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool result = false;
7160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (cond) {
7170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case eq: result = (ua == ub); break;
7180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case ge: result = (sa >= sb); break;
7190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case gt: result = (sa > sb) ; break;
7200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case hi: result = (ua > ub) ; break;
7210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case hs: result = (ua >= ub); break;
7220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case lt: result = (sa < sb) ; break;
7230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case le: result = (sa <= sb); break;
7240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default: VIXL_UNREACHABLE(); break;
7250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
7260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
7270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
7280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
7290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::cmp(VectorFormat vform,
7330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
7340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
7350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int imm,
7360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              Condition cond) {
7370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
7380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister imm_reg = dup_immediate(vform, temp, imm);
7390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return cmp(vform, dst, src1, imm_reg, cond);
7400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::cmptst(VectorFormat vform,
7440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
7450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
7460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
7470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
7480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ua = src1.Uint(vform, i);
7500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ub = src2.Uint(vform, i);
7510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, ((ua & ub) != 0) ? MaxUintFromFormat(vform) : 0);
7520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
7530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
7540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::add(VectorFormat vform,
7580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
7590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
7600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
7610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
7620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // TODO(all): consider assigning the result of LaneCountFromFormat to a local.
7630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for unsigned saturation.
7650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ua = src1.UintLeftJustified(vform, i);
7660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ub = src2.UintLeftJustified(vform, i);
7670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ur = ua + ub;
7680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (ur < ua) {
7690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUnsignedSat(i, true);
7700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
7710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for signed saturation.
7730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sa = src1.IntLeftJustified(vform, i);
7740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sb = src2.IntLeftJustified(vform, i);
7750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sr = sa + sb;
7760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If the signs of the operands are the same, but different from the result,
7770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // there was an overflow.
7780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (((sa >= 0) == (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
7790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(i, sa >= 0);
7800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
7810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, src1.Int(vform, i) + src2.Int(vform, i));
7830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
7840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
7850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addp(VectorFormat vform,
7890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
7900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
7910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
7920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
7930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uzp1(vform, temp1, src1, src2);
7940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uzp2(vform, temp2, src1, src2);
7950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, temp1, temp2);
7960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
7970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mla(VectorFormat vform,
8010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
8040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, temp, src1, src2);
8060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, dst, temp);
8070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
8080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mls(VectorFormat vform,
8120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
8150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, temp, src1, src2);
8170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, dst, temp);
8180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
8190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mul(VectorFormat vform,
8230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
8260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
8270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
8280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) * src2.Uint(vform, i));
8290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
8300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
8310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mul(VectorFormat vform,
8350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2,
8380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int index) {
8390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return mul(vform, dst, src1, dup_element(indexform, temp, src2, index));
8420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mla(VectorFormat vform,
8460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2,
8490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int index) {
8500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return mla(vform, dst, src1, dup_element(indexform, temp, src2, index));
8530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mls(VectorFormat vform,
8570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
8580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
8590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2,
8600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int index) {
8610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return mls(vform, dst, src1, dup_element(indexform, temp, src2, index));
8640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smull(VectorFormat vform,
8680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
8690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
8700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
8710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
8720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
8740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
8750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smull(vform, dst, src1, dup_element(indexform, temp, src2, index));
8760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smull2(VectorFormat vform,
8800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
8810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
8820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
8830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
8840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
8860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
8870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
8880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8910cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umull(VectorFormat vform,
8920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
8930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
8940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
8950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
8960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
8970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
8980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
8990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umull(vform, dst, src1, dup_element(indexform, temp, src2, index));
9000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umull2(VectorFormat vform,
9040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlal(VectorFormat vform,
9160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
9240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlal2(VectorFormat vform,
9280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlal(VectorFormat vform,
9400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
9480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlal2(VectorFormat vform,
9520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlsl(VectorFormat vform,
9640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
9720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9750cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlsl2(VectorFormat vform,
9760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return smlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlsl(VectorFormat vform,
9880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
9890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
9900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
9910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
9920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
9930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
9940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
9960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlsl2(VectorFormat vform,
10000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
10010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
10020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
10030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
10040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return umlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmull(VectorFormat vform,
10120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmull(vform, dst, src1, dup_element(indexform, temp, src2, index));
10200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmull2(VectorFormat vform,
10240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlal(VectorFormat vform,
10360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
10440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlal2(VectorFormat vform,
10480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlsl(VectorFormat vform,
10600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
10680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
10720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform =
10780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmulh(VectorFormat vform,
10840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
10890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform = VectorFormatFillQ(vform);
10900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
10910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrdmulh(VectorFormat vform,
10950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
10960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
10970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
10980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int index) {
10990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
11000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat indexform = VectorFormatFillQ(vform);
11010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqrdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
11020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11050cc8b6ece4b3e757e11a906a81ece292437713abarmvixluint16_t Simulator::PolynomialMult(uint8_t op1, uint8_t op2) {
11060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint16_t result = 0;
11070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint16_t extended_op2 = op2;
11080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < 8; ++i) {
11090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((op1 >> i) & 1) {
11100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = result ^ (extended_op2 << i);
11110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
11120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return result;
11140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::pmul(VectorFormat vform,
11180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
11190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
11200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
11210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
11220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i,
11240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                PolynomialMult(src1.Uint(vform, i), src2.Uint(vform, i)));
11250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
11270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::pmull(VectorFormat vform,
11310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
11320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
11330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
11340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_src = VectorFormatHalfWidth(vform);
11350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
11360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, i),
11380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         src2.Uint(vform_src, i)));
11390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
11410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::pmull2(VectorFormat vform,
11450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
11460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
11470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
11480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_src = VectorFormatHalfWidthDoubleLanes(vform);
11490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
11500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform);
11510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < lane_count; i++) {
11520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, lane_count + i),
11530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         src2.Uint(vform_src, lane_count + i)));
11540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
11560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sub(VectorFormat vform,
11600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
11610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
11620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
11630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
11640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for unsigned saturation.
11660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (src2.Uint(vform, i) > src1.Uint(vform, i)) {
11670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUnsignedSat(i, false);
11680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
11690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for signed saturation.
11710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sa = src1.IntLeftJustified(vform, i);
11720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sb = src2.IntLeftJustified(vform, i);
11730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sr = sa - sb;
11740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If the signs of the operands are different, and the sign of the first
11750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // operand doesn't match the result, there was an overflow.
11760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (((sa >= 0) != (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
11770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(i, sr < 0);
11780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
11790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, src1.Int(vform, i) - src2.Int(vform, i));
11810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
11830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::and_(VectorFormat vform,
11870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
11880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
11890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
11900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
11910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) & src2.Uint(vform, i));
11930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
11940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
11950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11980cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::orr(VectorFormat vform,
11990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) | src2.Uint(vform, i));
12050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12100cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::orn(VectorFormat vform,
12110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) | ~src2.Uint(vform, i));
12170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::eor(VectorFormat vform,
12230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) ^ src2.Uint(vform, i));
12290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::bic(VectorFormat vform,
12350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src1.Uint(vform, i) & ~src2.Uint(vform, i));
12410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::bic(VectorFormat vform,
12470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
12490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              uint64_t imm) {
12500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
12510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
12520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
12530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = src.Uint(vform, i) & ~imm;
12540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
12570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
12580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::bif(VectorFormat vform,
12640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand1 = dst.Uint(vform, i);
12700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand2 = ~src2.Uint(vform, i);
12710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand3 = src1.Uint(vform, i);
12720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
12730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result);
12740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::bit(VectorFormat vform,
12800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
12840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand1 = dst.Uint(vform, i);
12860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand2 = src2.Uint(vform, i);
12870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand3 = src1.Uint(vform, i);
12880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
12890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result);
12900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
12910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
12920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::bsl(VectorFormat vform,
12960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
12970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
12980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {
12990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
13000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand1 = src2.Uint(vform, i);
13020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand2 = dst.Uint(vform, i);
13030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t operand3 = src1.Uint(vform, i);
13040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
13050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result);
13060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
13070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sminmax(VectorFormat vform,
13120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
13130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
13140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
13150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  bool max) {
13160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
13170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src1_val = src1.Int(vform, i);
13190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src2_val = src2.Int(vform, i);
13200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t dst_val;
13210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
13220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
13230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
13240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
13250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
13260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, dst_val);
13270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
13280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smax(VectorFormat vform,
13330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
13340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
13350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
13360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sminmax(vform, dst, src1, src2, true);
13370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smin(VectorFormat vform,
13410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
13420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
13430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
13440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sminmax(vform, dst, src1, src2, false);
13450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sminmaxp(VectorFormat vform,
13490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
13500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int dst_index,
13510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
13520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   bool max) {
13530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
13540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src1_val = src.Int(vform, i);
13550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src2_val = src.Int(vform, i + 1);
13560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t dst_val;
13570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
13580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
13590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
13600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
13610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
13620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, dst_index + (i >> 1), dst_val);
13630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
13640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smaxp(VectorFormat vform,
13690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
13700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
13710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
13720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
13730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxp(vform, dst, 0, src1, true);
13740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
13750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sminp(VectorFormat vform,
13800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
13810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
13820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
13830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
13840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxp(vform, dst, 0, src1, false);
13850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
13860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addp(VectorFormat vform,
13910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
13920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
13930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vform == kFormatD);
13940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t dst_val = src.Int(kFormat2D, 0) + src.Int(kFormat2D, 1);
13960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
13970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetInt(vform, 0, dst_val);
13980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
13990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14020cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addv(VectorFormat vform,
14030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
14040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
14050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_dst
14060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
14070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t dst_val = 0;
14100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst_val += src.Int(vform, i);
14120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
14130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform_dst);
14150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetInt(vform_dst, 0, dst_val);
14160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddlv(VectorFormat vform,
14210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
14220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
14230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_dst
14240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
14250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t dst_val = 0;
14270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst_val += src.Int(vform, i);
14290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
14300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform_dst);
14320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetInt(vform_dst, 0, dst_val);
14330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddlv(VectorFormat vform,
14380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
14390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
14400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_dst
14410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
14420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t dst_val = 0;
14440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst_val += src.Uint(vform, i);
14460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
14470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform_dst);
14490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetUint(vform_dst, 0, dst_val);
14500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sminmaxv(VectorFormat vform,
14550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
14560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
14570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   bool max) {
14580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
14590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t dst_val = max ? INT64_MIN : INT64_MAX;
14600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, 0);
14620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src_val = src.Int(vform, i);
14630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
14640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src_val > dst_val) ? src_val : dst_val;
14650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
14660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src_val < dst_val) ? src_val : dst_val;
14670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
14680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
14690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetInt(vform, 0, dst_val);
14700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smaxv(VectorFormat vform,
14750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
14760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
14770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxv(vform, dst, src, true);
14780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14820cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sminv(VectorFormat vform,
14830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
14840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
14850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sminmaxv(vform, dst, src, false);
14860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
14870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uminmax(VectorFormat vform,
14910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
14920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
14930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
14940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  bool max) {
14950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
14960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src1_val = src1.Uint(vform, i);
14980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src2_val = src2.Uint(vform, i);
14990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t dst_val;
15000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
15010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
15020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
15030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
15040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
15050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, dst_val);
15060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
15070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umax(VectorFormat vform,
15120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
15130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
15140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
15150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return uminmax(vform, dst, src1, src2, true);
15160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umin(VectorFormat vform,
15200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
15210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
15220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
15230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return uminmax(vform, dst, src1, src2, false);
15240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uminmaxp(VectorFormat vform,
15280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
15290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int dst_index,
15300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
15310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   bool max) {
15320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
15330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src1_val = src.Uint(vform, i);
15340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src2_val = src.Uint(vform, i + 1);
15350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t dst_val;
15360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
15370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
15380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
15390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
15400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
15410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, dst_index + (i >> 1), dst_val);
15420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
15430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umaxp(VectorFormat vform,
15480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
15490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
15500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
15510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
15520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxp(vform, dst, 0, src1, true);
15530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
15540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uminp(VectorFormat vform,
15590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
15600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
15610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
15620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
15630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxp(vform, dst, 0, src1, false);
15640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
15650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uminmaxv(VectorFormat vform,
15700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
15710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
15720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   bool max) {
15730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
15740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t dst_val = max ? 0 : UINT64_MAX;
15750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
15760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, 0);
15770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src_val = src.Uint(vform, i);
15780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (max == true) {
15790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src_val > dst_val) ? src_val : dst_val;
15800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
15810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst_val = (src_val < dst_val) ? src_val : dst_val;
15820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
15830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
15840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetUint(vform, 0, dst_val);
15850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umaxv(VectorFormat vform,
15900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
15910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
15920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxv(vform, dst, src, true);
15930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
15940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uminv(VectorFormat vform,
15980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
15990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
16000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uminmaxv(vform, dst, src, false);
16010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
16020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::shl(VectorFormat vform,
16060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
16070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
16080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int shift) {
16090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
16100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
16110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
16120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return ushl(vform, dst, src, shiftreg);
16130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sshll(VectorFormat vform,
16170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
16180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
16190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
16200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
16210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
16220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister extendedreg = sxtl(vform, temp2, src);
16240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshl(vform, dst, extendedreg, shiftreg);
16250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sshll2(VectorFormat vform,
16290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
16300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
16310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
16320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
16330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
16340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister extendedreg = sxtl2(vform, temp2, src);
16360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshl(vform, dst, extendedreg, shiftreg);
16370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::shll(VectorFormat vform,
16410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
16420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
16430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int shift = LaneSizeInBitsFromFormat(vform) / 2;
16440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshll(vform, dst, src, shift);
16450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::shll2(VectorFormat vform,
16490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
16500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
16510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int shift = LaneSizeInBitsFromFormat(vform) / 2;
16520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshll2(vform, dst, src, shift);
16530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ushll(VectorFormat vform,
16570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
16580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
16590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
16600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
16610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
16620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister extendedreg = uxtl(vform, temp2, src);
16640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return ushl(vform, dst, extendedreg, shiftreg);
16650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ushll2(VectorFormat vform,
16690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
16700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
16710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
16720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
16730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
16740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister extendedreg = uxtl2(vform, temp2, src);
16760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return ushl(vform, dst, extendedreg, shiftreg);
16770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sli(VectorFormat vform,
16810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
16820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
16830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int shift) {
16840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
16850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
16860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
16870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src_lane = src.Uint(vform, i);
16880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t dst_lane = dst.Uint(vform, i);
16890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t shifted = src_lane << shift;
16900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t mask = MaxUintFromFormat(vform) << shift;
16910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
16920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
16930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
16940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshl(VectorFormat vform,
16980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
16990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
17000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
17010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
17020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshl(vform, dst, src, shiftreg).SignedSaturate(vform);
17050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqshl(VectorFormat vform,
17090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
17100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
17110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
17120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
17130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return ushl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
17160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshlu(VectorFormat vform,
17200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
17210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
17220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
17230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
17240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
17270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sri(VectorFormat vform,
17310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
17320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
17330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int shift) {
17340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
17350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
17360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift > 0) &&
17370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (shift <= static_cast<int>(LaneSizeInBitsFromFormat(vform))));
17380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
17390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src_lane = src.Uint(vform, i);
17400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t dst_lane = dst.Uint(vform, i);
17410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t shifted;
17420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t mask;
17430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (shift == 64) {
17440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shifted = 0;
17450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mask = 0;
17460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
17470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shifted = src_lane >> shift;
17480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mask = MaxUintFromFormat(vform) >> shift;
17490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
17500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
17510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
17520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
17530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ushr(VectorFormat vform,
17570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
17580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src,
17590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int shift) {
17600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
17610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
17630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return ushl(vform, dst, src, shiftreg);
17640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sshr(VectorFormat vform,
17680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
17690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src,
17700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int shift) {
17710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift >= 0);
17720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
17740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sshl(vform, dst, src, shiftreg);
17750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ssra(VectorFormat vform,
17790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
17800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src,
17810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int shift) {
17820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_reg = sshr(vform, temp, src, shift);
17840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, shifted_reg);
17850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usra(VectorFormat vform,
17890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
17900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src,
17910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int shift) {
17920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
17930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_reg = ushr(vform, temp, src, shift);
17940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, shifted_reg);
17950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17980cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::srsra(VectorFormat vform,
17990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
18000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
18010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
18020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
18030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_reg = sshr(vform, temp, src, shift).Round(vform);
18040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, shifted_reg);
18050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ursra(VectorFormat vform,
18090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
18100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
18110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
18120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
18130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_reg = ushr(vform, temp, src, shift).Round(vform);
18140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, shifted_reg);
18150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::cls(VectorFormat vform,
18190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
18200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
18210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
18220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
18230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
18240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
18250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = CountLeadingSignBits(src.Int(vform, i), laneSizeInBits);
18260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
18290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
18300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
18310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
18330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::clz(VectorFormat vform,
18370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
18380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
18390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
18400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
18410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
18420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
18430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = CountLeadingZeros(src.Uint(vform, i), laneSizeInBits);
18440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
18470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
18480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
18490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
18510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::cnt(VectorFormat vform,
18550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
18560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
18570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
18580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
18590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
18600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
18610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t value = src.Uint(vform, i);
18620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = 0;
18630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int j = 0; j < laneSizeInBits; j++) {
18640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result[i] += (value & 1);
18650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      value >>= 1;
18660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
18670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
18700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
18710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
18720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
18730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
18740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sshl(VectorFormat vform,
18780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
18790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
18800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
18810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
18820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
18830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int8_t shift_val = src2.Int(vform, i);
18840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t lj_src_val = src1.IntLeftJustified(vform, i);
18850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Set signed saturation state.
18870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((shift_val > CountLeadingSignBits(lj_src_val)) &&
18880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        (lj_src_val != 0)) {
18890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(i, lj_src_val >= 0);
18900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
18910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Set unsigned saturation state.
18930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (lj_src_val < 0) {
18940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUnsignedSat(i, false);
18950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if ((shift_val > CountLeadingZeros(lj_src_val)) &&
18960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl               (lj_src_val != 0)) {
18970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUnsignedSat(i, true);
18980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
18990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t src_val = src1.Int(vform, i);
19010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (shift_val > 63) {
19020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, 0);
19030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (shift_val < -63) {
19040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetRounding(i, src_val < 0);
19050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, (src_val < 0) ? -1 : 0);
19060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
19070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (shift_val < 0) {
19080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        // Set rounding state. Rounding only needed on right shifts.
19090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        if (((src_val >> (-shift_val - 1)) & 1) == 1) {
19100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          dst.SetRounding(i, true);
19110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        }
19120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        src_val >>= -shift_val;
19130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
19140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        src_val <<= shift_val;
19150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
19160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, src_val);
19170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
19200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ushl(VectorFormat vform,
19240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
19250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
19260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
19270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
19280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
19290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int8_t shift_val = src2.Int(vform, i);
19300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t lj_src_val = src1.UintLeftJustified(vform, i);
19310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Set saturation state.
19330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((shift_val > CountLeadingZeros(lj_src_val)) && (lj_src_val != 0)) {
19340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUnsignedSat(i, true);
19350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t src_val = src1.Uint(vform, i);
19380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((shift_val > 63) || (shift_val < -64)) {
19390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, 0);
19400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
19410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (shift_val < 0) {
19420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        // Set rounding state. Rounding only needed on right shifts.
19430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        if (((src_val >> (-shift_val - 1)) & 1) == 1) {
19440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          dst.SetRounding(i, true);
19450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        }
19460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        if (shift_val == -64) {
19480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          src_val = 0;
19490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        } else {
19500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          src_val >>= -shift_val;
19510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        }
19520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
19530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        src_val <<= shift_val;
19540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
19550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, src_val);
19560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
19590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::neg(VectorFormat vform,
19630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
19640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
19650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
19660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
19670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for signed saturation.
19680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sa = src.Int(vform, i);
19690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sa == MinIntFromFormat(vform)) {
19700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(i, true);
19710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, -sa);
19730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
19750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::suqadd(VectorFormat vform,
19790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
19800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
19810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
19820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
19830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t  sa = dst.IntLeftJustified(vform, i);
19840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t ub = src.UintLeftJustified(vform, i);
19850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t  sr = sa + ub;
19860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sr < sa) {  // Test for signed positive saturation.
19880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, MaxIntFromFormat(vform));
19890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
19900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, dst.Int(vform, i) + src.Int(vform, i));
19910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
19940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usqadd(VectorFormat vform,
19980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
19990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
20000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
20010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t  ua = dst.UintLeftJustified(vform, i);
20030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t   sb = src.IntLeftJustified(vform, i);
20040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t  ur = ua + sb;
20050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((sb > 0) && (ur <= ua)) {
20070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, MaxUintFromFormat(vform));  // Positive saturation.
20080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if ((sb < 0) && (ur >= ua)) {
20090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, 0);                         // Negative saturation.
20100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
20110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, dst.Uint(vform, i) + src.Int(vform, i));
20120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
20130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
20140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
20150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::abs(VectorFormat vform,
20190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
20200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
20210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
20220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for signed saturation.
20240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t sa = src.Int(vform, i);
20250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sa == MinIntFromFormat(vform)) {
20260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(i, true);
20270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
20280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sa < 0) {
20290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, -sa);
20300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
20310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, sa);
20320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
20330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
20340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
20350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20380cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::extractnarrow(VectorFormat dstform,
20390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        LogicVRegister dst,
20400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        bool dstIsSigned,
20410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const LogicVRegister& src,
20420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        bool srcIsSigned) {
20430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool upperhalf = false;
20440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat srcform = kFormatUndefined;
20450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t  ssrc[8];
20460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t usrc[8];
20470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (dstform) {
20490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat8B : upperhalf = false; srcform = kFormat8H; break;
20500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat16B: upperhalf = true;  srcform = kFormat8H; break;
20510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat4H : upperhalf = false; srcform = kFormat4S; break;
20520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat8H : upperhalf = true;  srcform = kFormat4S; break;
20530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat2S : upperhalf = false; srcform = kFormat2D; break;
20540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormat4S : upperhalf = true;  srcform = kFormat2D; break;
20550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormatB  : upperhalf = false; srcform = kFormatH;  break;
20560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormatH  : upperhalf = false; srcform = kFormatS;  break;
20570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kFormatS  : upperhalf = false; srcform = kFormatD;  break;
20580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:VIXL_UNIMPLEMENTED();
20590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
20600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
20620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    ssrc[i] = src.Int(srcform, i);
20630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    usrc[i] = src.Uint(srcform, i);
20640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
20650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int offset;
20670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (upperhalf) {
20680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset = LaneCountFromFormat(dstform) / 2;
20690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
20700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset = 0;
20710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.ClearForWrite(dstform);
20720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
20730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
20750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for signed saturation
20760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (ssrc[i] > MaxIntFromFormat(dstform)) {
20770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(offset + i, true);
20780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (ssrc[i] < MinIntFromFormat(dstform)) {
20790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetSignedSat(offset + i, false);
20800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
20810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Test for unsigned saturation
20830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (srcIsSigned) {
20840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (ssrc[i] > static_cast<int64_t>(MaxUintFromFormat(dstform))) {
20850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetUnsignedSat(offset + i, true);
20860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else if (ssrc[i] < 0) {
20870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetUnsignedSat(offset + i, false);
20880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
20890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
20900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (usrc[i] > MaxUintFromFormat(dstform)) {
20910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetUnsignedSat(offset + i, true);
20920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
20930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
20940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t result;
20960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (srcIsSigned) {
20970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = ssrc[i] & MaxUintFromFormat(dstform);
20980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
20990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = usrc[i] & MaxUintFromFormat(dstform);
21000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
21010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (dstIsSigned) {
21030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(dstform, offset + i, result);
21040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
21050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(dstform, offset + i, result);
21060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
21070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
21080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
21090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::xtn(VectorFormat vform,
21130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
21140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {
21150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vform, dst, true, src, true);
21160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqxtn(VectorFormat vform,
21200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
21210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
21220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vform, dst, true, src, true).SignedSaturate(vform);
21230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21260cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqxtun(VectorFormat vform,
21270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
21280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
21290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vform, dst, false, src, true).UnsignedSaturate(vform);
21300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqxtn(VectorFormat vform,
21340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
21350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
21360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vform, dst, false, src, false).UnsignedSaturate(vform);
21370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::absdiff(VectorFormat vform,
21410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
21420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
21430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
21440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  bool issigned) {
21450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
21460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
21470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (issigned) {
21480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      int64_t sr = src1.Int(vform, i) - src2.Int(vform, i);
21490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sr = sr > 0 ? sr : -sr;
21500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, sr);
21510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
21520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      int64_t sr = src1.Uint(vform, i) - src2.Uint(vform, i);
21530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sr = sr > 0 ? sr : -sr;
21540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, sr);
21550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
21560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
21570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
21580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saba(VectorFormat vform,
21620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
21630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
21640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
21650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
21660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
21670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, temp, src1, src2, true);
21680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, dst, temp);
21690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
21700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaba(VectorFormat vform,
21740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
21750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
21760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
21770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
21780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
21790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, temp, src1, src2, false);
21800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, dst, temp);
21810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
21820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::not_(VectorFormat vform,
21860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
21870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
21880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
21890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
21900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, ~src.Uint(vform, i));
21910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
21920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
21930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rbit(VectorFormat vform,
21970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
21980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
21990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
22000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
22010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
22020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t reversed_value;
22030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value;
22040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i++) {
22050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    value = src.Uint(vform, i);
22060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    reversed_value = 0;
22070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int j = 0; j < laneSizeInBits; j++) {
22080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      reversed_value = (reversed_value << 1) | (value & 1);
22090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      value >>= 1;
22100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
22110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = reversed_value;
22120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
22150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
22160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
22170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
22190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rev(VectorFormat vform,
22230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
22240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
22250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int revSize) {
22260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
22270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
22280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSize = LaneSizeInBytesFromFormat(vform);
22290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lanesPerLoop =  revSize / laneSize;
22300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; i += lanesPerLoop) {
22310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int j = 0; j < lanesPerLoop; j++) {
22320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result[i + lanesPerLoop - 1 - j] = src.Uint(vform, i + j);
22330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
22340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
22360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
22370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
22380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
22400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rev16(VectorFormat vform,
22440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
22450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
22460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rev(vform, dst, src, 2);
22470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22500cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rev32(VectorFormat vform,
22510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
22520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
22530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rev(vform, dst, src, 4);
22540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rev64(VectorFormat vform,
22580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
22590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
22600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rev(vform, dst, src, 8);
22610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22640cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addlp(VectorFormat vform,
22650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
22660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
22670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 bool is_signed,
22680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 bool do_accumulate) {
22690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatHalfWidthDoubleLanes(vform);
22700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t  sr[16];
22720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t ur[16];
22730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
22750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
22760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (is_signed) {
22770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sr[i] = src.Int(vformsrc, 2 * i) + src.Int(vformsrc, 2 * i + 1);
22780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
22790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      ur[i] = src.Uint(vformsrc, 2 * i) + src.Uint(vformsrc, 2 * i + 1);
22800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
22810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
22840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
22850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (do_accumulate) {
22860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (is_signed) {
22870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetInt(vform, i, dst.Int(vform, i) + sr[i]);
22880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
22890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetUint(vform, i, dst.Uint(vform, i) + ur[i]);
22900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
22910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
22920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (is_signed) {
22930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetInt(vform, i, sr[i]);
22940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
22950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        dst.SetUint(vform, i, ur[i]);
22960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
22970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
22980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddlp(VectorFormat vform,
23050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
23060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
23070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addlp(vform, dst, src, true, false);
23080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddlp(VectorFormat vform,
23120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
23130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
23140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addlp(vform, dst, src, false, false);
23150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sadalp(VectorFormat vform,
23190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
23200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
23210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addlp(vform, dst, src, true, true);
23220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uadalp(VectorFormat vform,
23260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
23270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
23280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addlp(vform, dst, src, false, true);
23290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ext(VectorFormat vform,
23330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
23340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,
23350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2,
23360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int index) {
23370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint8_t result[16];
23380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
23390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount - index; ++i) {
23400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = src1.Uint(vform, i + index);
23410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < index; ++i) {
23430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[laneCount - index + i] = src2.Uint(vform, i);
23440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
23460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
23470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
23480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::dup_element(VectorFormat vform,
23540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      LogicVRegister dst,
23550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const LogicVRegister& src,
23560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      int src_index) {
23570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
23580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value = src.Uint(vform, src_index);
23590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
23600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
23610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, value);
23620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::dup_immediate(VectorFormat vform,
23680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        LogicVRegister dst,
23690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        uint64_t imm) {
23700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
23710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value = imm & MaxUintFromFormat(vform);
23720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
23730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
23740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, value);
23750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ins_element(VectorFormat vform,
23810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      LogicVRegister dst,
23820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      int dst_index,
23830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const LogicVRegister& src,
23840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      int src_index) {
23850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetUint(vform, dst_index, src.Uint(vform, src_index));
23860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ins_immediate(VectorFormat vform,
23910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        LogicVRegister dst,
23920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        int dst_index,
23930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        uint64_t imm) {
23940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value = imm & MaxUintFromFormat(vform);
23950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetUint(vform, dst_index, value);
23960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
23970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::movi(VectorFormat vform,
24010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
24020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               uint64_t imm) {
24030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
24040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
24060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, imm);
24070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::mvni(VectorFormat vform,
24130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
24140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               uint64_t imm) {
24150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
24160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
24180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, ~imm);
24190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::orr(VectorFormat vform,
24250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
24260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src,
24270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              uint64_t imm) {
24280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
24290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
24300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
24310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i] = src.Uint(vform, i) | imm;
24320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
24350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
24360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24410cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uxtl(VectorFormat vform,
24420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
24430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
24440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
24450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
24480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src.Uint(vform_half, i));
24490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sxtl(VectorFormat vform,
24550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
24560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
24570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
24580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
24610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, src.Int(vform_half, i));
24620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uxtl2(VectorFormat vform,
24680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
24690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
24700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
24710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform);
24720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < lane_count; i++) {
24750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, src.Uint(vform_half, lane_count + i));
24760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sxtl2(VectorFormat vform,
24820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
24830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
24840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
24850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform);
24860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
24880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < lane_count; i++) {
24890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, src.Int(vform_half, lane_count + i));
24900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
24910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
24920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::shrn(VectorFormat vform,
24960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
24970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src,
24980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int shift) {
24990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
25000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_src = VectorFormatDoubleWidth(vform);
25010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vform_dst = vform;
25020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = ushr(vform_src, temp, src, shift);
25030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vform_dst, dst, false, shifted_src, false);
25040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::shrn2(VectorFormat vform,
25080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
25090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
25100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
25110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
25120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
25130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
25140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift);
25150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
25160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rshrn(VectorFormat vform,
25200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
25210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
25220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int shift) {
25230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
25240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
25250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
25260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
25270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
25280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rshrn2(VectorFormat vform,
25320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
25330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
25340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
25350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
25360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
25370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
25380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
25390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
25400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbl(VectorFormat vform,
25440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
25450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
25460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
25470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    movi(vform, dst, 0);
25480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return tbx(vform, dst, tab, ind);
25490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbl(VectorFormat vform,
25530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
25540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
25550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
25560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
25570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    movi(vform, dst, 0);
25580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return tbx(vform, dst, tab, tab2, ind);
25590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbl(VectorFormat vform,
25630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
25640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
25650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
25660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab3,
25670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
25680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    movi(vform, dst, 0);
25690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return tbx(vform, dst, tab, tab2, tab3, ind);
25700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbl(VectorFormat vform,
25740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
25750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
25760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
25770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab3,
25780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab4,
25790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
25800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    movi(vform, dst, 0);
25810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return tbx(vform, dst, tab, tab2, tab3, tab4, ind);
25820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbx(VectorFormat vform,
25860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
25870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
25880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
25890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
25900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
25915ee436a3a51863de7b5dc9326cf02895248050c2armvixl    uint64_t j = ind.Uint(vform, i);
25920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (j >> 4) {
25930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
25940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
25950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
25960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
25970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
26020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
26030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
26040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
26050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
26060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
26075ee436a3a51863de7b5dc9326cf02895248050c2armvixl    uint64_t j = ind.Uint(vform, i);
26080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (j >> 4) {
26090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
26100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
26110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
26120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
26130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
26140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
26190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
26200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
26210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab3,
26220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
26230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
26240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
26255ee436a3a51863de7b5dc9326cf02895248050c2armvixl    uint64_t j = ind.Uint(vform, i);
26260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (j >> 4) {
26270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
26280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
26290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
26300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
26310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
26320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
26330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,
26380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab,
26390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab2,
26400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab3,
26410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& tab4,
26420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& ind) {
26430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
26440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
26455ee436a3a51863de7b5dc9326cf02895248050c2armvixl    uint64_t j = ind.Uint(vform, i);
26460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (j >> 4) {
26470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
26480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
26490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
26500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case 3: dst.SetUint(vform, i, tab4.Uint(kFormat16B, j & 15)); break;
26510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
26520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
26530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
26540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqshrn(VectorFormat vform,
26580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
26590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
26600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
26610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return shrn(vform, dst, src, shift).UnsignedSaturate(vform);
26620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqshrn2(VectorFormat vform,
26660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
26670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src,
26680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int shift) {
26690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return shrn2(vform, dst, src, shift).UnsignedSaturate(vform);
26700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqrshrn(VectorFormat vform,
26740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
26750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src,
26760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int shift) {
26770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rshrn(vform, dst, src, shift).UnsignedSaturate(vform);
26780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uqrshrn2(VectorFormat vform,
26820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
26830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
26840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int shift) {
26850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return rshrn2(vform, dst, src, shift).UnsignedSaturate(vform);
26860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshrn(VectorFormat vform,
26900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
26910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
26920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 int shift) {
26930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
26940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
26950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
26960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
26970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtn(vformdst, dst, shifted_src);
26980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshrn2(VectorFormat vform,
27020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
27030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src,
27040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int shift) {
27050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
27090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtn(vformdst, dst, shifted_src);
27100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27130cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrshrn(VectorFormat vform,
27140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
27150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src,
27160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int shift) {
27170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
27190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtn(vformdst, dst, shifted_src);
27220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrshrn2(VectorFormat vform,
27260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
27270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
27280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int shift) {
27290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtn(vformdst, dst, shifted_src);
27340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshrun(VectorFormat vform,
27380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
27390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src,
27400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  int shift) {
27410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
27430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
27450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtun(vformdst, dst, shifted_src);
27460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqshrun2(VectorFormat vform,
27500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
27510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
27520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int shift) {
27530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
27570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtun(vformdst, dst, shifted_src);
27580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrshrun(VectorFormat vform,
27620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
27630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
27640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int shift) {
27650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
27670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtun(vformdst, dst, shifted_src);
27700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrshrun2(VectorFormat vform,
27740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    LogicVRegister dst,
27750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const LogicVRegister& src,
27760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    int shift) {
27770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
27780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VectorFormat vformdst = vform;
27800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqxtun(vformdst, dst, shifted_src);
27820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddl(VectorFormat vform,
27860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
27870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
27880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
27890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
27900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
27910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
27920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, temp1, temp2);
27930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
27940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddl2(VectorFormat vform,
27980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
27990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
28000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
28010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
28020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
28030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
28040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, temp1, temp2);
28050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddw(VectorFormat vform,
28100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
28110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
28120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
28130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
28140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp, src2);
28150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, src1, temp);
28160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uaddw2(VectorFormat vform,
28210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
28220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
28230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
28240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
28250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp, src2);
28260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, src1, temp);
28270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddl(VectorFormat vform,
28320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
28330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
28340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
28350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
28360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
28370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
28380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, temp1, temp2);
28390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddl2(VectorFormat vform,
28440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
28450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
28460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
28470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
28480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
28490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
28500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, temp1, temp2);
28510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddw(VectorFormat vform,
28560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
28570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
28580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
28590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
28600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp, src2);
28610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, src1, temp);
28620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::saddw2(VectorFormat vform,
28670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
28680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
28690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
28700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
28710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp, src2);
28720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(vform, dst, src1, temp);
28730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usubl(VectorFormat vform,
28780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
28790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
28800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
28810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
28820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
28830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
28840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, temp1, temp2);
28850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usubl2(VectorFormat vform,
28900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
28910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
28920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
28930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
28940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
28950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
28960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, temp1, temp2);
28970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
28980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usubw(VectorFormat vform,
29020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
29030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
29040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
29050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
29060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp, src2);
29070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, src1, temp);
29080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::usubw2(VectorFormat vform,
29130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
29140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
29150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
29160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
29170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp, src2);
29180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, src1, temp);
29190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ssubl(VectorFormat vform,
29240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
29250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
29260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
29270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
29280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
29290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
29300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, temp1, temp2);
29310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ssubl2(VectorFormat vform,
29360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
29370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
29380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
29390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
29400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
29410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
29420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, temp1, temp2);
29430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ssubw(VectorFormat vform,
29480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
29490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
29500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
29510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
29520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp, src2);
29530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, src1, temp);
29540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ssubw2(VectorFormat vform,
29590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
29600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
29610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
29620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
29630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp, src2);
29640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(vform, dst, src1, temp);
29650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uabal(VectorFormat vform,
29700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
29710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
29720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
29730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
29740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
29750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
29760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uaba(vform, dst, temp1, temp2);
29770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uabal2(VectorFormat vform,
29820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
29830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
29840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
29850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
29860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
29870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
29880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uaba(vform, dst, temp1, temp2);
29890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
29900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sabal(VectorFormat vform,
29940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
29950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
29960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
29970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
29980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
29990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
30000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  saba(vform, dst, temp1, temp2);
30010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sabal2(VectorFormat vform,
30060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
30070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
30080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
30090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
30110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
30120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  saba(vform, dst, temp1, temp2);
30130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uabdl(VectorFormat vform,
30180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
30190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
30200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
30210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
30230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
30240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, dst, temp1, temp2, false);
30250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uabdl2(VectorFormat vform,
30300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
30310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
30320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
30330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
30350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
30360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, dst, temp1, temp2, false);
30370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30410cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sabdl(VectorFormat vform,
30420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
30430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
30440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
30450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
30470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
30480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, dst, temp1, temp2, true);
30490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sabdl2(VectorFormat vform,
30540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
30550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
30560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
30570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
30590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
30600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  absdiff(vform, dst, temp1, temp2, true);
30610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umull(VectorFormat vform,
30660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
30670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
30680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
30690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
30710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
30720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, dst, temp1, temp2);
30730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umull2(VectorFormat vform,
30780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
30790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
30800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
30810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
30830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
30840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, dst, temp1, temp2);
30850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smull(VectorFormat vform,
30900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
30910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
30920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
30930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
30940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
30950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
30960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, dst, temp1, temp2);
30970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
30980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smull2(VectorFormat vform,
31020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
31030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
31040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
31050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
31070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
31080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mul(vform, dst, temp1, temp2);
31090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31130cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlsl(VectorFormat vform,
31140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
31150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
31160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
31170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
31190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
31200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mls(vform, dst, temp1, temp2);
31210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlsl2(VectorFormat vform,
31260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
31270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
31280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
31290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
31310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
31320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mls(vform, dst, temp1, temp2);
31330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlsl(VectorFormat vform,
31380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
31390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
31400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
31410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
31430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
31440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mls(vform, dst, temp1, temp2);
31450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlsl2(VectorFormat vform,
31500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
31510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
31520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
31530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
31550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
31560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mls(vform, dst, temp1, temp2);
31570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlal(VectorFormat vform,
31620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
31630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
31640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
31650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp1, src1);
31670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl(vform, temp2, src2);
31680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mla(vform, dst, temp1, temp2);
31690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::umlal2(VectorFormat vform,
31740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
31750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
31760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
31770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp1, src1);
31790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uxtl2(vform, temp2, src2);
31800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mla(vform, dst, temp1, temp2);
31810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlal(VectorFormat vform,
31860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
31870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
31880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
31890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
31900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp1, src1);
31910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl(vform, temp2, src2);
31920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mla(vform, dst, temp1, temp2);
31930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
31940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::smlal2(VectorFormat vform,
31980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
31990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
32000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
32010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
32020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp1, src1);
32030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sxtl2(vform, temp2, src2);
32040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  mla(vform, dst, temp1, temp2);
32050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
32060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlal(VectorFormat vform,
32100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = sqdmull(vform, temp, src1, src2);
32150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, product).SignedSaturate(vform);
32160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlal2(VectorFormat vform,
32200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = sqdmull2(vform, temp, src1, src2);
32250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, dst, product).SignedSaturate(vform);
32260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlsl(VectorFormat vform,
32300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = sqdmull(vform, temp, src1, src2);
32350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sub(vform, dst, dst, product).SignedSaturate(vform);
32360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
32400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = sqdmull2(vform, temp, src1, src2);
32450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sub(vform, dst, dst, product).SignedSaturate(vform);
32460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmull(VectorFormat vform,
32500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = smull(vform, temp, src1, src2);
32550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, product, product).SignedSaturate(vform);
32560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmull2(VectorFormat vform,
32600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
32610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
32620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
32630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
32640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = smull2(vform, temp, src1, src2);
32650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return add(vform, dst, product, product).SignedSaturate(vform);
32660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqrdmulh(VectorFormat vform,
32700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
32710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src1,
32720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src2,
32730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   bool round) {
32740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 2 * INT_32_MIN * INT_32_MIN causes int64_t to overflow.
32750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // To avoid this, we use (src1 * src2 + 1 << (esize - 2)) >> (esize - 1)
32760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // which is same as (2 * src1 * src2 + 1 << (esize - 1)) >> esize.
32770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int esize = LaneSizeInBitsFromFormat(vform);
32790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int round_const = round ? (1 << (esize - 2)) : 0;
32800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t product;
32810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
32830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
32840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    product = src1.Int(vform, i) * src2.Int(vform, i);
32850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    product += round_const;
32860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    product = product >> (esize - 1);
32870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (product > MaxIntFromFormat(vform)) {
32890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      product = MaxIntFromFormat(vform);
32900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (product < MinIntFromFormat(vform)) {
32910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      product = MinIntFromFormat(vform);
32920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
32930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetInt(vform, i, product);
32940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
32950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
32960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::sqdmulh(VectorFormat vform,
33000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
33010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
33020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
33030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sqrdmulh(vform, dst, src1, src2, false);
33040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addhn(VectorFormat vform,
33080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
33090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
33100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
33110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(VectorFormatDoubleWidth(vform), temp, src1, src2);
33130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::addhn2(VectorFormat vform,
33190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
33200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
33210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
33220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
33240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::raddhn(VectorFormat vform,
33300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
33310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
33320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
33330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(VectorFormatDoubleWidth(vform), temp, src1, src2);
33350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::raddhn2(VectorFormat vform,
33410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
33420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
33430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
33440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
33460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::subhn(VectorFormat vform,
33520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
33530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
33540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
33550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
33570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::subhn2(VectorFormat vform,
33630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
33640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
33650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
33660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
33680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rsubhn(VectorFormat vform,
33740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
33750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
33760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
33770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
33790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::rsubhn2(VectorFormat vform,
33850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
33860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
33870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
33880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
33890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
33900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
33920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::trn1(VectorFormat vform,
33960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
33970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
33980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
33990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
34000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
34010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int pairs = laneCount / 2;
34020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < pairs; ++i) {
34030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[2 * i]       = src1.Uint(vform, 2 * i);
34040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[(2 * i) + 1] = src2.Uint(vform, 2 * i);
34050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
34080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
34100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
34120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::trn2(VectorFormat vform,
34160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
34170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
34180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
34190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
34200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
34210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int pairs = laneCount / 2;
34220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < pairs; ++i) {
34230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[2 * i]       = src1.Uint(vform, (2 * i) + 1);
34240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[(2 * i) + 1] = src2.Uint(vform, (2 * i) + 1);
34250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
34280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
34300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
34320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::zip1(VectorFormat vform,
34360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
34370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
34380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
34390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
34400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
34410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int pairs = laneCount / 2;
34420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < pairs; ++i) {
34430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[2 * i]       = src1.Uint(vform, i);
34440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[(2 * i) + 1] = src2.Uint(vform, i);
34450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
34480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
34500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
34520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::zip2(VectorFormat vform,
34560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
34570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
34580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
34590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[16];
34600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
34610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int pairs = laneCount / 2;
34620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < pairs; ++i) {
34630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[2 * i]       = src1.Uint(vform, pairs + i);
34640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[(2 * i) + 1] = src2.Uint(vform, pairs + i);
34650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
34680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[i]);
34700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
34720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34750cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uzp1(VectorFormat vform,
34760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
34770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
34780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
34790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[32];
34800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
34810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i]             = src1.Uint(vform, i);
34830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[laneCount + i] = src2.Uint(vform, i);
34840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
34870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
34880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[2 * i]);
34890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
34910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::uzp2(VectorFormat vform,
34950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
34960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
34970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
34980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t result[32];
34990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneCount = LaneCountFromFormat(vform);
35000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
35010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[i]             = src1.Uint(vform, i);
35020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    result[laneCount + i] = src2.Uint(vform, i);
35030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
35060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < laneCount; ++i) {
35070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result[ (2 * i) + 1]);
35080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
35100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35130cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
35140cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPAdd(T op1, T op2) {
35150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs(op1, op2);
35160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(result)) return result;
35170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
35190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // inf + -inf returns the default NaN.
35200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
35210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
35220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
35230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Other cases should be handled by standard arithmetic.
35240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return op1 + op2;
35250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35290cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
35300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPSub(T op1, T op2) {
35310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // NaNs should be handled elsewhere.
35320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
35330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
35350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // inf - inf returns the default NaN.
35360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
35370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
35380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
35390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Other cases should be handled by standard arithmetic.
35400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return op1 - op2;
35410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35450cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
35460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMul(T op1, T op2) {
35470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // NaNs should be handled elsewhere.
35480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
35490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
35510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // inf * 0.0 returns the default NaN.
35520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
35530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
35540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
35550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Other cases should be handled by standard arithmetic.
35560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return op1 * op2;
35570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35610cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate<typename T>
35620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMulx(T op1, T op2) {
35630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
35640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // inf * 0.0 returns +/-2.0.
35650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T two = 2.0;
35660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return copysign(1.0, op1) * copysign(1.0, op2) * two;
35670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FPMul(op1, op2);
35690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35720cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate<typename T>
35730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMulAdd(T a, T op1, T op2) {
35740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs3(a, op1, op2);
35750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T sign_a = copysign(1.0, a);
35770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
35780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool isinf_prod = std::isinf(op1) || std::isinf(op2);
35790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool operation_generates_nan =
35800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (std::isinf(op1) && (op2 == 0.0)) ||                     // inf * 0.0
35810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (std::isinf(op2) && (op1 == 0.0)) ||                     // 0.0 * inf
35820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (std::isinf(a) && isinf_prod && (sign_a != sign_prod));  // inf - inf
35830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(result)) {
35850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Generated NaNs override quiet NaNs propagated from a.
35860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (operation_generates_nan && IsQuietNaN(a)) {
35870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      FPProcessException();
35880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FPDefaultNaN<T>();
35890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
35900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return result;
35910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
35920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // If the operation would produce a NaN, return the default NaN.
35950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (operation_generates_nan) {
35960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
35970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
35980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
35990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Work around broken fma implementations for exact zero results: The sign of
36010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // exact 0.0 results is positive unless both a and op1 * op2 are negative.
36020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
36030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
36040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  result = FusedMultiplyAdd(op1, op2, a);
36070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!std::isnan(result));
36080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Work around broken fma implementations for rounded zero results: If a is
36100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
36110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((a == 0.0) && (result == 0.0)) {
36120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return copysign(0.0, sign_prod);
36130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return result;
36160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36190cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPDiv(T op1, T op2) {
36210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // NaNs should be handled elsewhere.
36220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
36230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
36250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // inf / inf and 0.0 / 0.0 return the default NaN.
36260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
36270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
36280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
36290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (op2 == 0.0) FPProcessException();
36300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Other cases should be handled by standard arithmetic.
36320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return op1 / op2;
36330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36370cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36380cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPSqrt(T op) {
36390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(op)) {
36400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPProcessNaN(op);
36410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (op < 0.0) {
36420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
36430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
36440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
36450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return sqrt(op);
36460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36500cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMax(T a, T b) {
36520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs(a, b);
36530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(result)) return result;
36540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((a == 0.0) && (b == 0.0) &&
36560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (copysign(1.0, a) != copysign(1.0, b))) {
36570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // a and b are zero, and the sign differs: return +0.0.
36580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0.0;
36590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
36600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return (a > b) ? a : b;
36610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36650cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMaxNM(T a, T b) {
36670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
36680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    a = kFP64NegativeInfinity;
36690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
36700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    b = kFP64NegativeInfinity;
36710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs(a, b);
36740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(result) ? result : FPMax(a, b);
36750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36780cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMin(T a, T b) {
36800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs(a, b);
36810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(result)) return result;
36820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((a == 0.0) && (b == 0.0) &&
36840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (copysign(1.0, a) != copysign(1.0, b))) {
36850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // a and b are zero, and the sign differs: return -0.0.
36860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return -0.0;
36870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
36880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return (a < b) ? a : b;
36890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36930cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
36940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPMinNM(T a, T b) {
36950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
36960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    a = kFP64PositiveInfinity;
36970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
36980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    b = kFP64PositiveInfinity;
36990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  T result = FPProcessNaNs(a, b);
37020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(result) ? result : FPMin(a, b);
37030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37060cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
37070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPRecipStepFused(T op1, T op2) {
37080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const T two = 2.0;
37090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((std::isinf(op1) && (op2 == 0.0))
37100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      || ((op1 == 0.0) && (std::isinf(op2)))) {
37110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return two;
37120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (std::isinf(op1) || std::isinf(op2)) {
37130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Return +inf if signs match, otherwise -inf.
37140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
37150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                          : kFP64NegativeInfinity;
37160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
37170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FusedMultiplyAdd(op1, op2, two);
37180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37220cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
37230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPRSqrtStepFused(T op1, T op2) {
37240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const T one_point_five = 1.5;
37250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const T two = 2.0;
37260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((std::isinf(op1) && (op2 == 0.0))
37280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      || ((op1 == 0.0) && (std::isinf(op2)))) {
37290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return one_point_five;
37300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (std::isinf(op1) || std::isinf(op2)) {
37310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Return +inf if signs match, otherwise -inf.
37320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
37330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                          : kFP64NegativeInfinity;
37340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
37350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // The multiply-add-halve operation must be fully fused, so avoid interim
37360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // rounding by checking which operand can be losslessly divided by two
37370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // before doing the multiply-add.
37380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (std::isnormal(op1 / two)) {
37390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FusedMultiplyAdd(op1 / two, op2, one_point_five);
37400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (std::isnormal(op2 / two)) {
37410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return FusedMultiplyAdd(op1, op2 / two, one_point_five);
37420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
37430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Neither operand is normal after halving: the result is dominated by
37440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // the addition term, so just return that.
37450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return one_point_five;
37460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
37470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37510cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::FPRoundInt(double value, FPRounding round_mode) {
37520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
37530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (value == kFP64NegativeInfinity)) {
37540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return value;
37550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (std::isnan(value)) {
37560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPProcessNaN(value);
37570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double int_result = std::floor(value);
37600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double error = value - int_result;
37610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (round_mode) {
37620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FPTieAway: {
37630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Take care of correctly handling the range ]-0.5, -0.0], which must
37640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // yield -0.0.
37650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if ((-0.5 < value) && (value < 0.0)) {
37660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result = -0.0;
37670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
37690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        // If the error is greater than 0.5, or is equal to 0.5 and the integer
37700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        // result is positive, round up.
37710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result++;
37720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
37730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
37740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
37750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FPTieEven: {
37760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Take care of correctly handling the range [-0.5, -0.0], which must
37770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // yield -0.0.
37780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if ((-0.5 <= value) && (value < 0.0)) {
37790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result = -0.0;
37800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // If the error is greater than 0.5, or is equal to 0.5 and the integer
37820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // result is odd, round up.
37830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else if ((error > 0.5) ||
37840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          ((error == 0.5) && (std::fmod(int_result, 2) != 0))) {
37850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result++;
37860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
37870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
37880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
37890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FPZero: {
37900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // If value>0 then we take floor(value)
37910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // otherwise, ceil(value).
37920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (value < 0) {
37930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         int_result = ceil(value);
37940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
37950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
37960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
37970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FPNegativeInfinity: {
37980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // We always use floor(value).
37990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
38000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
38010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case FPPositiveInfinity: {
38020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Take care of correctly handling the range ]-1.0, -0.0], which must
38030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // yield -0.0.
38040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if ((-1.0 < value) && (value < 0.0)) {
38050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result = -0.0;
38060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // If the error is non-zero, round up.
38080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else if (error > 0.0) {
38090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        int_result++;
38100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
38110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
38120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
38130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default: VIXL_UNIMPLEMENTED();
38140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return int_result;
38160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlint32_t Simulator::FPToInt32(double value, FPRounding rmode) {
38200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  value = FPRoundInt(value, rmode);
38210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value >= kWMaxInt) {
38220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kWMaxInt;
38230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (value < kWMinInt) {
38240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kWMinInt;
38250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(value) ? 0 : static_cast<int32_t>(value);
38270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlint64_t Simulator::FPToInt64(double value, FPRounding rmode) {
38310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  value = FPRoundInt(value, rmode);
38320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value >= kXMaxInt) {
38330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kXMaxInt;
38340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (value < kXMinInt) {
38350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kXMinInt;
38360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(value) ? 0 : static_cast<int64_t>(value);
38380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38410cc8b6ece4b3e757e11a906a81ece292437713abarmvixluint32_t Simulator::FPToUInt32(double value, FPRounding rmode) {
38420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  value = FPRoundInt(value, rmode);
38430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value >= kWMaxUInt) {
38440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kWMaxUInt;
38450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (value < 0.0) {
38460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0;
38470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(value) ? 0 : static_cast<uint32_t>(value);
38490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38520cc8b6ece4b3e757e11a906a81ece292437713abarmvixluint64_t Simulator::FPToUInt64(double value, FPRounding rmode) {
38530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  value = FPRoundInt(value, rmode);
38540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value >= kXMaxUInt) {
38550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return kXMaxUInt;
38560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (value < 0.0) {
38570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0;
38580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return std::isnan(value) ? 0 : static_cast<uint64_t>(value);
38600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                \
38640cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>                                            \
38650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::FN(VectorFormat vform,                 \
38660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             LogicVRegister dst,                 \
38670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const LogicVRegister& src1,         \
38680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const LogicVRegister& src2) {       \
38690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);                                      \
38700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {         \
38710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = src1.Float<T>(i);                                    \
38720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);                                    \
38730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result;                                                    \
38740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (PROCNAN) {                                               \
38750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = FPProcessNaNs(op1, op2);                          \
38760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (!std::isnan(result)) {                                      \
38770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        result = OP(op1, op2);                                   \
38780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }                                                          \
38790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {                                                     \
38800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = OP(op1, op2);                                     \
38810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }                                                            \
38820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, result);                                     \
38830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }                                                              \
38840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;                                                    \
38850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}                                                                \
38860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                                 \
38870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::FN(VectorFormat vform,                 \
38880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             LogicVRegister dst,                 \
38890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const LogicVRegister& src1,         \
38900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const LogicVRegister& src2) {       \
38910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {            \
38920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FN<float>(vform, dst, src1, src2);                           \
38930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {                                                       \
38940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);   \
38950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FN<double>(vform, dst, src1, src2);                          \
38960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }                                                              \
38970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;                                                    \
38980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)
39000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_NEON_FP_VECTOR_OP
39010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fnmul(VectorFormat vform,
39040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
39050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
39060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2) {
39070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
39080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LogicVRegister product = fmul(vform, temp, src1, src2);
39090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return fneg(vform, dst, product);
39100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39130cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
39140cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frecps(VectorFormat vform,
39150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
39160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
39170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
39180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
39190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
39200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = -src1.Float<T>(i);
39210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);
39220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result = FPProcessNaNs(op1, op2);
39230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, std::isnan(result) ? result : FPRecipStepFused(op1, op2));
39240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
39250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
39260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frecps(VectorFormat vform,
39300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
39310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src1,
39320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src2) {
39330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
39340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frecps<float>(vform, dst, src1, src2);
39350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
39360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
39370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frecps<double>(vform, dst, src1, src2);
39380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
39390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
39400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39430cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
39440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frsqrts(VectorFormat vform,
39450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
39460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
39470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
39480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
39490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
39500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = -src1.Float<T>(i);
39510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);
39520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result = FPProcessNaNs(op1, op2);
39530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, std::isnan(result) ? result : FPRSqrtStepFused(op1, op2));
39540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
39550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
39560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frsqrts(VectorFormat vform,
39600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
39610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
39620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2) {
39630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
39640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frsqrts<float>(vform, dst, src1, src2);
39650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
39660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
39670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frsqrts<double>(vform, dst, src1, src2);
39680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
39690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
39700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39730cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
39740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcmp(VectorFormat vform,
39750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
39760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
39770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2,
39780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               Condition cond) {
39790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
39800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
39810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool result = false;
39820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = src1.Float<T>(i);
39830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);
39840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T nan_result = FPProcessNaNs(op1, op2);
39850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (!std::isnan(nan_result)) {
39860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      switch (cond) {
39870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        case eq: result = (op1 == op2); break;
39880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        case ge: result = (op1 >= op2); break;
39890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        case gt: result = (op1 > op2) ; break;
39900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        case le: result = (op1 <= op2); break;
39910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        case lt: result = (op1 < op2) ; break;
39920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        default: VIXL_UNREACHABLE(); break;
39930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
39940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
39950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
39960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
39970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
39980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcmp(VectorFormat vform,
40020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
40030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
40040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2,
40050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               Condition cond) {
40060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<float>(vform, dst, src1, src2, cond);
40080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
40090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<double>(vform, dst, src1, src2, cond);
40110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcmp_zero(VectorFormat vform,
40170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    LogicVRegister dst,
40180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const LogicVRegister& src,
40190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    Condition cond) {
40200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
40210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister zero_reg = dup_immediate(vform, temp, float_to_rawbits(0.0));
40230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<float>(vform, dst, src, zero_reg, cond);
40240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
40250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister zero_reg = dup_immediate(vform, temp,
40270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                            double_to_rawbits(0.0));
40280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<double>(vform, dst, src, zero_reg, cond);
40290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fabscmp(VectorFormat vform,
40350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
40360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src1,
40370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src2,
40380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  Condition cond) {
40390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;
40400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister abs_src1 = fabs_<float>(vform, temp1, src1);
40420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister abs_src2 = fabs_<float>(vform, temp2, src2);
40430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<float>(vform, dst, abs_src1, abs_src2, cond);
40440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
40450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister abs_src1 = fabs_<double>(vform, temp1, src1);
40470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister abs_src2 = fabs_<double>(vform, temp2, src2);
40480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fcmp<double>(vform, dst, abs_src1, abs_src2, cond);
40490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40540cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
40550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmla(VectorFormat vform,
40560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
40570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
40580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
40590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
40600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
40610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = src1.Float<T>(i);
40620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);
40630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T acc = dst.Float<T>(i);
40640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result = FPMulAdd(acc, op1, op2);
40650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, result);
40660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmla(VectorFormat vform,
40720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
40730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
40740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
40750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmla<float>(vform, dst, src1, src2);
40770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
40780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmla<double>(vform, dst, src1, src2);
40800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40850cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
40860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmls(VectorFormat vform,
40870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
40880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
40890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
40900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
40910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
40920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op1 = -src1.Float<T>(i);
40930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op2 = src2.Float<T>(i);
40940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T acc = dst.Float<T>(i);
40950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result = FPMulAdd(acc, op1, op2);
40960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, result);
40970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
40990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41020cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmls(VectorFormat vform,
41030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
41040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
41050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
41060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmls<float>(vform, dst, src1, src2);
41080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmls<double>(vform, dst, src1, src2);
41110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41160cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
41170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fneg(VectorFormat vform,
41180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
41190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
41200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
41210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op = src.Float<T>(i);
41230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = -op;
41240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, op);
41250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fneg(VectorFormat vform,
41310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
41320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src) {
41330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fneg<float>(vform, dst, src);
41350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fneg<double>(vform, dst, src);
41380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41430cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
41440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fabs_(VectorFormat vform,
41450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
41460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
41470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
41480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op = src.Float<T>(i);
41500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (copysign(1.0, op) < 0.0) {
41510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      op = -op;
41520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
41530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, op);
41540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fabs_(VectorFormat vform,
41600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
41610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
41620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fabs_<float>(vform, dst, src);
41640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fabs_<double>(vform, dst, src);
41670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fabd(VectorFormat vform,
41730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
41740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
41750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2) {
41760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
41770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  fsub(vform, temp, src1, src2);
41780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  fabs_(vform, dst, temp);
41790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
41800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fsqrt(VectorFormat vform,
41840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
41850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
41860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
41870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float result = FPSqrt(src.Float<float>(i));
41900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, result);
41910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
41920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double result = FPSqrt(src.Float<double>(i));
41960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, result);
41970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
41980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
42000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_NEON_FP_PAIR_OP(FNP, FN, OP)                          \
42040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::FNP(VectorFormat vform,                    \
42050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,                    \
42060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src1,            \
42070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src2) {          \
42080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp1, temp2;                                         \
42090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uzp1(vform, temp1, src1, src2);                                    \
42100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uzp2(vform, temp2, src1, src2);                                    \
42110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FN(vform, dst, temp1, temp2);                                      \
42120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;                                                        \
42130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}                                                                    \
42140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                                                     \
42150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::FNP(VectorFormat vform,                    \
42160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LogicVRegister dst,                    \
42170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const LogicVRegister& src) {           \
42180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vform == kFormatS) {                                           \
42190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    float result = OP(src.Float<float>(0), src.Float<float>(1));     \
42200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(0, result);                                         \
42210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {                                                           \
42220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vform == kFormatD);                                  \
42230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    double result = OP(src.Float<double>(0), src.Float<double>(1));  \
42240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(0, result);                                         \
42250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }                                                                  \
42260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);                                          \
42270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;                                                        \
42280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)
42300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_NEON_FP_PAIR_OP
42310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fminmaxv(VectorFormat vform,
42340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   LogicVRegister dst,
42350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const LogicVRegister& src,
42360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   FPMinMaxOp Op) {
42370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vform == kFormat4S);
42380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vform);
42390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  float result1 = (this->*Op)(src.Float<float>(0), src.Float<float>(1));
42400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  float result2 = (this->*Op)(src.Float<float>(2), src.Float<float>(3));
42410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  float result = (this->*Op)(result1, result2);
42420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(kFormatS);
42430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.SetFloat<float>(0, result);
42440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
42450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmaxv(VectorFormat vform,
42490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
42500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
42510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return fminmaxv(vform, dst, src, &Simulator::FPMax);
42520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fminv(VectorFormat vform,
42560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
42570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
42580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return fminmaxv(vform, dst, src, &Simulator::FPMin);
42590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmaxnmv(VectorFormat vform,
42630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
42640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
42650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return fminmaxv(vform, dst, src, &Simulator::FPMaxNM);
42660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fminnmv(VectorFormat vform,
42700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
42710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src) {
42720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return fminmaxv(vform, dst, src, &Simulator::FPMinNM);
42730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmul(VectorFormat vform,
42770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
42780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
42790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2,
42800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int index) {
42810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
42820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
42830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
42840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
42850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmul<float>(vform, dst, src1, index_reg);
42860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
42880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
42890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
42900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmul<double>(vform, dst, src1, index_reg);
42910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
42920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
42930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmla(VectorFormat vform,
42970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
42980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
42990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2,
43000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int index) {
43010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
43020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
43030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
43050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmla<float>(vform, dst, src1, index_reg);
43060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
43080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
43100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmla<double>(vform, dst, src1, index_reg);
43110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
43120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
43130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmls(VectorFormat vform,
43170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               LogicVRegister dst,
43180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src1,
43190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const LogicVRegister& src2,
43200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int index) {
43210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
43220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
43230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
43250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmls<float>(vform, dst, src1, index_reg);
43260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
43280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
43300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmls<double>(vform, dst, src1, index_reg);
43310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
43320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
43330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fmulx(VectorFormat vform,
43370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
43380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src1,
43390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src2,
43400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int index) {
43410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
43420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  SimVRegister temp;
43430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
43450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmulx<float>(vform, dst, src1, index_reg);
43460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
43480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
43500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fmulx<double>(vform, dst, src1, index_reg);
43510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
43520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
43530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frint(VectorFormat vform,
43570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
43580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
43590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPRounding rounding_mode,
43600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                bool inexact_exception) {
43610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
43620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
43640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float input = src.Float<float>(i);
43650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float rounded = FPRoundInt(input, rounding_mode);
43660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (inexact_exception && !std::isnan(input) && (input != rounded)) {
43670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
43680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
43690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<float>(i, rounded);
43700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
43710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
43720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
43740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double input = src.Float<double>(i);
43750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double rounded = FPRoundInt(input, rounding_mode);
43760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (inexact_exception && !std::isnan(input) && (input != rounded)) {
43770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        FPProcessException();
43780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
43790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<double>(i, rounded);
43800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
43810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
43820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
43830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvts(VectorFormat vform,
43870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
43880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
43890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPRounding rounding_mode,
43900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int fbits) {
43910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
43920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
43940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float op = src.Float<float>(i) * std::pow(2.0f, fbits);
43950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, FPToInt32(op, rounding_mode));
43960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
43970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
43980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double op = src.Float<double>(i) * std::pow(2.0, fbits);
44010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetInt(vform, i, FPToInt64(op, rounding_mode));
44020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtu(VectorFormat vform,
44090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
44100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
44110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPRounding rounding_mode,
44120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int fbits) {
44130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
44140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float op = src.Float<float>(i) * std::pow(2.0f, fbits);
44170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, FPToUInt32(op, rounding_mode));
44180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
44200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double op = src.Float<double>(i) * std::pow(2.0, fbits);
44230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetUint(vform, i, FPToUInt64(op, rounding_mode));
44240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtl(VectorFormat vform,
44310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
44320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
44330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
44350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToFloat(src.Float<float16>(i)));
44360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
44380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
44400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToDouble(src.Float<float>(i)));
44410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtl2(VectorFormat vform,
44480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
44490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
44500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform);
44510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < lane_count; i++) {
44530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToFloat(src.Float<float16>(i + lane_count)));
44540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
44560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < lane_count; i++) {
44580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToDouble(src.Float<float>(i + lane_count)));
44590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtn(VectorFormat vform,
44660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
44670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src) {
44680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
44690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToFloat16(src.Float<float>(i), FPTieEven));
44710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
44730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
44740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPTieEven));
44760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44820cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtn2(VectorFormat vform,
44830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
44840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
44850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform) / 2;
44860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
44870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = lane_count - 1; i >= 0; i--) {
44880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i + lane_count, FPToFloat16(src.Float<float>(i), FPTieEven));
44890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
44910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
44920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = lane_count - 1; i >= 0; i--) {
44930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPTieEven));
44940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
44950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
44960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
44970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtxn(VectorFormat vform,
45010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
45020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
45030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
45040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
45060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPRoundOdd));
45070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
45080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
45090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::fcvtxn2(VectorFormat vform,
45130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
45140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src) {
45150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_count = LaneCountFromFormat(vform) / 2;
45170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = lane_count - 1; i >= 0; i--) {
45180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPRoundOdd));
45190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
45200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
45210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Based on reference C function recip_sqrt_estimate from ARM ARM.
45250cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::recip_sqrt_estimate(double a) {
45260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int q0, q1, s;
45270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double r;
45280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (a < 0.5) {
45290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q0 = static_cast<int>(a * 512.0);
45300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
45310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else  {
45320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q1 = static_cast<int>(a * 256.0);
45330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
45340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
45350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  s = static_cast<int>(256.0 * r + 0.5);
45360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return static_cast<double>(s) / 256.0;
45370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlstatic inline uint64_t Bits(uint64_t val, int start_bit, int end_bit) {
45410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return unsigned_bitextract_64(start_bit, end_bit, val);
45420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45450cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
45460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPRecipSqrtEstimate(T op) {
45470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(op)) {
45480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPProcessNaN(op);
45490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (op == 0.0) {
45500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (copysign(1.0, op) < 0.0) {
45510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return kFP64NegativeInfinity;
45520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
45530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return kFP64PositiveInfinity;
45540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (copysign(1.0, op) < 0.0) {
45560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();
45570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPDefaultNaN<T>();
45580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (std::isinf(op)) {
45590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0.0;
45600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
45610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t fraction;
45620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int exp, result_exp;
45630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
45650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exp = float_exp(op);
45660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = float_mantissa(op);
45670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction <<= 29;
45680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
45690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exp = double_exp(op);
45700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = double_mantissa(op);
45710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (exp == 0) {
45740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      while (Bits(fraction, 51, 51) == 0) {
45750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        fraction = Bits(fraction, 50, 0) << 1;
45760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        exp -= 1;
45770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
45780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = Bits(fraction, 50, 0) << 1;
45790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    double scaled;
45820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (Bits(exp, 0, 0) == 0) {
45830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
45840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
45850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      scaled = double_pack(0, 1021, Bits(fraction, 51, 44) << 44);
45860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
45890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result_exp = (380 - exp) / 2;
45900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
45910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result_exp = (3068 - exp) / 2;
45920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45945ee436a3a51863de7b5dc9326cf02895248050c2armvixl    uint64_t estimate = double_to_rawbits(recip_sqrt_estimate(scaled));
45950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
45975ee436a3a51863de7b5dc9326cf02895248050c2armvixl      uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
45985ee436a3a51863de7b5dc9326cf02895248050c2armvixl      uint32_t est_bits = static_cast<uint32_t>(Bits(estimate, 51, 29));
45995ee436a3a51863de7b5dc9326cf02895248050c2armvixl      return float_pack(0, exp_bits, est_bits);
46000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46015ee436a3a51863de7b5dc9326cf02895248050c2armvixl      return double_pack(0, Bits(result_exp, 10, 0), Bits(estimate, 51, 0));
46020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
46040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frsqrte(VectorFormat vform,
46080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
46090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src) {
46100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
46110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
46120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
46130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float input = src.Float<float>(i);
46140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPRecipSqrtEstimate<float>(input));
46150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
46170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
46180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
46190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double input = src.Float<double>(i);
46200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPRecipSqrtEstimate<double>(input));
46210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
46230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
46240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46260cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
46270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlT Simulator::FPRecipEstimate(T op, FPRounding rounding) {
46280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t sign;
46290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
46310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    sign = float_sign(op);
46320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
46330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    sign = double_sign(op);
46340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
46350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (std::isnan(op)) {
46370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return FPProcessNaN(op);
46380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (std::isinf(op)) {
46390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return (sign == 1) ? -0.0 : 0.0;
46400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (op == 0.0) {
46410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();  // FPExc_DivideByZero exception.
46420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
46430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (((sizeof(T) == sizeof(float)) &&  // NOLINT(runtime/sizeof)
46440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (std::fabs(op) < std::pow(2.0, -128.0))) ||
46450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl             ((sizeof(T) == sizeof(double)) &&  // NOLINT(runtime/sizeof)
46460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (std::fabs(op) < std::pow(2.0, -1024.0)))) {
46470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool overflow_to_inf = false;
46480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rounding) {
46490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case FPTieEven: overflow_to_inf = true; break;
46500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case FPPositiveInfinity: overflow_to_inf = (sign == 0); break;
46510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case FPNegativeInfinity: overflow_to_inf = (sign == 1); break;
46520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case FPZero: overflow_to_inf = false; break;
46530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default: break;
46540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    FPProcessException();  // FPExc_Overflow and FPExc_Inexact.
46560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (overflow_to_inf) {
46570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
46580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Return FPMaxNormal(sign).
46600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
46610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return float_pack(sign, 0xfe, 0x07fffff);
46620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
46630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return double_pack(sign, 0x7fe, 0x0fffffffffffffl);
46640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
46650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
46670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint64_t fraction;
46680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int exp, result_exp;
46690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint32_t sign;
46700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
46720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sign = float_sign(op);
46730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exp = float_exp(op);
46740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = float_mantissa(op);
46750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction <<= 29;
46760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      sign = double_sign(op);
46780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      exp = double_exp(op);
46790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = double_mantissa(op);
46800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (exp == 0) {
46830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (Bits(fraction, 51, 51) == 0) {
46840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        exp -= 1;
46850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        fraction = Bits(fraction, 49, 0) << 2;
46860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
46870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        fraction = Bits(fraction, 50, 0) << 1;
46880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
46890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    double scaled = double_pack(0, 1022, Bits(fraction, 51, 44) << 44);
46920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
46940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result_exp = (253 - exp);  // In range 253-254 = -1 to 253+1 = 254.
46950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result_exp = (2045 - exp);  // In range 2045-2046 = -1 to 2045+1 = 2046.
46970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    double estimate = recip_estimate(scaled);
47000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    fraction = double_mantissa(estimate);
47020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (result_exp == 0) {
47030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = (UINT64_C(1) << 51) | Bits(fraction, 51, 1);
47040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (result_exp == -1) {
47050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      fraction = (UINT64_C(1) << 50) | Bits(fraction, 51, 2);
47060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result_exp = 0;
47070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
47095ee436a3a51863de7b5dc9326cf02895248050c2armvixl      uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
47105ee436a3a51863de7b5dc9326cf02895248050c2armvixl      uint32_t frac_bits = static_cast<uint32_t>(Bits(fraction, 51, 29));
47115ee436a3a51863de7b5dc9326cf02895248050c2armvixl      return float_pack(sign, exp_bits, frac_bits);
47120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
47130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return double_pack(sign, Bits(result_exp, 10, 0), Bits(fraction, 51, 0));
47140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frecpe(VectorFormat vform,
47200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
47210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src,
47220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 FPRounding round) {
47230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
47240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
47250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
47260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float input = src.Float<float>(i);
47270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPRecipEstimate<float>(input, round));
47280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
47300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
47310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
47320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double input = src.Float<double>(i);
47330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat(i, FPRecipEstimate<double>(input, round));
47340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
47370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ursqrte(VectorFormat vform,
47410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  LogicVRegister dst,
47420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const LogicVRegister& src) {
47430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
47445ee436a3a51863de7b5dc9326cf02895248050c2armvixl  uint64_t operand;
47455ee436a3a51863de7b5dc9326cf02895248050c2armvixl  uint32_t result;
47460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double dp_operand, dp_result;
47470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
47480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    operand = src.Uint(vform, i);
47490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (operand <= 0x3FFFFFFF) {
47500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = 0xFFFFFFFF;
47510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
47520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dp_operand = operand * std::pow(2.0, -32);
47530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dp_result = recip_sqrt_estimate(dp_operand) * std::pow(2.0, 31);
47540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = static_cast<uint32_t>(dp_result);
47550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result);
47570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
47590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Based on reference C function recip_estimate from ARM ARM.
47630cc8b6ece4b3e757e11a906a81ece292437713abarmvixldouble Simulator::recip_estimate(double a) {
47640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int q, s;
47650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double r;
47660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  q = static_cast<int>(a * 512.0);
47670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
47680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  s = static_cast<int>(256.0 * r + 0.5);
47690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return static_cast<double>(s) / 256.0;
47700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::urecpe(VectorFormat vform,
47740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
47750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
47760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
47775ee436a3a51863de7b5dc9326cf02895248050c2armvixl  uint64_t operand;
47785ee436a3a51863de7b5dc9326cf02895248050c2armvixl  uint32_t result;
47790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  double dp_operand, dp_result;
47800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
47810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    operand = src.Uint(vform, i);
47820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (operand <= 0x7FFFFFFF) {
47830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = 0xFFFFFFFF;
47840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
47850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dp_operand = operand * std::pow(2.0, -32);
47860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dp_result = recip_estimate(dp_operand) * std::pow(2.0, 31);
47870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      result = static_cast<uint32_t>(dp_result);
47880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetUint(vform, i, result);
47900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
47920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47940cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <typename T>
47950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frecpx(VectorFormat vform,
47960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
47970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
47980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dst.ClearForWrite(vform);
47990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T op = src.Float<T>(i);
48010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    T result;
48020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (std::isnan(op)) {
48030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       result = FPProcessNaN(op);
48040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
48050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      int exp;
48060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      uint32_t sign;
48070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
48080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        sign = float_sign(op);
48090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        exp = float_exp(op);
48105ee436a3a51863de7b5dc9326cf02895248050c2armvixl        exp = (exp == 0) ? (0xFF - 1) : static_cast<int>(Bits(~exp, 7, 0));
48110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        result = float_pack(sign, exp, 0);
48120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      } else {
48130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        sign = double_sign(op);
48140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        exp = double_exp(op);
48155ee436a3a51863de7b5dc9326cf02895248050c2armvixl        exp = (exp == 0) ? (0x7FF - 1) : static_cast<int>(Bits(~exp, 10, 0));
48160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        result = double_pack(sign, exp, 0);
48170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
48180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    dst.SetFloat(i, result);
48200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
48220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::frecpx(VectorFormat vform,
48260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicVRegister dst,
48270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const LogicVRegister& src) {
48280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
48290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frecpx<float>(vform, dst, src);
48300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
48310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
48320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    frecpx<double>(vform, dst, src);
48330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
48350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::scvtf(VectorFormat vform,
48380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
48390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
48400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int fbits,
48410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPRounding round) {
48420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
48440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float result = FixedToFloat(src.Int(kFormatS, i), fbits, round);
48450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<float>(i, result);
48460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
48470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
48480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double result = FixedToDouble(src.Int(kFormatD, i), fbits, round);
48490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<double>(i, result);
48500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
48530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLogicVRegister Simulator::ucvtf(VectorFormat vform,
48570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                LogicVRegister dst,
48580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const LogicVRegister& src,
48590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int fbits,
48600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPRounding round) {
48610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
48630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      float result = UFixedToFloat(src.Uint(kFormatS, i), fbits, round);
48640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<float>(i, result);
48650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
48660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
48670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      double result = UFixedToDouble(src.Uint(kFormatD, i), fbits, round);
48680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dst.SetFloat<double>(i, result);
48690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dst;
48720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}  // namespace vixl
48769795cffa6b242fddee25847d17136a8da5b5c2d7Phil Wang
48779795cffa6b242fddee25847d17136a8da5b5c2d7Phil Wang#endif  // VIXL_INCLUDE_SIMULATOR
4878