1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2015, VIXL authors
25289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// All rights reserved.
35289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//
45289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Redistribution and use in source and binary forms, with or without
55289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// modification, are permitted provided that the following conditions are met:
65289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//
75289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//   * Redistributions of source code must retain the above copyright notice,
85289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//     this list of conditions and the following disclaimer.
95289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//   * Redistributions in binary form must reproduce the above copyright notice,
105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//     this list of conditions and the following disclaimer in the documentation
115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//     and/or other materials provided with the distribution.
125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//     used to endorse or promote products derived from this software without
145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//     specific prior written permission.
155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl//
165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
271e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
28684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl#include <cmath>
30b68bacb75c1ab265fc539afa93964c7f51f35589Alexandre Rames
31b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "simulator-aarch64.h"
325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlnamespace vixl {
3488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch64 {
356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <>
370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixldouble Simulator::FPDefaultNaN<double>() {
386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return kFP64DefaultNaN;
396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <>
430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlfloat Simulator::FPDefaultNaN<float>() {
446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return kFP32DefaultNaN;
456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
466e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// See FPRound for a description of this function.
480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlstatic inline double FPRoundToDouble(int64_t sign,
490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                     int64_t exponent,
500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                     uint64_t mantissa,
510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                     FPRounding round_mode) {
526e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  int64_t bits =
536e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign,
546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                                 exponent,
556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                                 mantissa,
566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                                 round_mode);
5788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  return RawbitsToDouble(bits);
586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// See FPRound for a description of this function.
620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlstatic inline float FPRoundToFloat(int64_t sign,
630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   int64_t exponent,
640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   uint64_t mantissa,
650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   FPRounding round_mode) {
666e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  int32_t bits =
676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign,
686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                               exponent,
696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                               mantissa,
706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                                               round_mode);
7188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  return RawbitsToFloat(bits);
726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// See FPRound for a description of this function.
766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlstatic inline float16 FPRoundToFloat16(int64_t sign,
776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                       int64_t exponent,
786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                       uint64_t mantissa,
796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl                                       FPRounding round_mode) {
800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  return FPRound<float16,
810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 kFloat16ExponentBits,
820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 kFloat16MantissaBits>(sign, exponent, mantissa, round_mode);
836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
866e2c8275d5f34a531fe1eef7a7aa877601be8558armvixldouble Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) {
876e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (src >= 0) {
886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return UFixedToDouble(src, fbits, round);
899e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  } else if (src == INT64_MIN) {
909e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    return -UFixedToDouble(src, fbits, round);
916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else {
926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return -UFixedToDouble(-src, fbits, round);
936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixldouble Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) {
986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // An input of 0 is a special case because the result is effectively
996e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
1006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (src == 0) {
1016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return 0.0;
1026e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Calculate the exponent. The highest significant bit will have the value
1056e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // 2^exponent.
1066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  const int highest_significant_bit = 63 - CountLeadingZeros(src);
1076e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  const int64_t exponent = highest_significant_bit - fbits;
1086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1096e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return FPRoundToDouble(0, exponent, src, round);
1106e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
1116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1136e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) {
1146e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (src >= 0) {
1156e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return UFixedToFloat(src, fbits, round);
1169e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  } else if (src == INT64_MIN) {
1179e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    return -UFixedToFloat(src, fbits, round);
1186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else {
1196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return -UFixedToFloat(-src, fbits, round);
1206e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
1226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1246e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) {
1256e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // An input of 0 is a special case because the result is effectively
1266e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
1276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (src == 0) {
1286e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    return 0.0f;
1296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1306e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1316e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Calculate the exponent. The highest significant bit will have the value
1326e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // 2^exponent.
1336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  const int highest_significant_bit = 63 - CountLeadingZeros(src);
1346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  const int32_t exponent = highest_significant_bit - fbits;
1356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return FPRoundToFloat(0, exponent, src, round);
1376e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
1386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixldouble Simulator::FPToDouble(float value) {
1416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  switch (std::fpclassify(value)) {
1426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NAN: {
1436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (IsSignallingNaN(value)) {
1446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        FPProcessException();
1456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
14688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      if (ReadDN()) return kFP64DefaultNaN;
1476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert NaNs as the processor would:
1496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The sign is propagated.
1506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The payload (mantissa) is transferred entirely, except that the top
1516e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    bit is forced to '1', making the result a quiet NaN. The unused
1526e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    (low-order) payload bits are set to 0.
15388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      uint32_t raw = FloatToRawbits(value);
1546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t sign = raw >> 31;
1566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t exponent = (1 << 11) - 1;
15788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      uint64_t payload = ExtractUnsignedBitfield64(21, 0, raw);
1580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      payload <<= (52 - 23);           // The unused low-order bits should be 0.
1596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      payload |= (UINT64_C(1) << 51);  // Force a quiet NaN.
1606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
16188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return RawbitsToDouble((sign << 63) | (exponent << 52) | payload);
1626e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
1636e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1646e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_ZERO:
1656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NORMAL:
1666e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_SUBNORMAL:
1676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_INFINITE: {
1686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // All other inputs are preserved in a standard cast, because every value
1696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // representable using an IEEE-754 float is also representable using an
1706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // IEEE-754 double.
1716e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return static_cast<double>(value);
1726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
1736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_UNREACHABLE();
1766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return static_cast<double>(value);
1776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
1786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat Simulator::FPToFloat(float16 value) {
1816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  uint32_t sign = value >> 15;
1820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  uint32_t exponent =
18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      ExtractUnsignedBitfield32(kFloat16MantissaBits + kFloat16ExponentBits - 1,
18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                kFloat16MantissaBits,
18588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                value);
1860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  uint32_t mantissa =
18788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      ExtractUnsignedBitfield32(kFloat16MantissaBits - 1, 0, value);
1886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
18988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  switch (Float16Classify(value)) {
1906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_ZERO:
1916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? 0.0f : -0.0f;
1926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_INFINITE:
1946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? kFP32PositiveInfinity : kFP32NegativeInfinity;
1956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_SUBNORMAL: {
1976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Calculate shift required to put mantissa into the most-significant bits
1986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // of the destination mantissa.
1996e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      int shift = CountLeadingZeros(mantissa << (32 - 10));
2006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Shift mantissa and discard implicit '1'.
2026e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits) + shift + 1;
2036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa &= (1 << kFloatMantissaBits) - 1;
2046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2056e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Adjust the exponent for the shift applied, and rebias.
2066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      exponent = exponent - shift + (-15 + 127);
2076e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      break;
2086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
2096e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2106e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NAN:
2116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (IsSignallingNaN(value)) {
2126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        FPProcessException();
2136e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
21488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      if (ReadDN()) return kFP32DefaultNaN;
2156e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2166e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert NaNs as the processor would:
2176e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The sign is propagated.
2186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The payload (mantissa) is transferred entirely, except that the top
2196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    bit is forced to '1', making the result a quiet NaN. The unused
2206e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    (low-order) payload bits are set to 0.
2216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      exponent = (1 << kFloatExponentBits) - 1;
2226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Increase bits in mantissa, making low-order bits 0.
2246e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
2256e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa |= 1 << 22;  // Force a quiet NaN.
2266e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      break;
2276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2286e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NORMAL:
2296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Increase bits in mantissa, making low-order bits 0.
2306e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa <<= (kFloatMantissaBits - kFloat16MantissaBits);
2316e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2326e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Change exponent bias.
2336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      exponent += (-15 + 127);
2346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      break;
2356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    default:
2370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VIXL_UNREACHABLE();
2386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
23988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  return RawbitsToFloat((sign << 31) | (exponent << kFloatMantissaBits) |
24088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                        mantissa);
2416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
2426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat16 Simulator::FPToFloat16(float value, FPRounding round_mode) {
2456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Only the FPTieEven rounding mode is implemented.
2466e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(round_mode == FPTieEven);
2476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  USE(round_mode);
2486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
24988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t raw = FloatToRawbits(value);
2506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  int32_t sign = raw >> 31;
25188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int32_t exponent = ExtractUnsignedBitfield32(30, 23, raw) - 127;
25288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t mantissa = ExtractUnsignedBitfield32(22, 0, raw);
2536e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  switch (std::fpclassify(value)) {
2556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NAN: {
2566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (IsSignallingNaN(value)) {
2576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        FPProcessException();
2586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
25988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      if (ReadDN()) return kFP16DefaultNaN;
2606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert NaNs as the processor would:
2626e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The sign is propagated.
2636e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The payload (mantissa) is transferred as much as possible, except
2646e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
2650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      float16 result =
2660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
2676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      result |= mantissa >> (kFloatMantissaBits - kFloat16MantissaBits);
2686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      result |= (1 << 9);  // Force a quiet NaN;
2696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return result;
2706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
2716e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_ZERO:
2736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? 0 : 0x8000;
2746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_INFINITE:
2766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
2776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NORMAL:
2796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_SUBNORMAL: {
2806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert float-to-half as the processor would, assuming that FPCR.FZ
2816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // (flush-to-zero) is not set.
2826e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Add the implicit '1' bit to the mantissa.
2846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa += (1 << 23);
2856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
2866e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
2876e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
2886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2896e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_UNREACHABLE();
2906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return 0;
2916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
2926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat16 Simulator::FPToFloat16(double value, FPRounding round_mode) {
2956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Only the FPTieEven rounding mode is implemented.
2966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(round_mode == FPTieEven);
2976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  USE(round_mode);
2986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint64_t raw = DoubleToRawbits(value);
3006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  int32_t sign = raw >> 63;
30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int64_t exponent = ExtractUnsignedBitfield64(62, 52, raw) - 1023;
30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint64_t mantissa = ExtractUnsignedBitfield64(51, 0, raw);
3036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  switch (std::fpclassify(value)) {
3056e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NAN: {
3066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (IsSignallingNaN(value)) {
3076e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        FPProcessException();
3086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      if (ReadDN()) return kFP16DefaultNaN;
3106e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert NaNs as the processor would:
3126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The sign is propagated.
3136e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The payload (mantissa) is transferred as much as possible, except
3146e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
3150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      float16 result =
3160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
3176e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      result |= mantissa >> (kDoubleMantissaBits - kFloat16MantissaBits);
3186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      result |= (1 << 9);  // Force a quiet NaN;
3196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return result;
3206e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
3216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_ZERO:
3236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? 0 : 0x8000;
3246e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3256e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_INFINITE:
3266e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return (sign == 0) ? kFP16PositiveInfinity : kFP16NegativeInfinity;
3276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3286e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NORMAL:
3296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_SUBNORMAL: {
3306e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert double-to-half as the processor would, assuming that FPCR.FZ
3316e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // (flush-to-zero) is not set.
3326e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Add the implicit '1' bit to the mantissa.
3346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa += (UINT64_C(1) << 52);
3356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPRoundToFloat16(sign, exponent, mantissa, round_mode);
3366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
3376e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
3386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_UNREACHABLE();
3406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return 0;
3416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
3426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixlfloat Simulator::FPToFloat(double value, FPRounding round_mode) {
3456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Only the FPTieEven rounding mode is implemented.
3466e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
3476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  USE(round_mode);
3486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  switch (std::fpclassify(value)) {
3506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NAN: {
3516e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (IsSignallingNaN(value)) {
3526e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        FPProcessException();
3536e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      if (ReadDN()) return kFP32DefaultNaN;
3556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert NaNs as the processor would:
3576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The sign is propagated.
3586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //  - The payload (mantissa) is transferred as much as possible, except
3596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //    that the top bit is forced to '1', making the result a quiet NaN.
36088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      uint64_t raw = DoubleToRawbits(value);
3616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3626e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint32_t sign = raw >> 63;
3636e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint32_t exponent = (1 << 8) - 1;
364db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      uint32_t payload =
36588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois          static_cast<uint32_t>(ExtractUnsignedBitfield64(50, 52 - 23, raw));
3660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      payload |= (1 << 22);  // Force a quiet NaN.
3676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
36888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return RawbitsToFloat((sign << 31) | (exponent << 23) | payload);
3696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
3706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3716e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_ZERO:
3726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_INFINITE: {
3736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // In a C++ cast, any value representable in the target type will be
3746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // unchanged. This is always the case for +/-0.0 and infinities.
3756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return static_cast<float>(value);
3766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
3776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_NORMAL:
3796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    case FP_SUBNORMAL: {
3806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Convert double-to-float as the processor would, assuming that FPCR.FZ
3816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // (flush-to-zero) is not set.
38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      uint64_t raw = DoubleToRawbits(value);
3836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Extract the IEEE-754 double components.
3846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint32_t sign = raw >> 63;
3856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Extract the exponent and remove the IEEE-754 encoding bias.
386db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      int32_t exponent =
38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois          static_cast<int32_t>(ExtractUnsignedBitfield64(62, 52, raw)) - 1023;
3886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // Extract the mantissa and add the implicit '1' bit.
38988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      uint64_t mantissa = ExtractUnsignedBitfield64(51, 0, raw);
3906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (std::fpclassify(value) == FP_NORMAL) {
3916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        mantissa |= (UINT64_C(1) << 52);
3926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
3936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPRoundToFloat(sign, exponent, mantissa, round_mode);
3946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
3956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
3966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_UNREACHABLE();
3986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return value;
3996e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
4006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
4016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
4020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid Simulator::ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr) {
4035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
4045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.ReadUintFromMem(vform, i, addr);
4065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr += LaneSizeInBytesFromFormat(vform);
4075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld1(VectorFormat vform,
4125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
4135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
4145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
4155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ReadUintFromMem(vform, index, addr);
4165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid Simulator::ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr) {
4205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
4215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.ReadUintFromMem(vform, i, addr);
4235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld2(VectorFormat vform,
4285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
4295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
4305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
4315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
4325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
4335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
4345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + esize;
4355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr1);
4375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
4385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr1 += 2 * esize;
4395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 2 * esize;
4405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld2(VectorFormat vform,
4455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
4465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
4475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
4485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
4495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
4505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
4515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
4525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ReadUintFromMem(vform, index, addr1);
4535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ReadUintFromMem(vform, index, addr2);
4545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld2r(VectorFormat vform,
4585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst1,
4595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst2,
4605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     uint64_t addr) {
4615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
4625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
4635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
4645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr);
4665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
4675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld3(VectorFormat vform,
4725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
4735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
4745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
4755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
4765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
4775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
4785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
4795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
4805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + esize;
4815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + esize;
4825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr1);
4845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
4855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.ReadUintFromMem(vform, i, addr3);
4865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr1 += 3 * esize;
4875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 3 * esize;
4885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr3 += 3 * esize;
4895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
4915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld3(VectorFormat vform,
4945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
4955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
4965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
4975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
4985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
4995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
5005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
5015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
5025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
5035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ReadUintFromMem(vform, index, addr1);
5055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ReadUintFromMem(vform, index, addr2);
5065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ReadUintFromMem(vform, index, addr3);
5075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
5085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld3r(VectorFormat vform,
5115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst1,
5125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst2,
5135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst3,
5145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     uint64_t addr) {
5155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
5165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
5175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
5185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
5195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr);
5225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
5235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.ReadUintFromMem(vform, i, addr3);
5245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
5265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld4(VectorFormat vform,
5295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
5305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
5315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
5325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst4,
5335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
5345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
5355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
5365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
5375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst4.ClearForWrite(vform);
5385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
5395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + esize;
5405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + esize;
5415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr4 = addr3 + esize;
5425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr1);
5445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
5455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.ReadUintFromMem(vform, i, addr3);
5465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst4.ReadUintFromMem(vform, i, addr4);
5475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr1 += 4 * esize;
5485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 4 * esize;
5495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr3 += 4 * esize;
5505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr4 += 4 * esize;
5515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
5535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld4(VectorFormat vform,
5565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst1,
5575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
5585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
5595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst4,
5605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
5615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr1) {
5625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
5635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
5645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
5655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst4.ClearForWrite(vform);
5665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
5675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
5695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ReadUintFromMem(vform, index, addr1);
5705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ReadUintFromMem(vform, index, addr2);
5715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ReadUintFromMem(vform, index, addr3);
5725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst4.ReadUintFromMem(vform, index, addr4);
5735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
5745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::ld4r(VectorFormat vform,
5775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst1,
5785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst2,
5795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst3,
5805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst4,
5815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     uint64_t addr) {
5825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst1.ClearForWrite(vform);
5835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.ClearForWrite(vform);
5845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.ClearForWrite(vform);
5855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst4.ClearForWrite(vform);
5865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
5875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
5885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
5895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst1.ReadUintFromMem(vform, i, addr);
5915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.ReadUintFromMem(vform, i, addr2);
5925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.ReadUintFromMem(vform, i, addr3);
5935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst4.ReadUintFromMem(vform, i, addr4);
5945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
5965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid Simulator::st1(VectorFormat vform, LogicVRegister src, uint64_t addr) {
5995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    src.WriteUintToMem(vform, i, addr);
6015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr += LaneSizeInBytesFromFormat(vform);
6025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st1(VectorFormat vform,
6075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister src,
6085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
6095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  src.WriteUintToMem(vform, index, addr);
6115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st2(VectorFormat vform,
6155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
6195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + esize;
6205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.WriteUintToMem(vform, i, addr);
6225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.WriteUintToMem(vform, i, addr2);
6235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr += 2 * esize;
6245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 2 * esize;
6255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st2(VectorFormat vform,
6305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
6335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
6355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.WriteUintToMem(vform, index, addr);
6365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
6375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st3(VectorFormat vform,
6415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
6445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
6465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + esize;
6475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + esize;
6485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.WriteUintToMem(vform, i, addr);
6505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.WriteUintToMem(vform, i, addr2);
6515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.WriteUintToMem(vform, i, addr3);
6525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr += 3 * esize;
6535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 3 * esize;
6545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr3 += 3 * esize;
6555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st3(VectorFormat vform,
6605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
6635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
6645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
6665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.WriteUintToMem(vform, index, addr);
6675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
6685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.WriteUintToMem(vform, index, addr + 2 * esize);
6695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st4(VectorFormat vform,
6735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
6765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst4,
6775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
6785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
6795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr2 = addr + esize;
6805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr3 = addr2 + esize;
6815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t addr4 = addr3 + esize;
6825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.WriteUintToMem(vform, i, addr);
6845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst2.WriteUintToMem(vform, i, addr2);
6855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst3.WriteUintToMem(vform, i, addr3);
6865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst4.WriteUintToMem(vform, i, addr4);
6875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr += 4 * esize;
6885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr2 += 4 * esize;
6895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr3 += 4 * esize;
6905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    addr4 += 4 * esize;
6915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
6935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlvoid Simulator::st4(VectorFormat vform,
6965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst,
6975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst2,
6985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst3,
6995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    LogicVRegister dst4,
7005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    int index,
7015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                    uint64_t addr) {
7025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBytesFromFormat(vform);
7035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.WriteUintToMem(vform, index, addr);
7045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst2.WriteUintToMem(vform, index, addr + 1 * esize);
7055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst3.WriteUintToMem(vform, index, addr + 2 * esize);
7065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst4.WriteUintToMem(vform, index, addr + 3 * esize);
7075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
7085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::cmp(VectorFormat vform,
7115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
7125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
7135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2,
7145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              Condition cond) {
7155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
7165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    int64_t sa = src1.Int(vform, i);
7180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    int64_t sb = src2.Int(vform, i);
7195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ua = src1.Uint(vform, i);
7205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ub = src2.Uint(vform, i);
7215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    bool result = false;
7225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (cond) {
7230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case eq:
7240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (ua == ub);
7250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case ge:
7270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (sa >= sb);
7280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case gt:
7300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (sa > sb);
7310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case hi:
7330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (ua > ub);
7340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case hs:
7360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (ua >= ub);
7370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case lt:
7390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (sa < sb);
7400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case le:
7420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = (sa <= sb);
7430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
7450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
7460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
7475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
7485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
7495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
7505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
7515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
7525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::cmp(VectorFormat vform,
7555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
7565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
7575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int imm,
7585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              Condition cond) {
7595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
7605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister imm_reg = dup_immediate(vform, temp, imm);
7615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return cmp(vform, dst, src1, imm_reg, cond);
7625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
7635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::cmptst(VectorFormat vform,
7665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
7675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
7685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
7695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
7705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ua = src1.Uint(vform, i);
7725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ub = src2.Uint(vform, i);
7735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, ((ua & ub) != 0) ? MaxUintFromFormat(vform) : 0);
7745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
7755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
7765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
7775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::add(VectorFormat vform,
7805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
7815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
7825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
7839e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  int lane_size = LaneSizeInBitsFromFormat(vform);
7845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
7855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
7865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for unsigned saturation.
7875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ua = src1.UintLeftJustified(vform, i);
7885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ub = src2.UintLeftJustified(vform, i);
7895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ur = ua + ub;
7905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (ur < ua) {
7915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUnsignedSat(i, true);
7925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
7935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
7945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for signed saturation.
7959e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_a = (ua >> 63) == 0;
7969e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_b = (ub >> 63) == 0;
7979e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_r = (ur >> 63) == 0;
7985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // If the signs of the operands are the same, but different from the result,
7995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // there was an overflow.
8009e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    if ((pos_a == pos_b) && (pos_a != pos_r)) {
8019e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetSignedSat(i, pos_a);
8025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
8035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8049e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    dst.SetInt(vform, i, ur >> (64 - lane_size));
8055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
8065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
8075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addp(VectorFormat vform,
8115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
8125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
8135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
8145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
8155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uzp1(vform, temp1, src1, src2);
8165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uzp2(vform, temp2, src1, src2);
8175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, temp1, temp2);
8185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
8195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mla(VectorFormat vform,
8235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
8265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, temp, src1, src2);
8285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, dst, temp);
8295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
8305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mls(VectorFormat vform,
8345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
8375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, temp, src1, src2);
8395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, dst, temp);
8405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
8415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mul(VectorFormat vform,
8455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
8485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
8495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
8505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) * src2.Uint(vform, i));
8515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
8525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
8535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mul(VectorFormat vform,
8575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2,
8605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int index) {
8615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return mul(vform, dst, src1, dup_element(indexform, temp, src2, index));
8645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mla(VectorFormat vform,
8685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2,
8715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int index) {
8725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return mla(vform, dst, src1, dup_element(indexform, temp, src2, index));
8755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mls(VectorFormat vform,
8795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
8805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
8815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2,
8825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int index) {
8835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform = VectorFormatFillQ(vform);
8855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return mls(vform, dst, src1, dup_element(indexform, temp, src2, index));
8865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
8895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smull(VectorFormat vform,
8905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
8915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
8925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
8935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
8945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
8955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
8960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
8975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smull(vform, dst, src1, dup_element(indexform, temp, src2, index));
8985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
8995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smull2(VectorFormat vform,
9020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
9030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
9040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
9050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
9065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umull(VectorFormat vform,
9145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
9155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
9165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
9175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
9185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umull(vform, dst, src1, dup_element(indexform, temp, src2, index));
9225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umull2(VectorFormat vform,
9260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
9270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
9280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
9290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
9305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlal(VectorFormat vform,
9385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
9395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
9405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
9415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
9425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
9465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlal2(VectorFormat vform,
9500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
9510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
9520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
9530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
9545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlal(VectorFormat vform,
9625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
9635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
9645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
9655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
9665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
9705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlal2(VectorFormat vform,
9740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
9750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
9760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
9770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
9785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
9825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlsl(VectorFormat vform,
9865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
9875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
9885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
9895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
9905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
9915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
9920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
9935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
9945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
9955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
9975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlsl2(VectorFormat vform,
9980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
9990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
10000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
10010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
10025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return smlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlsl(VectorFormat vform,
10105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
10115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
10125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
10135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
10145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
10185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlsl2(VectorFormat vform,
10220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
10230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
10240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2,
10250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 int index) {
10265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return umlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmull(VectorFormat vform,
10345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
10355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
10365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
10375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int index) {
10385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmull(vform, dst, src1, dup_element(indexform, temp, src2, index));
10425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmull2(VectorFormat vform,
10460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
10470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
10480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2,
10490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   int index) {
10505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlal(VectorFormat vform,
10585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
10595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
10605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
10615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int index) {
10625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
10665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlal2(VectorFormat vform,
10700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
10710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
10720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2,
10730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   int index) {
10745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
10785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlsl(VectorFormat vform,
10825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
10835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
10845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
10855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int index) {
10865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
10885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
10895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
10905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
10915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
10935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
10940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
10950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
10960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2,
10970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   int index) {
10985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
10995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform =
11005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
11015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
11025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmulh(VectorFormat vform,
11065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
11075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
11085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
11095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int index) {
11105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
11115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform = VectorFormatFillQ(vform);
11125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
11135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrdmulh(VectorFormat vform,
11170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
11180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
11190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2,
11200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   int index) {
11215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
11225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat indexform = VectorFormatFillQ(vform);
11235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqrdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
11245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
1127868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Ramesuint16_t Simulator::PolynomialMult(uint8_t op1, uint8_t op2) const {
11285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint16_t result = 0;
11295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint16_t extended_op2 = op2;
11305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < 8; ++i) {
11315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if ((op1 >> i) & 1) {
11325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = result ^ (extended_op2 << i);
11335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
11345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
11355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return result;
11365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::pmul(VectorFormat vform,
11405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
11415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
11425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
11435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
11445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.SetUint(vform,
11460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                i,
11475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                PolynomialMult(src1.Uint(vform, i), src2.Uint(vform, i)));
11485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
11495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
11505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::pmull(VectorFormat vform,
11540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                LogicVRegister dst,
11550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src1,
11560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src2) {
11575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_src = VectorFormatHalfWidth(vform);
11585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
11595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.SetUint(vform,
11610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                i,
11620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                PolynomialMult(src1.Uint(vform_src, i),
11630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               src2.Uint(vform_src, i)));
11645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
11655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
11665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::pmull2(VectorFormat vform,
11700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 LogicVRegister dst,
11710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src1,
11720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                 const LogicVRegister& src2) {
11735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_src = VectorFormatHalfWidthDoubleLanes(vform);
11745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
11755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform);
11765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < lane_count; i++) {
11770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.SetUint(vform,
11780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                i,
11790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                PolynomialMult(src1.Uint(vform_src, lane_count + i),
11800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               src2.Uint(vform_src, lane_count + i)));
11815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
11825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
11835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
11845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sub(VectorFormat vform,
11875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
11885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
11895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
11909e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  int lane_size = LaneSizeInBitsFromFormat(vform);
11915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
11925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
11935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for unsigned saturation.
11949e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    uint64_t ua = src1.UintLeftJustified(vform, i);
11959e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    uint64_t ub = src2.UintLeftJustified(vform, i);
11969e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    uint64_t ur = ua - ub;
11979e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    if (ub > ua) {
11985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUnsignedSat(i, false);
11995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
12005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for signed saturation.
12029e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_a = (ua >> 63) == 0;
12039e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_b = (ub >> 63) == 0;
12049e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool pos_r = (ur >> 63) == 0;
12055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // If the signs of the operands are different, and the sign of the first
12065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // operand doesn't match the result, there was an overflow.
12079e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    if ((pos_a != pos_b) && (pos_a != pos_r)) {
12089e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetSignedSat(i, pos_a);
12095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
12105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12119e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    dst.SetInt(vform, i, ur >> (64 - lane_size));
12125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::and_(VectorFormat vform,
12185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
12195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
12205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
12215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) & src2.Uint(vform, i));
12245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::orr(VectorFormat vform,
12305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
12325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
12335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) | src2.Uint(vform, i));
12365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::orn(VectorFormat vform,
12425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
12445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
12455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) | ~src2.Uint(vform, i));
12485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::eor(VectorFormat vform,
12545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
12565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
12575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) ^ src2.Uint(vform, i));
12605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::bic(VectorFormat vform,
12665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
12685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
12695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
12715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src1.Uint(vform, i) & ~src2.Uint(vform, i));
12725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::bic(VectorFormat vform,
12785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
12805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              uint64_t imm) {
12815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
12825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
12835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
12845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = src.Uint(vform, i) & ~imm;
12855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
12885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
12895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
12915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
12925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::bif(VectorFormat vform,
12955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
12965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
12975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
12985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
12995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand1 = dst.Uint(vform, i);
13015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand2 = ~src2.Uint(vform, i);
13025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand3 = src1.Uint(vform, i);
13035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
13045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result);
13055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
13065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
13075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::bit(VectorFormat vform,
13115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
13125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
13135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
13145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
13155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand1 = dst.Uint(vform, i);
13175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand2 = src2.Uint(vform, i);
13185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand3 = src1.Uint(vform, i);
13195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
13205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result);
13215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
13225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
13235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::bsl(VectorFormat vform,
13275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
13285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
13295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2) {
13305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
13315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand1 = src2.Uint(vform, i);
13335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand2 = dst.Uint(vform, i);
13345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t operand3 = src1.Uint(vform, i);
13355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
13365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result);
13375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
13385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
13395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sminmax(VectorFormat vform,
13435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
13445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
13455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
13465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  bool max) {
13475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
13485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
13495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t src1_val = src1.Int(vform, i);
13505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t src2_val = src2.Int(vform, i);
13515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t dst_val;
1352491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell    if (max) {
13535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
13545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
13555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
13565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
13575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetInt(vform, i, dst_val);
13585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
13595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
13605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smax(VectorFormat vform,
13645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
13655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
13665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
13675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sminmax(vform, dst, src1, src2, true);
13685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smin(VectorFormat vform,
13725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
13735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
13745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
13755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sminmax(vform, dst, src1, src2, false);
13765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
13775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
13795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sminmaxp(VectorFormat vform,
13805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
1381b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                   const LogicVRegister& src1,
1382b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                   const LogicVRegister& src2,
13835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   bool max) {
1384b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  int lanes = LaneCountFromFormat(vform);
1385b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  int64_t result[kMaxLanesPerVector];
1386b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  const LogicVRegister* src = &src1;
1387b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  for (int j = 0; j < 2; j++) {
1388b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    for (int i = 0; i < lanes; i += 2) {
1389b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      int64_t first_val = src->Int(vform, i);
1390b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      int64_t second_val = src->Int(vform, i + 1);
1391b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      int64_t dst_val;
1392b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      if (max) {
1393b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell        dst_val = (first_val > second_val) ? first_val : second_val;
1394b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      } else {
1395b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell        dst_val = (first_val < second_val) ? first_val : second_val;
1396b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      }
1397b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      VIXL_ASSERT(((i >> 1) + (j * lanes / 2)) < kMaxLanesPerVector);
1398b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      result[(i >> 1) + (j * lanes / 2)] = dst_val;
13995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
1400b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    src = &src2;
14015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
1402b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  dst.SetIntArray(vform, result);
14035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
14045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smaxp(VectorFormat vform,
14085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
14095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
14105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
1411b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return sminmaxp(vform, dst, src1, src2, true);
14125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sminp(VectorFormat vform,
14165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
14175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
14185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
1419b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return sminmaxp(vform, dst, src1, src2, false);
14205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addp(VectorFormat vform,
14245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
14255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
14265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(vform == kFormatD);
14275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14289e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  uint64_t dst_val = src.Uint(kFormat2D, 0) + src.Uint(kFormat2D, 1);
14295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
14309e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  dst.SetUint(vform, 0, dst_val);
14315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
14325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addv(VectorFormat vform,
14365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
14375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
14380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  VectorFormat vform_dst =
14390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
14405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int64_t dst_val = 0;
14435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst_val += src.Int(vform, i);
14455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
14465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform_dst);
14485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetInt(vform_dst, 0, dst_val);
14495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
14505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddlv(VectorFormat vform,
14545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
14555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
14560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  VectorFormat vform_dst =
14570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
14585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int64_t dst_val = 0;
14605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst_val += src.Int(vform, i);
14625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
14635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform_dst);
14655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetInt(vform_dst, 0, dst_val);
14665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
14675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddlv(VectorFormat vform,
14715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
14725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
14730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  VectorFormat vform_dst =
14740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
14755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t dst_val = 0;
14775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst_val += src.Uint(vform, i);
14795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
14805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform_dst);
14825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetUint(vform_dst, 0, dst_val);
14835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
14845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
14855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sminmaxv(VectorFormat vform,
14885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
14895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
14905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   bool max) {
14915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int64_t dst_val = max ? INT64_MIN : INT64_MAX;
14925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
14935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t src_val = src.Int(vform, i);
1494491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell    if (max) {
14955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src_val > dst_val) ? src_val : dst_val;
14965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
14975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src_val < dst_val) ? src_val : dst_val;
14985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
14995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
1500491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell  dst.ClearForWrite(ScalarFormatFromFormat(vform));
15015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetInt(vform, 0, dst_val);
15025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
15035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smaxv(VectorFormat vform,
15075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
15085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
15095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sminmaxv(vform, dst, src, true);
15105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
15115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sminv(VectorFormat vform,
15155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
15165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
15175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sminmaxv(vform, dst, src, false);
15185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
15195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uminmax(VectorFormat vform,
15235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
15245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
15255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
15265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  bool max) {
15275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
15285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
15295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src1_val = src1.Uint(vform, i);
15305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src2_val = src2.Uint(vform, i);
15315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t dst_val;
1532491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell    if (max) {
15335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src1_val > src2_val) ? src1_val : src2_val;
15345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
15355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src1_val < src2_val) ? src1_val : src2_val;
15365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
15375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, dst_val);
15385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
15405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umax(VectorFormat vform,
15445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
15455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
15465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
15475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return uminmax(vform, dst, src1, src2, true);
15485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umin(VectorFormat vform,
15525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
15535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
15545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
15555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return uminmax(vform, dst, src1, src2, false);
15565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uminmaxp(VectorFormat vform,
15605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
1561b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                   const LogicVRegister& src1,
1562b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                   const LogicVRegister& src2,
15635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   bool max) {
1564b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  int lanes = LaneCountFromFormat(vform);
1565b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  uint64_t result[kMaxLanesPerVector];
1566b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  const LogicVRegister* src = &src1;
1567b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  for (int j = 0; j < 2; j++) {
1568b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
1569b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      uint64_t first_val = src->Uint(vform, i);
1570b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      uint64_t second_val = src->Uint(vform, i + 1);
1571b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      uint64_t dst_val;
1572b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      if (max) {
1573b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell        dst_val = (first_val > second_val) ? first_val : second_val;
1574b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      } else {
1575b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell        dst_val = (first_val < second_val) ? first_val : second_val;
1576b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      }
1577b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      VIXL_ASSERT(((i >> 1) + (j * lanes / 2)) < kMaxLanesPerVector);
1578b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      result[(i >> 1) + (j * lanes / 2)] = dst_val;
15795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
1580b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    src = &src2;
15815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
1582b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  dst.SetUintArray(vform, result);
15835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
15845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umaxp(VectorFormat vform,
15885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
15895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
15905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
1591b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return uminmaxp(vform, dst, src1, src2, true);
15925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
15935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uminp(VectorFormat vform,
15965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
15975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
15985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
1599b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return uminmaxp(vform, dst, src1, src2, false);
16005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uminmaxv(VectorFormat vform,
16045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
16055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
16065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   bool max) {
16075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t dst_val = max ? 0 : UINT64_MAX;
16085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
16095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src_val = src.Uint(vform, i);
1610491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell    if (max) {
16115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src_val > dst_val) ? src_val : dst_val;
16125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
16135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst_val = (src_val < dst_val) ? src_val : dst_val;
16145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
16155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
1616491a575777fe21edc15bedd877a288a7f042bf48Martyn Capewell  dst.ClearForWrite(ScalarFormatFromFormat(vform));
16175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetUint(vform, 0, dst_val);
16185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
16195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umaxv(VectorFormat vform,
16235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
16245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
16255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uminmaxv(vform, dst, src, true);
16265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
16275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uminv(VectorFormat vform,
16315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
16325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
16335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uminmaxv(vform, dst, src, false);
16345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
16355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::shl(VectorFormat vform,
16395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
16405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
16415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int shift) {
16425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
16435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
16445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
16455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return ushl(vform, dst, src, shiftreg);
16465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sshll(VectorFormat vform,
16505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
16515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
16525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
16535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
16545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
16555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister extendedreg = sxtl(vform, temp2, src);
16575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshl(vform, dst, extendedreg, shiftreg);
16585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sshll2(VectorFormat vform,
16625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
16635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
16645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
16655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
16665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
16675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister extendedreg = sxtl2(vform, temp2, src);
16695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshl(vform, dst, extendedreg, shiftreg);
16705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::shll(VectorFormat vform,
16745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
16755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
16765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int shift = LaneSizeInBitsFromFormat(vform) / 2;
16775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshll(vform, dst, src, shift);
16785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::shll2(VectorFormat vform,
16825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
16835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
16845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int shift = LaneSizeInBitsFromFormat(vform) / 2;
16855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshll2(vform, dst, src, shift);
16865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
16895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ushll(VectorFormat vform,
16905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
16915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
16925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
16935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
16945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
16955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
16965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister extendedreg = uxtl(vform, temp2, src);
16975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return ushl(vform, dst, extendedreg, shiftreg);
16985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
16995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ushll2(VectorFormat vform,
17025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
17035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
17045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
17055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
17065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
17075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
17085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister extendedreg = uxtl2(vform, temp2, src);
17095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return ushl(vform, dst, extendedreg, shiftreg);
17105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sli(VectorFormat vform,
17145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
17155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
17165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int shift) {
17175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
17185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
17195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
17205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src_lane = src.Uint(vform, i);
17215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t dst_lane = dst.Uint(vform, i);
17225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t shifted = src_lane << shift;
17235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t mask = MaxUintFromFormat(vform) << shift;
17245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
17255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
17265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
17275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshl(VectorFormat vform,
17315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
17325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
17335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
17345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
17355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
17365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshl(vform, dst, src, shiftreg).SignedSaturate(vform);
17385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqshl(VectorFormat vform,
17425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
17435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
17445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
17455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
17465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
17475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return ushl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
17495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshlu(VectorFormat vform,
17535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
17545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
17555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
17565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
17575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
17585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
17595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
17605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sri(VectorFormat vform,
17645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
17655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
17665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int shift) {
17675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
17685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
17695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT((shift > 0) &&
17705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl              (shift <= static_cast<int>(LaneSizeInBitsFromFormat(vform))));
17715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
17725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src_lane = src.Uint(vform, i);
17735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t dst_lane = dst.Uint(vform, i);
17745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t shifted;
17755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t mask;
17765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (shift == 64) {
17775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      shifted = 0;
17785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      mask = 0;
17795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
17805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      shifted = src_lane >> shift;
17815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      mask = MaxUintFromFormat(vform) >> shift;
17825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
17835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
17845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
17855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
17865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ushr(VectorFormat vform,
17905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
17915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
17925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int shift) {
17935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
17945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
17955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
17965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return ushl(vform, dst, src, shiftreg);
17975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
17985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
17995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sshr(VectorFormat vform,
18015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
18025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
18035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int shift) {
18045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(shift >= 0);
18055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
18065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
18075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sshl(vform, dst, src, shiftreg);
18085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ssra(VectorFormat vform,
18125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
18135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
18145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int shift) {
18155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
18165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_reg = sshr(vform, temp, src, shift);
18175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, shifted_reg);
18185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usra(VectorFormat vform,
18225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
18235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
18245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int shift) {
18255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
18265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_reg = ushr(vform, temp, src, shift);
18275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, shifted_reg);
18285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::srsra(VectorFormat vform,
18325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
18335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
18345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
18355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
18365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_reg = sshr(vform, temp, src, shift).Round(vform);
18375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, shifted_reg);
18385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ursra(VectorFormat vform,
18425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
18435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
18445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
18455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
18465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_reg = ushr(vform, temp, src, shift).Round(vform);
18475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, shifted_reg);
18485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::cls(VectorFormat vform,
18525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
18535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
18545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
18550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
18565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
18575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
18585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = CountLeadingSignBits(src.Int(vform, i), laneSizeInBits);
18595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
18605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
18625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
18635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
18645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
18655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
18665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::clz(VectorFormat vform,
18705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
18715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
18725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
18730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
18745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
18755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
18765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = CountLeadingZeros(src.Uint(vform, i), laneSizeInBits);
18775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
18785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
18805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
18815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
18825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
18835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
18845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
18855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
18875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::cnt(VectorFormat vform,
18885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
18895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
18905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
18910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
18925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
18935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
18945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t value = src.Uint(vform, i);
18955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = 0;
18965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int j = 0; j < laneSizeInBits; j++) {
18975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result[i] += (value & 1);
18985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      value >>= 1;
18995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
19005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
19015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
19035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
19045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
19055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
19065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
19075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
19085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sshl(VectorFormat vform,
19115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
19125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
19135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
19145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
19155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
19165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int8_t shift_val = src2.Int(vform, i);
19175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t lj_src_val = src1.IntLeftJustified(vform, i);
19185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Set signed saturation state.
19200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    if ((shift_val > CountLeadingSignBits(lj_src_val)) && (lj_src_val != 0)) {
19215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetSignedSat(i, lj_src_val >= 0);
19225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
19235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Set unsigned saturation state.
19255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (lj_src_val < 0) {
19265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUnsignedSat(i, false);
19276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if ((shift_val > CountLeadingZeros(lj_src_val)) &&
19285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl               (lj_src_val != 0)) {
19295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUnsignedSat(i, true);
19305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
19315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t src_val = src1.Int(vform, i);
19339e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    bool src_is_negative = src_val < 0;
19345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (shift_val > 63) {
19355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, 0);
19365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else if (shift_val < -63) {
19379e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetRounding(i, src_is_negative);
19389e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetInt(vform, i, src_is_negative ? -1 : 0);
19395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
19409e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      // Use unsigned types for shifts, as behaviour is undefined for signed
19419e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      // lhs.
19429e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      uint64_t usrc_val = static_cast<uint64_t>(src_val);
19439e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell
19445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (shift_val < 0) {
19459e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        // Convert to right shift.
19469e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        shift_val = -shift_val;
19479e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell
19489e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        // Set rounding state by testing most-significant bit shifted out.
19499e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        // Rounding only needed on right shifts.
19509e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        if (((usrc_val >> (shift_val - 1)) & 1) == 1) {
19515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl          dst.SetRounding(i, true);
19525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        }
19539e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell
19549e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        usrc_val >>= shift_val;
19559e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell
19569e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        if (src_is_negative) {
19579e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell          // Simulate sign-extension.
19589e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell          usrc_val |= (~UINT64_C(0) << (64 - shift_val));
19599e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        }
19605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else {
19619e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        usrc_val <<= shift_val;
19625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
19639e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetUint(vform, i, usrc_val);
19645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
19655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
19665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
19675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
19685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ushl(VectorFormat vform,
19715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
19725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
19735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
19745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
19755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
19765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int8_t shift_val = src2.Int(vform, i);
19775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t lj_src_val = src1.UintLeftJustified(vform, i);
19785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Set saturation state.
19806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if ((shift_val > CountLeadingZeros(lj_src_val)) && (lj_src_val != 0)) {
19815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUnsignedSat(i, true);
19825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
19835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t src_val = src1.Uint(vform, i);
19855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if ((shift_val > 63) || (shift_val < -64)) {
19865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, 0);
19875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
19885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (shift_val < 0) {
19895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // Set rounding state. Rounding only needed on right shifts.
19905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        if (((src_val >> (-shift_val - 1)) & 1) == 1) {
19915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl          dst.SetRounding(i, true);
19925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        }
19935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        if (shift_val == -64) {
19955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl          src_val = 0;
19965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        } else {
19975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl          src_val >>= -shift_val;
19985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        }
19995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else {
20005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        src_val <<= shift_val;
20015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
20025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, src_val);
20035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
20055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
20065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
20075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::neg(VectorFormat vform,
20105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
20115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
20125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
20135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for signed saturation.
20155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t sa = src.Int(vform, i);
20165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sa == MinIntFromFormat(vform)) {
20175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetSignedSat(i, true);
20185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20199e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    dst.SetInt(vform, i, (sa == INT64_MIN) ? sa : -sa);
20205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
20215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
20225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
20235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::suqadd(VectorFormat vform,
20265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
20275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
20285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
20295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    int64_t sa = dst.IntLeftJustified(vform, i);
20315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t ub = src.UintLeftJustified(vform, i);
20329e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    uint64_t ur = sa + ub;
20335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20349e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    int64_t sr;
20359e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    memcpy(&sr, &ur, sizeof(sr));
20365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sr < sa) {  // Test for signed positive saturation.
20375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, MaxIntFromFormat(vform));
20385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
20399e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetUint(vform, i, dst.Int(vform, i) + src.Uint(vform, i));
20405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
20425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
20435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
20445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usqadd(VectorFormat vform,
20475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
20485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
20495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
20505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    uint64_t ua = dst.UintLeftJustified(vform, i);
20520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    int64_t sb = src.IntLeftJustified(vform, i);
20530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    uint64_t ur = ua + sb;
20545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if ((sb > 0) && (ur <= ua)) {
20565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, MaxUintFromFormat(vform));  // Positive saturation.
20575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else if ((sb < 0) && (ur >= ua)) {
20580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      dst.SetUint(vform, i, 0);  // Negative saturation.
20595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
20605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, dst.Uint(vform, i) + src.Int(vform, i));
20615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
20635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
20645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
20655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::abs(VectorFormat vform,
20685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
20695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
20705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
20715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
20725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for signed saturation.
20735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t sa = src.Int(vform, i);
20745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sa == MinIntFromFormat(vform)) {
20755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetSignedSat(i, true);
20765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sa < 0) {
20789e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      dst.SetInt(vform, i, (sa == INT64_MIN) ? sa : -sa);
20795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
20805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, sa);
20815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
20825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
20835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
20845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
20855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::extractnarrow(VectorFormat dstform,
20885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        LogicVRegister dst,
20895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        bool dstIsSigned,
20905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        const LogicVRegister& src,
20915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        bool srcIsSigned) {
20925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  bool upperhalf = false;
20935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat srcform = kFormatUndefined;
20940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int64_t ssrc[8];
20955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t usrc[8];
20965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  switch (dstform) {
20980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat8B:
20990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat8H;
21010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat16B:
21030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = true;
21040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat8H;
21050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat4H:
21070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat4S;
21090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat8H:
21110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = true;
21120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat4S;
21130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat2S:
21150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat2D;
21170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormat4S:
21190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = true;
21200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormat2D;
21210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormatB:
21230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormatH;
21250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormatH:
21270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormatS;
21290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    case kFormatS:
21310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      upperhalf = false;
21320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      srcform = kFormatD;
21330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      break;
21340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    default:
21350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VIXL_UNIMPLEMENTED();
21365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
21375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
21395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    ssrc[i] = src.Int(srcform, i);
21405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    usrc[i] = src.Uint(srcform, i);
21415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
21425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int offset;
21445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (upperhalf) {
21455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    offset = LaneCountFromFormat(dstform) / 2;
21465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
21475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    offset = 0;
21485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.ClearForWrite(dstform);
21495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
21505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
21525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for signed saturation
21535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (ssrc[i] > MaxIntFromFormat(dstform)) {
21545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetSignedSat(offset + i, true);
21555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else if (ssrc[i] < MinIntFromFormat(dstform)) {
21565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetSignedSat(offset + i, false);
21575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
21585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Test for unsigned saturation
21605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (srcIsSigned) {
21615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (ssrc[i] > static_cast<int64_t>(MaxUintFromFormat(dstform))) {
21625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        dst.SetUnsignedSat(offset + i, true);
21635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if (ssrc[i] < 0) {
21645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        dst.SetUnsignedSat(offset + i, false);
21655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
21665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
21675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (usrc[i] > MaxUintFromFormat(dstform)) {
21685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        dst.SetUnsignedSat(offset + i, true);
21695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
21705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
21715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t result;
21735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (srcIsSigned) {
21745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = ssrc[i] & MaxUintFromFormat(dstform);
21755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
21765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = usrc[i] & MaxUintFromFormat(dstform);
21775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
21785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (dstIsSigned) {
21805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(dstform, offset + i, result);
21815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
21825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(dstform, offset + i, result);
21835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
21845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
21855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
21865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
21875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::xtn(VectorFormat vform,
21905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
21915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src) {
21925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vform, dst, true, src, true);
21935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
21945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
21965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqxtn(VectorFormat vform,
21975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
21985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
21995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vform, dst, true, src, true).SignedSaturate(vform);
22005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqxtun(VectorFormat vform,
22045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
22055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
22065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vform, dst, false, src, true).UnsignedSaturate(vform);
22075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqxtn(VectorFormat vform,
22115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
22125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
22135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vform, dst, false, src, false).UnsignedSaturate(vform);
22145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::absdiff(VectorFormat vform,
22185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
22195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
22205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
22215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  bool issigned) {
22225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
22235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
22245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (issigned) {
22255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      int64_t sr = src1.Int(vform, i) - src2.Int(vform, i);
22265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      sr = sr > 0 ? sr : -sr;
22275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, sr);
22285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
22295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      int64_t sr = src1.Uint(vform, i) - src2.Uint(vform, i);
22305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      sr = sr > 0 ? sr : -sr;
22315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, sr);
22325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
22335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
22345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
22355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saba(VectorFormat vform,
22395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
22415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
22425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
22435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
22445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, temp, src1, src2, true);
22455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, dst, temp);
22465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
22475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaba(VectorFormat vform,
22515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
22535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
22545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
22555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
22565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, temp, src1, src2, false);
22575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, dst, temp);
22585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
22595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::not_(VectorFormat vform,
22635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
22655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
22665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
22675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, ~src.Uint(vform, i));
22685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
22695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
22705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rbit(VectorFormat vform,
22745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
22765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
22775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
22780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int laneSizeInBits = LaneSizeInBitsFromFormat(vform);
22795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t reversed_value;
22805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t value;
22815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i++) {
22825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    value = src.Uint(vform, i);
22835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    reversed_value = 0;
22845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int j = 0; j < laneSizeInBits; j++) {
22855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      reversed_value = (reversed_value << 1) | (value & 1);
22865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      value >>= 1;
22875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
22885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = reversed_value;
22895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
22905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
22925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
22935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
22945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
22955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
22965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
22975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
22995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rev(VectorFormat vform,
23005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
23015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
23025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int revSize) {
23035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
23045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
23055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneSize = LaneSizeInBytesFromFormat(vform);
23060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  int lanesPerLoop = revSize / laneSize;
23075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; i += lanesPerLoop) {
23085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int j = 0; j < lanesPerLoop; j++) {
23095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result[i + lanesPerLoop - 1 - j] = src.Uint(vform, i + j);
23105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
23115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
23125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
23135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
23145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
23155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
23165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
23175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rev16(VectorFormat vform,
23215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
23225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
23235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return rev(vform, dst, src, 2);
23245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rev32(VectorFormat vform,
23285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
23295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
23305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return rev(vform, dst, src, 4);
23315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rev64(VectorFormat vform,
23355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
23365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
23375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return rev(vform, dst, src, 8);
23385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addlp(VectorFormat vform,
23420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                LogicVRegister dst,
23430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src,
23440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                bool is_signed,
23450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                bool do_accumulate) {
23465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatHalfWidthDoubleLanes(vform);
23479e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  VIXL_ASSERT(LaneSizeInBitsFromFormat(vformsrc) <= 32);
23489e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  VIXL_ASSERT(LaneCountFromFormat(vform) <= 8);
23495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23509e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  uint64_t result[8];
23519e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  int lane_count = LaneCountFromFormat(vform);
23529e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  for (int i = 0; i < lane_count; i++) {
23535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (is_signed) {
23549e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      result[i] = static_cast<uint64_t>(src.Int(vformsrc, 2 * i) +
23559e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell                                        src.Int(vformsrc, 2 * i + 1));
23565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
23579e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      result[i] = src.Uint(vformsrc, 2 * i) + src.Uint(vformsrc, 2 * i + 1);
23585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
23595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
23605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
23629e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell  for (int i = 0; i < lane_count; ++i) {
23635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (do_accumulate) {
23649e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      result[i] += dst.Uint(vform, i);
23655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
23669e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    dst.SetUint(vform, i, result[i]);
23675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
23685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
23705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddlp(VectorFormat vform,
23745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
23755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
23765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return addlp(vform, dst, src, true, false);
23775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddlp(VectorFormat vform,
23815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
23825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
23835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return addlp(vform, dst, src, false, false);
23845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sadalp(VectorFormat vform,
23885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
23895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
23905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return addlp(vform, dst, src, true, true);
23915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
23945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uadalp(VectorFormat vform,
23955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
23965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
23975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return addlp(vform, dst, src, false, true);
23985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
23995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ext(VectorFormat vform,
24025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
24035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src1,
24045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src2,
24055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int index) {
24065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint8_t result[16];
24075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount - index; ++i) {
24095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = src1.Uint(vform, i + index);
24105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < index; ++i) {
24125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[laneCount - index + i] = src2.Uint(vform, i);
24135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
24155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
24165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
24175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::dup_element(VectorFormat vform,
24235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      LogicVRegister dst,
24245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      const LogicVRegister& src,
24255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      int src_index) {
24265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t value = src.Uint(vform, src_index);
24285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
24295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
24305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, value);
24315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::dup_immediate(VectorFormat vform,
24375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        LogicVRegister dst,
24385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        uint64_t imm) {
24395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t value = imm & MaxUintFromFormat(vform);
24415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
24425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
24435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, value);
24445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ins_element(VectorFormat vform,
24505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      LogicVRegister dst,
24515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      int dst_index,
24525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      const LogicVRegister& src,
24535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      int src_index) {
24545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetUint(vform, dst_index, src.Uint(vform, src_index));
24555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ins_immediate(VectorFormat vform,
24605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        LogicVRegister dst,
24615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        int dst_index,
24625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                        uint64_t imm) {
24635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t value = imm & MaxUintFromFormat(vform);
24645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetUint(vform, dst_index, value);
24655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::movi(VectorFormat vform,
24705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
24715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               uint64_t imm) {
24725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
24745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
24755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, imm);
24765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::mvni(VectorFormat vform,
24825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
24835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               uint64_t imm) {
24845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
24865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
24875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, ~imm);
24885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
24895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
24905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
24915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
24935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::orr(VectorFormat vform,
24945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
24955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& src,
24965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              uint64_t imm) {
24975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
24985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
24995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
25005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[i] = src.Uint(vform, i) | imm;
25015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
25035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
25045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
25055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
25075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uxtl(VectorFormat vform,
25115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
25125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
25135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
25145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
25165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
25175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src.Uint(vform_half, i));
25185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
25205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sxtl(VectorFormat vform,
25245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
25255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
25265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
25275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
25295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
25305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetInt(vform, i, src.Int(vform_half, i));
25315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
25335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uxtl2(VectorFormat vform,
25375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
25385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
25395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
25405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform);
25415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
25435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < lane_count; i++) {
25445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, src.Uint(vform_half, lane_count + i));
25455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
25475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sxtl2(VectorFormat vform,
25515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
25525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
25535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_half = VectorFormatHalfWidth(vform);
25545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform);
25555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
25575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < lane_count; i++) {
25585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetInt(vform, i, src.Int(vform_half, lane_count + i));
25595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
25605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
25615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::shrn(VectorFormat vform,
25655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
25665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
25675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int shift) {
25685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
25695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_src = VectorFormatDoubleWidth(vform);
25705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vform_dst = vform;
25715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = ushr(vform_src, temp, src, shift);
25725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vform_dst, dst, false, shifted_src, false);
25735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::shrn2(VectorFormat vform,
25775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
25785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
25795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
25805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
25815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
25825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
25835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift);
25845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
25855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rshrn(VectorFormat vform,
25895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
25905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
25915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int shift) {
25925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
25935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
25945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
25955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
25965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
25975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
25985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
25995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rshrn2(VectorFormat vform,
26015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
26025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
26035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
26045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
26055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
26065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
26075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
26085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return extractnarrow(vformdst, dst, false, shifted_src, false);
26095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2612b953ea8255b36e27834f17941429cd17af12f6f2Martyn CapewellLogicVRegister Simulator::Table(VectorFormat vform,
2613b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                LogicVRegister dst,
2614b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                const LogicVRegister& ind,
2615b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                bool zero_out_of_bounds,
2616b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                const LogicVRegister* tab1,
2617b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                const LogicVRegister* tab2,
2618b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                const LogicVRegister* tab3,
2619b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                                const LogicVRegister* tab4) {
2620b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  VIXL_ASSERT(tab1 != NULL);
2621b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  const LogicVRegister* tab[4] = {tab1, tab2, tab3, tab4};
2622b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  uint64_t result[kMaxLanesPerVector];
2623b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2624b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    result[i] = zero_out_of_bounds ? 0 : dst.Uint(kFormat16B, i);
2625b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  }
2626b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2627b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    uint64_t j = ind.Uint(vform, i);
2628b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    int tab_idx = static_cast<int>(j >> 4);
2629b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    int j_idx = static_cast<int>(j & 15);
2630b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    if ((tab_idx < 4) && (tab[tab_idx] != NULL)) {
2631b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      result[i] = tab[tab_idx]->Uint(kFormat16B, j_idx);
2632b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    }
2633b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  }
2634b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  dst.SetUintArray(vform, result);
2635b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return dst;
2636b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell}
2637b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell
2638b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell
26395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbl(VectorFormat vform,
26405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2643b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, true, &tab);
26445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbl(VectorFormat vform,
26485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
26515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2652b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, true, &tab, &tab2);
26535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbl(VectorFormat vform,
26575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
26605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab3,
26615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2662b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, true, &tab, &tab2, &tab3);
26635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbl(VectorFormat vform,
26675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
26705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab3,
26715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab4,
26725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2673b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, true, &tab, &tab2, &tab3, &tab4);
26745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2681b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, false, &tab);
26825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
26895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2690b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, false, &tab, &tab2);
26915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
26925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
26945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbx(VectorFormat vform,
26955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
26965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
26975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
26985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab3,
26995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2700b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, false, &tab, &tab2, &tab3);
27015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::tbx(VectorFormat vform,
27055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              LogicVRegister dst,
27065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab,
27075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab2,
27085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab3,
27095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& tab4,
27105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              const LogicVRegister& ind) {
2711b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  return Table(vform, dst, ind, false, &tab, &tab2, &tab3, &tab4);
27125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqshrn(VectorFormat vform,
27165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
27175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
27185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
27195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return shrn(vform, dst, src, shift).UnsignedSaturate(vform);
27205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqshrn2(VectorFormat vform,
27245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
27255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src,
27265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int shift) {
27275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return shrn2(vform, dst, src, shift).UnsignedSaturate(vform);
27285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqrshrn(VectorFormat vform,
27325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
27335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src,
27345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int shift) {
27355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return rshrn(vform, dst, src, shift).UnsignedSaturate(vform);
27365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uqrshrn2(VectorFormat vform,
27405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
27415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
27425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   int shift) {
27435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return rshrn2(vform, dst, src, shift).UnsignedSaturate(vform);
27445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshrn(VectorFormat vform,
27485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
27495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
27505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 int shift) {
27515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
27525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
27535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
27545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
27555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtn(vformdst, dst, shifted_src);
27565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshrn2(VectorFormat vform,
27605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
27615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src,
27625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int shift) {
27635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
27645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
27665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
27675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtn(vformdst, dst, shifted_src);
27685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrshrn(VectorFormat vform,
27725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
27735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src,
27745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int shift) {
27755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
27765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
27775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
27785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtn(vformdst, dst, shifted_src);
27805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrshrn2(VectorFormat vform,
27845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
27855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
27865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   int shift) {
27875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
27885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
27895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
27905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
27915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtn(vformdst, dst, shifted_src);
27925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
27935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
27955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshrun(VectorFormat vform,
27965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
27975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src,
27985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  int shift) {
27995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
28015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
28025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
28035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtun(vformdst, dst, shifted_src);
28045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqshrun2(VectorFormat vform,
28085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
28095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
28105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   int shift) {
28115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
28135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
28145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
28155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtun(vformdst, dst, shifted_src);
28165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrshrun(VectorFormat vform,
28205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
28215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
28225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   int shift) {
28235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
28255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
28265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
28275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtun(vformdst, dst, shifted_src);
28285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrshrun2(VectorFormat vform,
28325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    LogicVRegister dst,
28335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    const LogicVRegister& src,
28345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    int shift) {
28355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
28375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VectorFormat vformdst = vform;
28385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
28395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqxtun(vformdst, dst, shifted_src);
28405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddl(VectorFormat vform,
28445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
28455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
28465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
28475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
28485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
28495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
28505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, temp1, temp2);
28515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
28525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddl2(VectorFormat vform,
28565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
28575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
28585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
28595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
28605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
28615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
28625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, temp1, temp2);
28635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
28645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddw(VectorFormat vform,
28685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
28695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
28705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
28715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp, src2);
28735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, src1, temp);
28745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
28755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uaddw2(VectorFormat vform,
28795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
28805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
28815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
28825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
28835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp, src2);
28845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, src1, temp);
28855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
28865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddl(VectorFormat vform,
28905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
28915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
28925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
28935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
28945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
28955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
28965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, temp1, temp2);
28975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
28985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
28995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddl2(VectorFormat vform,
29025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
29035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
29045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
29055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
29065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
29075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
29085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, temp1, temp2);
29095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddw(VectorFormat vform,
29145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
29155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
29165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
29175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
29185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp, src2);
29195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, src1, temp);
29205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::saddw2(VectorFormat vform,
29255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
29265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
29275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
29285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
29295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp, src2);
29305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(vform, dst, src1, temp);
29315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usubl(VectorFormat vform,
29365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
29375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
29385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
29395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
29405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
29415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
29425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, temp1, temp2);
29435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usubl2(VectorFormat vform,
29485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
29495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
29505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
29515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
29525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
29535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
29545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, temp1, temp2);
29555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usubw(VectorFormat vform,
29605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
29615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
29625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
29635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
29645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp, src2);
29655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, src1, temp);
29665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::usubw2(VectorFormat vform,
29715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
29725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
29735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
29745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
29755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp, src2);
29765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, src1, temp);
29775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ssubl(VectorFormat vform,
29825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
29835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
29845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
29855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
29865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
29875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
29885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, temp1, temp2);
29895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
29905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
29915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ssubl2(VectorFormat vform,
29945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
29955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
29965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
29975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
29985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
29995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
30005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, temp1, temp2);
30015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ssubw(VectorFormat vform,
30065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
30075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
30085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
30095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
30105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp, src2);
30115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, src1, temp);
30125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ssubw2(VectorFormat vform,
30175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
30185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
30195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
30205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
30215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp, src2);
30225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(vform, dst, src1, temp);
30235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uabal(VectorFormat vform,
30285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
30295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
30305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
30315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
30335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
30345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uaba(vform, dst, temp1, temp2);
30355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uabal2(VectorFormat vform,
30405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
30415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
30425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
30435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
30455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
30465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uaba(vform, dst, temp1, temp2);
30475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sabal(VectorFormat vform,
30525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
30535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
30545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
30555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
30575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
30585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  saba(vform, dst, temp1, temp2);
30595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sabal2(VectorFormat vform,
30645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
30655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
30665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
30675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
30695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
30705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  saba(vform, dst, temp1, temp2);
30715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uabdl(VectorFormat vform,
30765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
30775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
30785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
30795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
30815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
30825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, dst, temp1, temp2, false);
30835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uabdl2(VectorFormat vform,
30885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
30895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
30905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
30915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
30925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
30935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
30945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, dst, temp1, temp2, false);
30955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
30965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
30975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sabdl(VectorFormat vform,
31005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
31015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
31025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
31035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
31055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
31065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, dst, temp1, temp2, true);
31075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sabdl2(VectorFormat vform,
31125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
31135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
31145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
31155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
31175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
31185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  absdiff(vform, dst, temp1, temp2, true);
31195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umull(VectorFormat vform,
31245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
31255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
31265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
31275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
31295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
31305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, dst, temp1, temp2);
31315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umull2(VectorFormat vform,
31365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
31375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
31385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
31395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
31415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
31425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, dst, temp1, temp2);
31435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smull(VectorFormat vform,
31485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
31495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
31505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
31515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
31535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
31545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, dst, temp1, temp2);
31555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smull2(VectorFormat vform,
31605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
31615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
31625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
31635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
31655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
31665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mul(vform, dst, temp1, temp2);
31675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlsl(VectorFormat vform,
31725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
31735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
31745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
31755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
31775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
31785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mls(vform, dst, temp1, temp2);
31795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlsl2(VectorFormat vform,
31845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
31855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
31865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
31875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
31885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
31895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
31905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mls(vform, dst, temp1, temp2);
31915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
31925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
31935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlsl(VectorFormat vform,
31965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
31975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
31985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
31995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
32015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
32025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mls(vform, dst, temp1, temp2);
32035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlsl2(VectorFormat vform,
32085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
32095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
32105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
32115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
32135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
32145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mls(vform, dst, temp1, temp2);
32155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlal(VectorFormat vform,
32205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
32215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
32225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
32235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp1, src1);
32255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl(vform, temp2, src2);
32265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mla(vform, dst, temp1, temp2);
32275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::umlal2(VectorFormat vform,
32325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
32335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
32345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
32355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp1, src1);
32375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uxtl2(vform, temp2, src2);
32385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mla(vform, dst, temp1, temp2);
32395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlal(VectorFormat vform,
32445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
32455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
32465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
32475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp1, src1);
32495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl(vform, temp2, src2);
32505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mla(vform, dst, temp1, temp2);
32515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::smlal2(VectorFormat vform,
32565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
32575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
32585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
32595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
32605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp1, src1);
32615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sxtl2(vform, temp2, src2);
32625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  mla(vform, dst, temp1, temp2);
32635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
32645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlal(VectorFormat vform,
32685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
32695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
32705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
32715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
32725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = sqdmull(vform, temp, src1, src2);
32735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, product).SignedSaturate(vform);
32745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlal2(VectorFormat vform,
32780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
32790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
32800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2) {
32815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
32825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = sqdmull2(vform, temp, src1, src2);
32835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, dst, product).SignedSaturate(vform);
32845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlsl(VectorFormat vform,
32885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
32895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
32905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
32915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
32925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = sqdmull(vform, temp, src1, src2);
32935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sub(vform, dst, dst, product).SignedSaturate(vform);
32945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
32955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
32975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
32980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
32990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
33000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2) {
33015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = sqdmull2(vform, temp, src1, src2);
33035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sub(vform, dst, dst, product).SignedSaturate(vform);
33045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmull(VectorFormat vform,
33085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
33095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
33105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
33115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = smull(vform, temp, src1, src2);
33135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, product, product).SignedSaturate(vform);
33145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmull2(VectorFormat vform,
33180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   LogicVRegister dst,
33190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src1,
33200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                   const LogicVRegister& src2) {
33215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = smull2(vform, temp, src1, src2);
33235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return add(vform, dst, product, product).SignedSaturate(vform);
33245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqrdmulh(VectorFormat vform,
33285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
33295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src1,
33305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src2,
33315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   bool round) {
33325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // 2 * INT_32_MIN * INT_32_MIN causes int64_t to overflow.
33335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // To avoid this, we use (src1 * src2 + 1 << (esize - 2)) >> (esize - 1)
33345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // which is same as (2 * src1 * src2 + 1 << (esize - 1)) >> esize.
33355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int esize = LaneSizeInBitsFromFormat(vform);
33375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int round_const = round ? (1 << (esize - 2)) : 0;
33385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int64_t product;
33395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
33415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
33425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    product = src1.Int(vform, i) * src2.Int(vform, i);
33435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    product += round_const;
33445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    product = product >> (esize - 1);
33455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (product > MaxIntFromFormat(vform)) {
33475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      product = MaxIntFromFormat(vform);
33485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else if (product < MinIntFromFormat(vform)) {
33495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      product = MinIntFromFormat(vform);
33505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
33515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetInt(vform, i, product);
33525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
33535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
33545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::sqdmulh(VectorFormat vform,
33585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
33595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
33605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
33615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return sqrdmulh(vform, dst, src1, src2, false);
33625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addhn(VectorFormat vform,
33665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
33675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
33685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
33695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(VectorFormatDoubleWidth(vform), temp, src1, src2);
33715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
33735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::addhn2(VectorFormat vform,
33775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
33785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
33795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
33805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
33825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
33845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::raddhn(VectorFormat vform,
33885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
33895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
33905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
33915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
33925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(VectorFormatDoubleWidth(vform), temp, src1, src2);
33935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
33945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
33955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
33965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
33985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::raddhn2(VectorFormat vform,
33995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
34005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
34015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
34025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
34035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
34045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
34055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::subhn(VectorFormat vform,
34105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
34115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
34125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
34135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
34145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
34155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
34165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::subhn2(VectorFormat vform,
34215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
34225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
34235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
34245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
34255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
34265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
34275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rsubhn(VectorFormat vform,
34325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
34335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
34345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
34355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
34365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
34375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
34385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::rsubhn2(VectorFormat vform,
34435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
34445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
34455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
34465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
34475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
34485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
34495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::trn1(VectorFormat vform,
34545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
34555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
34565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
34575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
34585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
34595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int pairs = laneCount / 2;
34605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < pairs; ++i) {
34610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[2 * i] = src1.Uint(vform, 2 * i);
34625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[(2 * i) + 1] = src2.Uint(vform, 2 * i);
34635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
34645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
34665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
34675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
34685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
34695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::trn2(VectorFormat vform,
34745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
34755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
34765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
34775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
34785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
34795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int pairs = laneCount / 2;
34805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < pairs; ++i) {
34810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[2 * i] = src1.Uint(vform, (2 * i) + 1);
34825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[(2 * i) + 1] = src2.Uint(vform, (2 * i) + 1);
34835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
34845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
34865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
34875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
34885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
34895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
34905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
34915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
34935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::zip1(VectorFormat vform,
34945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
34955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
34965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
34975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
34985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
34995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int pairs = laneCount / 2;
35005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < pairs; ++i) {
35010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[2 * i] = src1.Uint(vform, i);
35025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[(2 * i) + 1] = src2.Uint(vform, i);
35035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
35065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
35085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
35105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
35115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::zip2(VectorFormat vform,
35145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
35155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
35165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
35175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[16];
35185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
35195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int pairs = laneCount / 2;
35205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < pairs; ++i) {
35210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[2 * i] = src1.Uint(vform, pairs + i);
35225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[(2 * i) + 1] = src2.Uint(vform, pairs + i);
35235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
35265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[i]);
35285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
35305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
35315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uzp1(VectorFormat vform,
35345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
35355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
35365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
35375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[32];
35385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
35395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[i] = src1.Uint(vform, i);
35415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[laneCount + i] = src2.Uint(vform, i);
35425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
35455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result[2 * i]);
35475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
35495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
35505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::uzp2(VectorFormat vform,
35535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
35545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
35555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
35565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t result[32];
35575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int laneCount = LaneCountFromFormat(vform);
35585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    result[i] = src1.Uint(vform, i);
35605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    result[laneCount + i] = src2.Uint(vform, i);
35615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
35645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < laneCount; ++i) {
35650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.SetUint(vform, i, result[(2 * i) + 1]);
35665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
35685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
35695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
35725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPAdd(T op1, T op2) {
35735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs(op1, op2);
35746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(result)) return result;
35755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
35775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // inf + -inf returns the default NaN.
35785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
35795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
35805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
35815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Other cases should be handled by standard arithmetic.
35825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return op1 + op2;
35835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
35845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
35855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
35885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPSub(T op1, T op2) {
35895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // NaNs should be handled elsewhere.
35906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
35915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
35926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
35935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // inf - inf returns the default NaN.
35945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
35955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
35965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
35975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Other cases should be handled by standard arithmetic.
35985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return op1 - op2;
35995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
36015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
36045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMul(T op1, T op2) {
36055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // NaNs should be handled elsewhere.
36066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
36075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
36095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // inf * 0.0 returns the default NaN.
36105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
36115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
36125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
36135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Other cases should be handled by standard arithmetic.
36145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return op1 * op2;
36155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
36175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T>
36205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMulx(T op1, T op2) {
36216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
36225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // inf * 0.0 returns +/-2.0.
36235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T two = 2.0;
36245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return copysign(1.0, op1) * copysign(1.0, op2) * two;
36255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return FPMul(op1, op2);
36275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
36285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T>
36315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMulAdd(T a, T op1, T op2) {
36325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs3(a, op1, op2);
36335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T sign_a = copysign(1.0, a);
36355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
36366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  bool isinf_prod = std::isinf(op1) || std::isinf(op2);
36375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  bool operation_generates_nan =
36386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      (std::isinf(op1) && (op2 == 0.0)) ||                     // inf * 0.0
36396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      (std::isinf(op2) && (op1 == 0.0)) ||                     // 0.0 * inf
36406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      (std::isinf(a) && isinf_prod && (sign_a != sign_prod));  // inf - inf
36415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(result)) {
36435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Generated NaNs override quiet NaNs propagated from a.
36445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (operation_generates_nan && IsQuietNaN(a)) {
36455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      FPProcessException();
36465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return FPDefaultNaN<T>();
36475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
36485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return result;
36495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
36505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // If the operation would produce a NaN, return the default NaN.
36535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (operation_generates_nan) {
36545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
36555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
36565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Work around broken fma implementations for exact zero results: The sign of
36595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // exact 0.0 results is positive unless both a and op1 * op2 are negative.
36605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
36615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
36625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  result = FusedMultiplyAdd(op1, op2, a);
36656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(!std::isnan(result));
36665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Work around broken fma implementations for rounded zero results: If a is
36685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
36695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if ((a == 0.0) && (result == 0.0)) {
36705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return copysign(0.0, sign_prod);
36715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return result;
36745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
36755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
36785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPDiv(T op1, T op2) {
36795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // NaNs should be handled elsewhere.
36806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
36815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36826e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
36835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // inf / inf and 0.0 / 0.0 return the default NaN.
36845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
36855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
36865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
36879e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    if (op2 == 0.0) {
36889e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      FPProcessException();
36899e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      if (!std::isnan(op1)) {
36909e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        double op1_sign = copysign(1.0, op1);
36919e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        double op2_sign = copysign(1.0, op2);
36929e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell        return static_cast<T>(op1_sign * op2_sign * kFP64PositiveInfinity);
36939e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell      }
36949e52d5becfa81b6b819cdc0350693c3ad6b95b1dMartyn Capewell    }
36955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
36965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Other cases should be handled by standard arithmetic.
36975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return op1 / op2;
36985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
36995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPSqrt(T op) {
37046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(op)) {
37055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPProcessNaN(op);
37065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (op < 0.0) {
37075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
37085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
37095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
37105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return sqrt(op);
37115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMax(T a, T b) {
37175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs(a, b);
37186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(result)) return result;
37195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if ((a == 0.0) && (b == 0.0) && (copysign(1.0, a) != copysign(1.0, b))) {
37215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // a and b are zero, and the sign differs: return +0.0.
37225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 0.0;
37235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
37245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (a > b) ? a : b;
37255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMaxNM(T a, T b) {
37315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
37325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    a = kFP64NegativeInfinity;
37335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
37345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    b = kFP64NegativeInfinity;
37355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs(a, b);
37386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(result) ? result : FPMax(a, b);
37395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMin(T a, T b) {
37445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs(a, b);
37456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(result)) return result;
37465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if ((a == 0.0) && (b == 0.0) && (copysign(1.0, a) != copysign(1.0, b))) {
37485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // a and b are zero, and the sign differs: return -0.0.
37495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return -0.0;
37505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
37515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (a < b) ? a : b;
37525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPMinNM(T a, T b) {
37585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
37595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    a = kFP64PositiveInfinity;
37605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
37615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    b = kFP64PositiveInfinity;
37625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T result = FPProcessNaNs(a, b);
37656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(result) ? result : FPMin(a, b);
37665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPRecipStepFused(T op1, T op2) {
37715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  const T two = 2.0;
37720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if ((std::isinf(op1) && (op2 == 0.0)) ||
37730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      ((op1 == 0.0) && (std::isinf(op2)))) {
37745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return two;
37756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else if (std::isinf(op1) || std::isinf(op2)) {
37765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Return +inf if signs match, otherwise -inf.
37775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
37785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                          : kFP64NegativeInfinity;
37795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
37805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FusedMultiplyAdd(op1, op2, two);
37815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
37825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
37835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
37865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPRSqrtStepFused(T op1, T op2) {
37875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  const T one_point_five = 1.5;
37885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  const T two = 2.0;
37895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
37900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  if ((std::isinf(op1) && (op2 == 0.0)) ||
37910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      ((op1 == 0.0) && (std::isinf(op2)))) {
37925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return one_point_five;
37936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else if (std::isinf(op1) || std::isinf(op2)) {
37945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Return +inf if signs match, otherwise -inf.
37955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
37965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                          : kFP64NegativeInfinity;
37975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
37985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // The multiply-add-halve operation must be fully fused, so avoid interim
37995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // rounding by checking which operand can be losslessly divided by two
38005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // before doing the multiply-add.
38016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (std::isnormal(op1 / two)) {
38025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return FusedMultiplyAdd(op1 / two, op2, one_point_five);
38036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnormal(op2 / two)) {
38045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return FusedMultiplyAdd(op1, op2 / two, one_point_five);
38055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
38065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // Neither operand is normal after halving: the result is dominated by
38075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // the addition term, so just return that.
38085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return one_point_five;
38095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
38115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
38125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixldouble Simulator::FPRoundInt(double value, FPRounding round_mode) {
38155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
38165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      (value == kFP64NegativeInfinity)) {
38175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return value;
38186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else if (std::isnan(value)) {
38195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPProcessNaN(value);
38205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
38215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  double int_result = std::floor(value);
38235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double error = value - int_result;
38245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  switch (round_mode) {
38255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    case FPTieAway: {
38265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // Take care of correctly handling the range ]-0.5, -0.0], which must
38275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // yield -0.0.
38285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if ((-0.5 < value) && (value < 0.0)) {
38295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result = -0.0;
38305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
38325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // If the error is greater than 0.5, or is equal to 0.5 and the integer
38335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // result is positive, round up.
38345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result++;
38355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
38365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      break;
38375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    case FPTieEven: {
38395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // Take care of correctly handling the range [-0.5, -0.0], which must
38405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // yield -0.0.
38415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if ((-0.5 <= value) && (value < 0.0)) {
38425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result = -0.0;
38435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        // If the error is greater than 0.5, or is equal to 0.5 and the integer
38450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        // result is odd, round up.
38465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if ((error > 0.5) ||
38470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 ((error == 0.5) && (std::fmod(int_result, 2) != 0))) {
38485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result++;
38495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
38505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      break;
38515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    case FPZero: {
38535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // If value>0 then we take floor(value)
38545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // otherwise, ceil(value).
38555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (value < 0) {
38560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        int_result = ceil(value);
38575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
38585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      break;
38595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    case FPNegativeInfinity: {
38615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // We always use floor(value).
38625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      break;
38635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    case FPPositiveInfinity: {
38655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // Take care of correctly handling the range ]-1.0, -0.0], which must
38665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // yield -0.0.
38675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if ((-1.0 < value) && (value < 0.0)) {
38685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result = -0.0;
38695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        // If the error is non-zero, round up.
38715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if (error > 0.0) {
38725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        int_result++;
38735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
38745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      break;
38755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
38760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    default:
38770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VIXL_UNIMPLEMENTED();
38785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
38795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return int_result;
38805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
38815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlint32_t Simulator::FPToInt32(double value, FPRounding rmode) {
38845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  value = FPRoundInt(value, rmode);
38855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (value >= kWMaxInt) {
38865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kWMaxInt;
38875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (value < kWMinInt) {
38885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kWMinInt;
38895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
38906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(value) ? 0 : static_cast<int32_t>(value);
38915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
38925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
38945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlint64_t Simulator::FPToInt64(double value, FPRounding rmode) {
38955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  value = FPRoundInt(value, rmode);
38965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (value >= kXMaxInt) {
38975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kXMaxInt;
38985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (value < kXMinInt) {
38995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kXMinInt;
39005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
39016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(value) ? 0 : static_cast<int64_t>(value);
39025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
39035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixluint32_t Simulator::FPToUInt32(double value, FPRounding rmode) {
39065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  value = FPRoundInt(value, rmode);
39075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (value >= kWMaxUInt) {
39085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kWMaxUInt;
39095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (value < 0.0) {
39105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 0;
39115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
39126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(value) ? 0 : static_cast<uint32_t>(value);
39135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
39145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixluint64_t Simulator::FPToUInt64(double value, FPRounding rmode) {
39175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  value = FPRoundInt(value, rmode);
39185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (value >= kXMaxUInt) {
39195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return kXMaxUInt;
39205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (value < 0.0) {
39215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 0;
39225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
39236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  return std::isnan(value) ? 0 : static_cast<uint64_t>(value);
39245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
39255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl#define DEFINE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                \
39280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>                                          \
39290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister Simulator::FN(VectorFormat vform,               \
39300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               LogicVRegister dst,               \
39310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               const LogicVRegister& src1,       \
39320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               const LogicVRegister& src2) {     \
39330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.ClearForWrite(vform);                                    \
39340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {       \
39350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      T op1 = src1.Float<T>(i);                                  \
39360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      T op2 = src2.Float<T>(i);                                  \
39370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      T result;                                                  \
39380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      if (PROCNAN) {                                             \
39390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        result = FPProcessNaNs(op1, op2);                        \
39400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        if (!std::isnan(result)) {                               \
39410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = OP(op1, op2);                                 \
39420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        }                                                        \
39430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      } else {                                                   \
39445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        result = OP(op1, op2);                                   \
39455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }                                                          \
39460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      dst.SetFloat(i, result);                                   \
39475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }                                                            \
39480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    return dst;                                                  \
39495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }                                                              \
39505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                                 \
39510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister Simulator::FN(VectorFormat vform,               \
39520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               LogicVRegister dst,               \
39530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               const LogicVRegister& src1,       \
39540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               const LogicVRegister& src2) {     \
39550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {          \
39560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      FN<float>(vform, dst, src1, src2);                         \
39570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    } else {                                                     \
39580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize); \
39590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      FN<double>(vform, dst, src1, src2);                        \
39600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    }                                                            \
39610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    return dst;                                                  \
39620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  }
39635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlNEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)
39645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl#undef DEFINE_NEON_FP_VECTOR_OP
39655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fnmul(VectorFormat vform,
39685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
39695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
39705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2) {
39715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
39725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister product = fmul(vform, temp, src1, src2);
39735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return fneg(vform, dst, product);
39745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
39755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
39785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frecps(VectorFormat vform,
39795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
39805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
39815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
39825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
39835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
39845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op1 = -src1.Float<T>(i);
39855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op2 = src2.Float<T>(i);
39865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result = FPProcessNaNs(op1, op2);
39876e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    dst.SetFloat(i, std::isnan(result) ? result : FPRecipStepFused(op1, op2));
39885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
39895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
39905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
39915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
39935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frecps(VectorFormat vform,
39945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
39955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src1,
39965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src2) {
39975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
39985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frecps<float>(vform, dst, src1, src2);
39995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
40005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frecps<double>(vform, dst, src1, src2);
40025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
40035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
40045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
40055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
40085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frsqrts(VectorFormat vform,
40095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
40105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
40115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
40125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
40135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
40145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op1 = -src1.Float<T>(i);
40155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op2 = src2.Float<T>(i);
40165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result = FPProcessNaNs(op1, op2);
40176e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    dst.SetFloat(i, std::isnan(result) ? result : FPRSqrtStepFused(op1, op2));
40185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
40195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
40205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
40215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frsqrts(VectorFormat vform,
40245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
40255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
40265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2) {
40275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frsqrts<float>(vform, dst, src1, src2);
40295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
40305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frsqrts<double>(vform, dst, src1, src2);
40325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
40335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
40345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
40355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
40385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcmp(VectorFormat vform,
40395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
40405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
40415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2,
40425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               Condition cond) {
40435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
40445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
40455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    bool result = false;
40465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op1 = src1.Float<T>(i);
40475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op2 = src2.Float<T>(i);
40485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T nan_result = FPProcessNaNs(op1, op2);
40496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (!std::isnan(nan_result)) {
40505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      switch (cond) {
40510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case eq:
40520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = (op1 == op2);
40530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case ge:
40550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = (op1 >= op2);
40560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case gt:
40580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = (op1 > op2);
40590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case le:
40610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = (op1 <= op2);
40620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        case lt:
40640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          result = (op1 < op2);
40650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        default:
40670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          VIXL_UNREACHABLE();
40680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          break;
40695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
40705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
40715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
40725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
40735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
40745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
40755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcmp(VectorFormat vform,
40785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
40795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
40805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2,
40815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               Condition cond) {
40825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
40835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<float>(vform, dst, src1, src2, cond);
40845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
40855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
40865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<double>(vform, dst, src1, src2, cond);
40875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
40885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
40895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
40905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
40925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcmp_zero(VectorFormat vform,
40935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    LogicVRegister dst,
40945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    const LogicVRegister& src,
40955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                    Condition cond) {
40965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
40975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
409888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    LogicVRegister zero_reg = dup_immediate(vform, temp, FloatToRawbits(0.0));
40995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<float>(vform, dst, src, zero_reg, cond);
41005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
41015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
410288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    LogicVRegister zero_reg = dup_immediate(vform, temp, DoubleToRawbits(0.0));
41035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<double>(vform, dst, src, zero_reg, cond);
41045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fabscmp(VectorFormat vform,
41105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
41115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src1,
41125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src2,
41135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  Condition cond) {
41145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp1, temp2;
41155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister abs_src1 = fabs_<float>(vform, temp1, src1);
41175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister abs_src2 = fabs_<float>(vform, temp2, src2);
41185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<float>(vform, dst, abs_src1, abs_src2, cond);
41195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
41205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister abs_src1 = fabs_<double>(vform, temp1, src1);
41225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister abs_src2 = fabs_<double>(vform, temp2, src2);
41235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fcmp<double>(vform, dst, abs_src1, abs_src2, cond);
41245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
41305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmla(VectorFormat vform,
41315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
41325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
41335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
41345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
41355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op1 = src1.Float<T>(i);
41375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op2 = src2.Float<T>(i);
41385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T acc = dst.Float<T>(i);
41395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result = FPMulAdd(acc, op1, op2);
41405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, result);
41415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmla(VectorFormat vform,
41475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
41485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
41495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
41505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmla<float>(vform, dst, src1, src2);
41525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
41535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmla<double>(vform, dst, src1, src2);
41555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
41615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmls(VectorFormat vform,
41625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
41635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
41645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
41655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
41665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op1 = -src1.Float<T>(i);
41685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op2 = src2.Float<T>(i);
41695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T acc = dst.Float<T>(i);
41705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result = FPMulAdd(acc, op1, op2);
41715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, result);
41725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmls(VectorFormat vform,
41785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
41795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
41805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
41815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
41825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmls<float>(vform, dst, src1, src2);
41835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
41845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
41855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmls<double>(vform, dst, src1, src2);
41865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
41875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
41885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
41895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
41915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
41925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fneg(VectorFormat vform,
41935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
41945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
41955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
41965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
41975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op = src.Float<T>(i);
41985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    op = -op;
41995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, op);
42005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
42015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fneg(VectorFormat vform,
42065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
42075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src) {
42085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
42095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fneg<float>(vform, dst, src);
42105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
42115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
42125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fneg<double>(vform, dst, src);
42135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
42145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
42195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fabs_(VectorFormat vform,
42205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
42215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
42225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
42235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
42245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op = src.Float<T>(i);
42255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (copysign(1.0, op) < 0.0) {
42265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      op = -op;
42275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
42285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, op);
42295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
42305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fabs_(VectorFormat vform,
42355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
42365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
42375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
42385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fabs_<float>(vform, dst, src);
42395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
42405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
42415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fabs_<double>(vform, dst, src);
42425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
42435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fabd(VectorFormat vform,
42485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
42495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
42505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2) {
42515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
42525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  fsub(vform, temp, src1, src2);
42535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  fabs_(vform, dst, temp);
42545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fsqrt(VectorFormat vform,
42595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
42605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
42615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
42625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
42635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
42645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float result = FPSqrt(src.Float<float>(i));
42655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, result);
42665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
42675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
42685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
42695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
42705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double result = FPSqrt(src.Float<double>(i));
42715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, result);
42725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
42735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
42745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
42755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
42765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
42780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DEFINE_NEON_FP_PAIR_OP(FNP, FN, OP)                           \
42790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister Simulator::FNP(VectorFormat vform,                   \
42800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                LogicVRegister dst,                   \
42810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src1,           \
42820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src2) {         \
42830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    SimVRegister temp1, temp2;                                        \
42840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    uzp1(vform, temp1, src1, src2);                                   \
42850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    uzp2(vform, temp2, src1, src2);                                   \
42860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    FN(vform, dst, temp1, temp2);                                     \
42870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    return dst;                                                       \
42880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  }                                                                   \
42890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                                                      \
42900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister Simulator::FNP(VectorFormat vform,                   \
42910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                LogicVRegister dst,                   \
42920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                const LogicVRegister& src) {          \
42930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    if (vform == kFormatS) {                                          \
42940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      float result = OP(src.Float<float>(0), src.Float<float>(1));    \
42950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      dst.SetFloat(0, result);                                        \
42960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    } else {                                                          \
42970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      VIXL_ASSERT(vform == kFormatD);                                 \
42980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      double result = OP(src.Float<double>(0), src.Float<double>(1)); \
42990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      dst.SetFloat(0, result);                                        \
43000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    }                                                                 \
43010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    dst.ClearForWrite(vform);                                         \
43020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    return dst;                                                       \
43030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  }
43045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlNEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)
43055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl#undef DEFINE_NEON_FP_PAIR_OP
43065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fminmaxv(VectorFormat vform,
43095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   LogicVRegister dst,
43105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   const LogicVRegister& src,
43115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                   FPMinMaxOp Op) {
43125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(vform == kFormat4S);
43135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  USE(vform);
43145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float result1 = (this->*Op)(src.Float<float>(0), src.Float<float>(1));
43155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float result2 = (this->*Op)(src.Float<float>(2), src.Float<float>(3));
43165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float result = (this->*Op)(result1, result2);
43175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(kFormatS);
43185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.SetFloat<float>(0, result);
43195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
43205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmaxv(VectorFormat vform,
43245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
43255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
43265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return fminmaxv(vform, dst, src, &Simulator::FPMax);
43275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fminv(VectorFormat vform,
43315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
43325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
43335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return fminmaxv(vform, dst, src, &Simulator::FPMin);
43345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmaxnmv(VectorFormat vform,
43380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                  LogicVRegister dst,
43390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                                  const LogicVRegister& src) {
43405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return fminmaxv(vform, dst, src, &Simulator::FPMaxNM);
43415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fminnmv(VectorFormat vform,
43455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
43465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src) {
43475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return fminmaxv(vform, dst, src, &Simulator::FPMinNM);
43485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmul(VectorFormat vform,
43525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
43535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
43545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2,
43555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int index) {
43565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
43575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
43585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
43605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmul<float>(vform, dst, src1, index_reg);
43615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
43635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
43655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmul<double>(vform, dst, src1, index_reg);
43665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
43675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
43685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmla(VectorFormat vform,
43725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
43735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
43745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2,
43755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int index) {
43765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
43775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
43785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
43805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmla<float>(vform, dst, src1, index_reg);
43815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
43835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
43845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
43855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmla<double>(vform, dst, src1, index_reg);
43865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
43875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
43885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
43895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
43915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmls(VectorFormat vform,
43925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
43935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src1,
43945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src2,
43955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int index) {
43965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
43975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
43985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
43995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
44005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmls<float>(vform, dst, src1, index_reg);
44015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
44035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
44055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmls<double>(vform, dst, src1, index_reg);
44065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
44075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
44085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
44095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fmulx(VectorFormat vform,
44125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
44135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src1,
44145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src2,
44155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int index) {
44165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
44175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister temp;
44185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
44205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmulx<float>(vform, dst, src1, index_reg);
44215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
44235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
44255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    fmulx<double>(vform, dst, src1, index_reg);
44265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
44275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
44285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
44295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frint(VectorFormat vform,
44325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
44335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
44345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                FPRounding rounding_mode,
44355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                bool inexact_exception) {
44365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
44375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float input = src.Float<float>(i);
44405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float rounded = FPRoundInt(input, rounding_mode);
44416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (inexact_exception && !std::isnan(input) && (input != rounded)) {
44425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        FPProcessException();
44435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
44445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<float>(i, rounded);
44455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
44465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
44475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double input = src.Float<double>(i);
44505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double rounded = FPRoundInt(input, rounding_mode);
44516e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (inexact_exception && !std::isnan(input) && (input != rounded)) {
44525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        FPProcessException();
44535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
44545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<double>(i, rounded);
44555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
44565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
44575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
44585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
44595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvts(VectorFormat vform,
44625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
44635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
44645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                FPRounding rounding_mode,
44655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int fbits) {
44665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
44675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      float op = src.Float<float>(i) * std::pow(2.0f, fbits);
44705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, FPToInt32(op, rounding_mode));
44715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
44725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
44735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      double op = src.Float<double>(i) * std::pow(2.0, fbits);
44765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetInt(vform, i, FPToInt64(op, rounding_mode));
44775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
44785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
44795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
44805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
44815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
44835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtu(VectorFormat vform,
44845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
44855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
44865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                FPRounding rounding_mode,
44875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int fbits) {
44885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
44895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
44905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      float op = src.Float<float>(i) * std::pow(2.0f, fbits);
44925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, FPToUInt32(op, rounding_mode));
44935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
44945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
44955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
44965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
44976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      double op = src.Float<double>(i) * std::pow(2.0, fbits);
44985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetUint(vform, i, FPToUInt64(op, rounding_mode));
44995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtl(VectorFormat vform,
45065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
45075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
45085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
45095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
45105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToFloat(src.Float<float16>(i)));
45115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
45135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
45145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
45155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToDouble(src.Float<float>(i)));
45165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtl2(VectorFormat vform,
45235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
45245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
45255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform);
45265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
45275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < lane_count; i++) {
45285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToFloat(src.Float<float16>(i + lane_count)));
45295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
45315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
45325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < lane_count; i++) {
45335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToDouble(src.Float<float>(i + lane_count)));
45345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtn(VectorFormat vform,
45415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
45425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src) {
45435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
45445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
45455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToFloat16(src.Float<float>(i), FPTieEven));
45465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
45485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
45505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPTieEven));
45515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtn2(VectorFormat vform,
45585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
45595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
45605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform) / 2;
45615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
45625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = lane_count - 1; i >= 0; i--) {
45635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i + lane_count, FPToFloat16(src.Float<float>(i), FPTieEven));
45645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
45665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = lane_count - 1; i >= 0; i--) {
45685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPTieEven));
45695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
45705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtxn(VectorFormat vform,
45765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
45775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
45785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
45795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
45815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, FPToFloat(src.Float<double>(i), FPRoundOdd));
45825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::fcvtxn2(VectorFormat vform,
45885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
45895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src) {
45905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
45915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int lane_count = LaneCountFromFormat(vform) / 2;
45925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = lane_count - 1; i >= 0; i--) {
45935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i + lane_count, FPToFloat(src.Float<double>(i), FPRoundOdd));
45945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
45955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
45965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
45975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
45995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Based on reference C function recip_sqrt_estimate from ARM ARM.
46005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixldouble Simulator::recip_sqrt_estimate(double a) {
46015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int q0, q1, s;
46025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double r;
46035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (a < 0.5) {
46045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    q0 = static_cast<int>(a * 512.0);
46055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
46060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  } else {
46075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    q1 = static_cast<int>(a * 256.0);
46085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
46095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
46105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  s = static_cast<int>(256.0 * r + 0.5);
46115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return static_cast<double>(s) / 256.0;
46125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
46135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlstatic inline uint64_t Bits(uint64_t val, int start_bit, int end_bit) {
461688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  return ExtractUnsignedBitfield64(start_bit, end_bit, val);
46175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
46185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
46215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPRecipSqrtEstimate(T op) {
46226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(op)) {
46235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPProcessNaN(op);
46245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (op == 0.0) {
46255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (copysign(1.0, op) < 0.0) {
46265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return kFP64NegativeInfinity;
46275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
46285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return kFP64PositiveInfinity;
46295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (copysign(1.0, op) < 0.0) {
46315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();
46325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPDefaultNaN<T>();
46336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else if (std::isinf(op)) {
46345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 0.0;
46355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
46365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t fraction;
46375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int exp, result_exp;
46385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
464088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      exp = FloatExp(op);
464188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      fraction = FloatMantissa(op);
46425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      fraction <<= 29;
46435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
464488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      exp = DoubleExp(op);
464588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      fraction = DoubleMantissa(op);
46465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (exp == 0) {
46495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      while (Bits(fraction, 51, 51) == 0) {
46505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        fraction = Bits(fraction, 50, 0) << 1;
46515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        exp -= 1;
46525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
46535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      fraction = Bits(fraction, 50, 0) << 1;
46545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    double scaled;
46575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (Bits(exp, 0, 0) == 0) {
465888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      scaled = DoublePack(0, 1022, Bits(fraction, 51, 44) << 44);
46595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
466088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      scaled = DoublePack(0, 1021, Bits(fraction, 51, 44) << 44);
46615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
46645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result_exp = (380 - exp) / 2;
46655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
46665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result_exp = (3068 - exp) / 2;
46675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
466988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    uint64_t estimate = DoubleToRawbits(recip_sqrt_estimate(scaled));
46705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4672db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4673db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      uint32_t est_bits = static_cast<uint32_t>(Bits(estimate, 51, 29));
467488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return FloatPack(0, exp_bits, est_bits);
46755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
467688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return DoublePack(0, Bits(result_exp, 10, 0), Bits(estimate, 51, 0));
46775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
46795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
46805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
46825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frsqrte(VectorFormat vform,
46835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
46845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src) {
46855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
46865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
46875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
46885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float input = src.Float<float>(i);
46895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPRecipSqrtEstimate<float>(input));
46905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
46925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
46935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
46945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double input = src.Float<double>(i);
46955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPRecipSqrtEstimate<double>(input));
46965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
46975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
46985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
46995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
47005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
47025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlT Simulator::FPRecipEstimate(T op, FPRounding rounding) {
47035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint32_t sign;
47045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
470688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    sign = FloatSign(op);
47075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
470888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    sign = DoubleSign(op);
47095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
47105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (std::isnan(op)) {
47125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return FPProcessNaN(op);
47136e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else if (std::isinf(op)) {
47145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (sign == 1) ? -0.0 : 0.0;
47155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (op == 0.0) {
47165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();  // FPExc_DivideByZero exception.
47175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
47185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else if (((sizeof(T) == sizeof(float)) &&  // NOLINT(runtime/sizeof)
47196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl              (std::fabs(op) < std::pow(2.0, -128.0))) ||
47205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl             ((sizeof(T) == sizeof(double)) &&  // NOLINT(runtime/sizeof)
47216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl              (std::fabs(op) < std::pow(2.0, -1024.0)))) {
47225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    bool overflow_to_inf = false;
47235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (rounding) {
47240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case FPTieEven:
47250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        overflow_to_inf = true;
47260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
47270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case FPPositiveInfinity:
47280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        overflow_to_inf = (sign == 0);
47290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
47300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case FPNegativeInfinity:
47310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        overflow_to_inf = (sign == 1);
47320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
47330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case FPZero:
47340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        overflow_to_inf = false;
47350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
47360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
47370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
47385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    FPProcessException();  // FPExc_Overflow and FPExc_Inexact.
47405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (overflow_to_inf) {
47415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
47425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
47435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // Return FPMaxNormal(sign).
47445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
474588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return FloatPack(sign, 0xfe, 0x07fffff);
47465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else {
474788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return DoublePack(sign, 0x7fe, 0x0fffffffffffffl);
47485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
47495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
47515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t fraction;
47525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int exp, result_exp;
47535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint32_t sign;
47545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
475688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      sign = FloatSign(op);
475788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      exp = FloatExp(op);
475888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      fraction = FloatMantissa(op);
47595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      fraction <<= 29;
47605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
476188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      sign = DoubleSign(op);
476288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      exp = DoubleExp(op);
476388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      fraction = DoubleMantissa(op);
47645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (exp == 0) {
47675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (Bits(fraction, 51, 51) == 0) {
47685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        exp -= 1;
47695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        fraction = Bits(fraction, 49, 0) << 2;
47705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else {
47715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        fraction = Bits(fraction, 50, 0) << 1;
47725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
47735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
477588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    double scaled = DoublePack(0, 1022, Bits(fraction, 51, 44) << 44);
47765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
47780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      result_exp = (253 - exp);        // In range 253-254 = -1 to 253+1 = 254.
47795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
47805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result_exp = (2045 - exp);  // In range 2045-2046 = -1 to 2045+1 = 2046.
47815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
47835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    double estimate = recip_estimate(scaled);
47845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
478588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    fraction = DoubleMantissa(estimate);
47865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (result_exp == 0) {
47876e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      fraction = (UINT64_C(1) << 51) | Bits(fraction, 51, 1);
47885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else if (result_exp == -1) {
47896e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      fraction = (UINT64_C(1) << 50) | Bits(fraction, 51, 2);
47905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result_exp = 0;
47915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4793db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4794db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      uint32_t frac_bits = static_cast<uint32_t>(Bits(fraction, 51, 29));
479588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return FloatPack(sign, exp_bits, frac_bits);
47965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
479788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      return DoublePack(sign, Bits(result_exp, 10, 0), Bits(fraction, 51, 0));
47985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
47995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
48005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
48015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frecpe(VectorFormat vform,
48045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
48055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src,
48065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 FPRounding round) {
48075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
48085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
48095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float input = src.Float<float>(i);
48115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPRecipEstimate<float>(input, round));
48125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
48135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
48145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
48155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double input = src.Float<double>(i);
48175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat(i, FPRecipEstimate<double>(input, round));
48185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
48195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
48205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
48215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
48225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ursqrte(VectorFormat vform,
48255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  LogicVRegister dst,
48265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                  const LogicVRegister& src) {
48275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
4828db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  uint64_t operand;
4829db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  uint32_t result;
48305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double dp_operand, dp_result;
48315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    operand = src.Uint(vform, i);
48335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (operand <= 0x3FFFFFFF) {
48345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = 0xFFFFFFFF;
48355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
48366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      dp_operand = operand * std::pow(2.0, -32);
48376e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      dp_result = recip_sqrt_estimate(dp_operand) * std::pow(2.0, 31);
48385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = static_cast<uint32_t>(dp_result);
48395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
48405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result);
48415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
48425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
48435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
48445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Based on reference C function recip_estimate from ARM ARM.
48475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixldouble Simulator::recip_estimate(double a) {
48485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int q, s;
48495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double r;
48505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  q = static_cast<int>(a * 512.0);
48515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
48525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  s = static_cast<int>(256.0 * r + 0.5);
48535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return static_cast<double>(s) / 256.0;
48545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
48555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::urecpe(VectorFormat vform,
48585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
48595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
48605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
4861db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  uint64_t operand;
4862db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl  uint32_t result;
48635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double dp_operand, dp_result;
48645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    operand = src.Uint(vform, i);
48665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (operand <= 0x7FFFFFFF) {
48675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = 0xFFFFFFFF;
48685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
48696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      dp_operand = operand * std::pow(2.0, -32);
48706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      dp_result = recip_estimate(dp_operand) * std::pow(2.0, 31);
48715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      result = static_cast<uint32_t>(dp_result);
48725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
48735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetUint(vform, i, result);
48745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
48755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
48765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
48775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
48785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixltemplate <typename T>
48795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frecpx(VectorFormat vform,
48805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
48815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
48825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  dst.ClearForWrite(vform);
48835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
48845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T op = src.Float<T>(i);
48855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result;
48866e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (std::isnan(op)) {
48870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      result = FPProcessNaN(op);
48885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
48895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      int exp;
48905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      uint32_t sign;
48915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
489288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        sign = FloatSign(op);
489388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        exp = FloatExp(op);
4894db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        exp = (exp == 0) ? (0xFF - 1) : static_cast<int>(Bits(~exp, 7, 0));
489588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        result = FloatPack(sign, exp, 0);
48965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else {
489788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        sign = DoubleSign(op);
489888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        exp = DoubleExp(op);
4899db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        exp = (exp == 0) ? (0x7FF - 1) : static_cast<int>(Bits(~exp, 10, 0));
490088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        result = DoublePack(sign, exp, 0);
49015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
49025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
49035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    dst.SetFloat(i, result);
49045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
49055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
49065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
49075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::frecpx(VectorFormat vform,
49105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 LogicVRegister dst,
49115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                 const LogicVRegister& src) {
49125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
49135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frecpx<float>(vform, dst, src);
49145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  } else {
49155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
49165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    frecpx<double>(vform, dst, src);
49175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
49185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
49195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
49205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::scvtf(VectorFormat vform,
49225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
49235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
49245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int fbits,
49255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                FPRounding round) {
49265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
49275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
49285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float result = FixedToFloat(src.Int(kFormatS, i), fbits, round);
49295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<float>(i, result);
49305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
49315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
49325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double result = FixedToDouble(src.Int(kFormatD, i), fbits, round);
49335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<double>(i, result);
49345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
49355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
49365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
49375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
49385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlLogicVRegister Simulator::ucvtf(VectorFormat vform,
49415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                LogicVRegister dst,
49425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                const LogicVRegister& src,
49435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                int fbits,
49445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                FPRounding round) {
49455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  for (int i = 0; i < LaneCountFromFormat(vform); i++) {
49465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
49475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      float result = UFixedToFloat(src.Uint(kFormatS, i), fbits, round);
49485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<float>(i, result);
49495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    } else {
49505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
49515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      double result = UFixedToDouble(src.Uint(kFormatD, i), fbits, round);
49525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      dst.SetFloat<double>(i, result);
49535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
49545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
49555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  return dst;
49565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}
49575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
49585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
495988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}  // namespace aarch64
49605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl}  // namespace vixl
4961684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
49621e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
4963