1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2015, VIXL authors
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved.
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met:
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions of source code must retain the above copyright notice,
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer.
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer in the documentation
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     and/or other materials provided with the distribution.
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     used to endorse or promote products derived from this software without
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     specific prior written permission.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
27d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#ifndef VIXL_AARCH64_SIMULATOR_AARCH64_H_
28d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#define VIXL_AARCH64_SIMULATOR_AARCH64_H_
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
30b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "../globals-vixl.h"
31b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "../utils-vixl.h"
32b68bacb75c1ab265fc539afa93964c7f51f35589Alexandre Rames
33b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "abi-aarch64.h"
34b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "disasm-aarch64.h"
35b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "instructions-aarch64.h"
36b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "instrument-aarch64.h"
37b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "simulator-constants-aarch64.h"
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
39a4055d25c688d1397fc369a40abf57fa4f1ab805Pierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
40a4055d25c688d1397fc369a40abf57fa4f1ab805Pierre Langlois
41064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// These are only used for the ABI feature, and depend on checks performed for
42064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// it.
43ca73ba046c11d65b6dce59cfd26847d14aba06abAlexandre Rames#ifdef VIXL_HAS_ABI_SUPPORT
44064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#include <tuple>
45064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#if __cplusplus >= 201402L
46064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// Required for `std::index_sequence`
47064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#include <utility>
48064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
49064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
50064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
5288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch64 {
53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// Assemble the specified IEEE-754 components into the target type and apply
556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// appropriate rounding.
566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//  sign:     0 = positive, 1 = negative
576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//  exponent: Unbiased IEEE-754 exponent.
586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//  mantissa: The mantissa of the input. The top bit (which is not encoded for
596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//            normal IEEE-754 values) must not be omitted. This bit has the
606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//            value 'pow(2, exponent)'.
616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//
626e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// The input value is assumed to be a normalized value. That is, the input may
636e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// not be infinity or NaN. If the source value is subnormal, it must be
646e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// normalized before calling this function such that the highest set bit in the
656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// mantissa has the value 'pow(2, exponent)'.
666e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl//
676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl// calling a templated FPRound.
696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixltemplate <class T, int ebits, int mbits>
700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlT FPRound(int64_t sign,
710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          int64_t exponent,
720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          uint64_t mantissa,
730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          FPRounding round_mode) {
746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT((sign == 0) || (sign == 1));
756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Only FPTieEven and FPRoundOdd rounding modes are implemented.
776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT((round_mode == FPTieEven) || (round_mode == FPRoundOdd));
786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Rounding can promote subnormals to normals, and normals to infinities. For
806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // encodable as a float, but rounding based on the low-order mantissa bits
826e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // could make it overflow. With ties-to-even rounding, this value would become
836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // an infinity.
846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // ---- Rounding Method ----
866e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //
876e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // The exponent is irrelevant in the rounding operation, so we treat the
886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // lowest-order bit that will fit into the result ('onebit') as having
896e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // the value '1'. Similarly, the highest-order bit that won't fit into
906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // the result ('halfbit') has the value '0.5'. The 'point' sits between
916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // 'onebit' and 'halfbit':
926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //
936e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //            These bits fit into the result.
946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //               |---------------------|
956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                                     ||
976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                                    / |
986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                                   /  halfbit
996e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                               onebit
1006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //
1016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // For subnormal outputs, the range of representable bits is smaller and
1026e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // the position of onebit and halfbit depends on the exponent of the
1036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // input, but the method is otherwise similar.
1046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //
1056e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //   onebit(frac)
1066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //     |
1076e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //     | halfbit(frac)          halfbit(adjusted)
1086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //     | /                      /
1096e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //     | |                      |
1106e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b00.0 (exact)      -> 0b00.0 (exact)                    -> 0b00
1116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b00.0...           -> 0b00.0...                         -> 0b00
1126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b00.1 (exact)      -> 0b00.0111..111                    -> 0b00
1136e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b00.1...           -> 0b00.1...                         -> 0b01
1146e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b01.0 (exact)      -> 0b01.0 (exact)                    -> 0b01
1156e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b01.0...           -> 0b01.0...                         -> 0b01
1166e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b01.1 (exact)      -> 0b01.1 (exact)                    -> 0b10
1176e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b01.1...           -> 0b01.1...                         -> 0b10
1186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b10.0 (exact)      -> 0b10.0 (exact)                    -> 0b10
1196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b10.0...           -> 0b10.0...                         -> 0b10
1206e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b10.1 (exact)      -> 0b10.0111..111                    -> 0b10
1216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b10.1...           -> 0b10.1...                         -> 0b11
1226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  0b11.0 (exact)      -> 0b11.0 (exact)                    -> 0b11
1236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //  ...                   /             |                      /   |
1246e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                       /              |                     /    |
1256e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                                                           /     |
1266e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // adjusted = frac - (halfbit(mantissa) & ~onebit(frac));   /      |
1276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //
1286e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  //                   mantissa = (mantissa >> shift) + halfbit(adjusted);
1296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1306e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static const int mantissa_offset = 0;
1316e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static const int exponent_offset = mantissa_offset + mbits;
1326e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static const int sign_offset = exponent_offset + ebits;
1336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  VIXL_ASSERT(sign_offset == (sizeof(T) * 8 - 1));
1346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Bail out early for zero inputs.
1366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (mantissa == 0) {
137db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    return static_cast<T>(sign << sign_offset);
1386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // If all bits in the exponent are set, the value is infinite or NaN.
1416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // This is true for all binary IEEE-754 formats.
1426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static const int infinite_exponent = (1 << ebits) - 1;
1436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static const int max_normal_exponent = infinite_exponent - 1;
1446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Apply the exponent bias to encode it for the result. Doing this early makes
1466e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // it easy to detect values that will be infinite or subnormal.
1476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  exponent += max_normal_exponent >> 1;
1486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (exponent > max_normal_exponent) {
1506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // Overflow: the input is too large for the result type to represent.
1516e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (round_mode == FPTieEven) {
1526e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // FPTieEven rounding mode handles overflows using infinities.
1536e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      exponent = infinite_exponent;
1546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa = 0;
1556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else {
1566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(round_mode == FPRoundOdd);
1576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // FPRoundOdd rounding mode handles overflows using the largest magnitude
1586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // normal number.
1596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      exponent = max_normal_exponent;
1606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      mantissa = (UINT64_C(1) << exponent_offset) - 1;
1616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
162db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    return static_cast<T>((sign << sign_offset) |
163db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                          (exponent << exponent_offset) |
164db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                          (mantissa << mantissa_offset));
1656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
1666e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Calculate the shift required to move the top mantissa bit to the proper
1686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // place in the destination type.
1696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  const int highest_significant_bit = 63 - CountLeadingZeros(mantissa);
1706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  int shift = highest_significant_bit - mbits;
1716e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (exponent <= 0) {
1736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // The output will be subnormal (before rounding).
1746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // For subnormal outputs, the shift must be adjusted by the exponent. The +1
1756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // is necessary because the exponent of a subnormal value (encoded as 0) is
1766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // the same as the exponent of the smallest normal value (encoded as 1).
1776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    shift += -exponent + 1;
1786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // Handle inputs that would produce a zero output.
1806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    //
1816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // Shifts higher than highest_significant_bit+1 will always produce a zero
1826e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // result. A shift of exactly highest_significant_bit+1 might produce a
1836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // non-zero result after rounding.
1846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (shift > (highest_significant_bit + 1)) {
1856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (round_mode == FPTieEven) {
1866e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        // The result will always be +/-0.0.
187db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        return static_cast<T>(sign << sign_offset);
1886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      } else {
1896e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        VIXL_ASSERT(round_mode == FPRoundOdd);
1906e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        VIXL_ASSERT(mantissa != 0);
1916e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        // For FPRoundOdd, if the mantissa is too small to represent and
1926e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        // non-zero return the next "odd" value.
193db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        return static_cast<T>((sign << sign_offset) | 1);
1946e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
1956e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
1966e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
1976e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // Properly encode the exponent for a subnormal output.
1986e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    exponent = 0;
1996e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else {
2006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // Clear the topmost mantissa bit, since this is not encoded in IEEE-754
2016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // normal values.
2026e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    mantissa &= ~(UINT64_C(1) << highest_significant_bit);
2036e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
2046e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2056e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  if (shift > 0) {
2066e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (round_mode == FPTieEven) {
2076e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // We have to shift the mantissa to the right. Some precision is lost, so
2086e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // we need to apply rounding.
2096e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t onebit_mantissa = (mantissa >> (shift)) & 1;
2100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1;
2116e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa);
2126e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t adjusted = mantissa - adjustment;
2130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      T halfbit_adjusted = (adjusted >> (shift - 1)) & 1;
2146e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      T result =
2160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl          static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) |
2170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                         ((mantissa >> shift) << mantissa_offset));
2186e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2196e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // A very large mantissa can overflow during rounding. If this happens,
2206e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // the exponent should be incremented and the mantissa set to 1.0
2216e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // (encoded as 0). Applying halfbit_adjusted after assembling the float
2226e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // has the nice side-effect that this case is handled for free.
2236e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      //
2246e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // This also handles cases where a very large finite value overflows to
2256e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // infinity, or where a very large subnormal value overflows to become
2266e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // normal.
2276e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return result + halfbit_adjusted;
2286e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else {
2296e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(round_mode == FPRoundOdd);
2306e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // If any bits at position halfbit or below are set, onebit (ie. the
2316e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      // bottom bit of the resulting mantissa) must be set.
2326e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1);
2336e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      if (fractional_bits != 0) {
2346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        mantissa |= UINT64_C(1) << shift;
2356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      }
2366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
237db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      return static_cast<T>((sign << sign_offset) |
238db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                            (exponent << exponent_offset) |
239db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                            ((mantissa >> shift) << mantissa_offset));
2406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
2416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  } else {
2426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // We have to shift the mantissa to the left (or not at all). The input
2436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // mantissa is exactly representable in the output mantissa, so apply no
2446e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    // rounding correction.
245db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    return static_cast<T>((sign << sign_offset) |
246db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                          (exponent << exponent_offset) |
247db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl                          ((mantissa << -shift) << mantissa_offset));
2486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
2496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl}
2506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
2515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Representation of memory, with typed getters and setters for access.
2535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlclass Memory {
2545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl public:
2555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
2565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  static T AddressUntag(T address) {
2575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Cast the address using a C-style cast. A reinterpret_cast would be
2585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // appropriate, but it can't cast one integral type to another.
2595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t bits = (uint64_t)address;
2605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (T)(bits & ~kAddressTagMask);
2615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
2625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T, typename A>
2645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  static T Read(A address) {
2655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T value;
2665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    address = AddressUntag(address);
2675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
2685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                (sizeof(value) == 4) || (sizeof(value) == 8) ||
2695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                (sizeof(value) == 16));
2700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value));
2715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return value;
2725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
2735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T, typename A>
2755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  static void Write(A address, T value) {
2765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    address = AddressUntag(address);
2775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
2785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                (sizeof(value) == 4) || (sizeof(value) == 8) ||
2795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                (sizeof(value) == 16));
2800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    memcpy(reinterpret_cast<char*>(address), &value, sizeof(value));
2815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
2825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl};
2835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Represent a register (r0-r31, v0-v31).
2850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <int kSizeInBytes>
2865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlclass SimRegisterBase {
2875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl public:
2885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimRegisterBase() : written_since_last_log_(false) {}
2895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
2905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Write the specified value. The value is zero-extended if necessary.
2910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void Write(T new_value) {
2935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_STATIC_ASSERT(sizeof(new_value) <= kSizeInBytes);
2945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (sizeof(new_value) < kSizeInBytes) {
2955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      // All AArch64 registers are zero-extending.
2965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value));
2975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
2985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    memcpy(value_, &new_value, sizeof(new_value));
2995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    NotifyRegisterWrite();
3005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("Write", void Set(T new_value)) {
30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    Write(new_value);
30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
3055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Insert a typed value into a register, leaving the rest of the register
3075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // unchanged. The lane parameter indicates where in the register the value
3085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where
3095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // 0 represents the least significant bits.
3100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
3115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void Insert(int lane, T new_value) {
3125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(lane >= 0);
3130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    VIXL_ASSERT((sizeof(new_value) + (lane * sizeof(new_value))) <=
3140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                kSizeInBytes);
3155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    memcpy(&value_[lane * sizeof(new_value)], &new_value, sizeof(new_value));
3165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    NotifyRegisterWrite();
3175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
3185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Get the value as the specified type. The value is truncated if necessary.
32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T Get() const {
32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return GetLane<T>(0);
32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Get the lane value as the specified type. The value is truncated if
32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // necessary.
3270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T GetLane(int lane) const {
3295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result;
3305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(lane >= 0);
3315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT((sizeof(result) + (lane * sizeof(result))) <= kSizeInBytes);
3325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    memcpy(&result, &value_[lane * sizeof(result)], sizeof(result));
3335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return result;
3345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("GetLane", T Get(int lane) const) {
33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return GetLane(lane);
33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
3395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // TODO: Make this return a map of updated bytes, so that we can highlight
3415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // updated lanes for load-and-insert. (That never happens for scalar code, but
3425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // NEON has some instructions that can update individual lanes.)
3430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  bool WrittenSinceLastLog() const { return written_since_last_log_; }
3445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void NotifyRegisterLogged() { written_since_last_log_ = false; }
3465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl protected:
3485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint8_t value_[kSizeInBytes];
3495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Helpers to aid with register tracing.
3515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  bool written_since_last_log_;
3525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void NotifyRegisterWrite() { written_since_last_log_ = true; }
3545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl};
3550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltypedef SimRegisterBase<kXRegSizeInBytes> SimRegister;   // r0-r31
3560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltypedef SimRegisterBase<kQRegSizeInBytes> SimVRegister;  // v0-v31
3575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// Representation of a vector register, with typed getters and setters for lanes
3595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// and additional information to represent lane state.
3605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixlclass LogicVRegister {
3615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl public:
36260241a544be0ebf48347789bf0ec268414364627Vincent Belliard  inline LogicVRegister(
36360241a544be0ebf48347789bf0ec268414364627Vincent Belliard      SimVRegister& other)  // NOLINT(runtime/references)(runtime/explicit)
3645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      : register_(other) {
3655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (unsigned i = 0; i < sizeof(saturated_) / sizeof(saturated_[0]); i++) {
3665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      saturated_[i] = kNotSaturated;
3675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
3685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (unsigned i = 0; i < sizeof(round_) / sizeof(round_[0]); i++) {
3695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      round_[i] = 0;
3705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
3715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
3725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  int64_t Int(VectorFormat vform, int index) const {
3745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    int64_t element;
3755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
3760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
37788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<int8_t>(index);
3780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
3790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
38088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<int16_t>(index);
3810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
3820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<int32_t>(index);
3840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
3850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
38688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<int64_t>(index);
3870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
3880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
3890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
3900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return 0;
3915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
3925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return element;
3935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
3945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t Uint(VectorFormat vform, int index) const {
3965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t element;
3975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
3980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<uint8_t>(index);
4000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<uint16_t>(index);
4030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
40588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<uint32_t>(index);
4060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
40888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        element = register_.GetLane<uint64_t>(index);
4090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
4110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
4120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return 0;
4135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
4145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return element;
4155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint64_t UintLeftJustified(VectorFormat vform, int index) const {
4185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform));
4195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
4215b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell  int64_t IntLeftJustified(VectorFormat vform, int index) const {
4225b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell    uint64_t value = UintLeftJustified(vform, index);
4235b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell    int64_t result;
4245b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell    memcpy(&result, &value, sizeof(result));
4255b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell    return result;
4265b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell  }
4275b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell
4285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetInt(VectorFormat vform, int index, int64_t value) const {
4295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
4300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
4310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<int8_t>(value));
4320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
4340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<int16_t>(value));
4350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
4370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<int32_t>(value));
4380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
4400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<int64_t>(value));
4410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
4430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
4440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return;
4455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
4465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
448b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  void SetIntArray(VectorFormat vform, const int64_t* src) const {
449b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    ClearForWrite(vform);
450b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
451b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      SetInt(vform, i, src[i]);
452b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    }
453b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  }
454b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell
4555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetUint(VectorFormat vform, int index, uint64_t value) const {
4565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
4570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
4580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<uint8_t>(value));
4590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
4610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<uint16_t>(value));
4620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
4640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<uint32_t>(value));
4650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
4670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, static_cast<uint64_t>(value));
4680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
4700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
4710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return;
4725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
4735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
4745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
475b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  void SetUintArray(VectorFormat vform, const uint64_t* src) const {
476b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    ClearForWrite(vform);
477b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
478b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell      SetUint(vform, i, src[i]);
479b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell    }
480b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  }
481b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell
4825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const {
4835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
4840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
4850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, Memory::Read<uint8_t>(addr));
4860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
4880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, Memory::Read<uint16_t>(addr));
4890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
4910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, Memory::Read<uint32_t>(addr));
4920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
4940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        register_.Insert(index, Memory::Read<uint64_t>(addr));
4950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
4960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
4970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
4980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return;
4995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
5005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const {
503db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    uint64_t value = Uint(vform, index);
5045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (LaneSizeInBitsFromFormat(vform)) {
5050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 8:
5060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        Memory::Write(addr, static_cast<uint8_t>(value));
5070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
5080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 16:
5090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        Memory::Write(addr, static_cast<uint16_t>(value));
5100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
5110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 32:
5120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        Memory::Write(addr, static_cast<uint32_t>(value));
5130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
5140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case 64:
5150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        Memory::Write(addr, value);
5160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
5175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
5185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
5215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T Float(int index) const {
52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return register_.GetLane<T>(index);
5235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
5265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetFloat(int index, T value) const {
5275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    register_.Insert(index, value);
5285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // When setting a result in a register of size less than Q, the top bits of
5315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // the Q register must be cleared.
5325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ClearForWrite(VectorFormat vform) const {
5335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    unsigned size = RegisterSizeInBytesFromFormat(vform);
5345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (unsigned i = size; i < kQRegSizeInBytes; i++) {
5355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      SetUint(kFormat16B, i, 0);
5365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
5375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Saturation state for each lane of a vector.
5405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  enum Saturation {
5415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kNotSaturated = 0,
5425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kSignedSatPositive = 1 << 0,
5435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kSignedSatNegative = 1 << 1,
5445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kSignedSatMask = kSignedSatPositive | kSignedSatNegative,
5455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kSignedSatUndefined = kSignedSatMask,
5465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kUnsignedSatPositive = 1 << 2,
5475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kUnsignedSatNegative = 1 << 3,
5485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative,
5495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kUnsignedSatUndefined = kUnsignedSatMask
5505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  };
5515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Getters for saturation state.
5535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  Saturation GetSignedSaturation(int index) {
5545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return static_cast<Saturation>(saturated_[index] & kSignedSatMask);
5555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  Saturation GetUnsignedSaturation(int index) {
5585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask);
5595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Setters for saturation state.
5620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void ClearSat(int index) { saturated_[index] = kNotSaturated; }
5635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetSignedSat(int index, bool positive) {
5655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative);
5665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetUnsignedSat(int index, bool positive) {
5695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative);
5705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SetSatFlag(int index, Saturation sat) {
5735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    saturated_[index] = static_cast<Saturation>(saturated_[index] | sat);
5745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT((sat & kUnsignedSatMask) != kUnsignedSatUndefined);
5755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT((sat & kSignedSatMask) != kSignedSatUndefined);
5765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Saturate lanes of a vector based on saturation state.
5795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister& SignedSaturate(VectorFormat vform) {
5805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      Saturation sat = GetSignedSaturation(i);
5825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (sat == kSignedSatPositive) {
5835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        SetInt(vform, i, MaxIntFromFormat(vform));
5845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if (sat == kSignedSatNegative) {
5855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        SetInt(vform, i, MinIntFromFormat(vform));
5865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
5875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
5885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return *this;
5895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
5905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
5915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister& UnsignedSaturate(VectorFormat vform) {
5925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
5935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      Saturation sat = GetUnsignedSaturation(i);
5945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (sat == kUnsignedSatPositive) {
5955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        SetUint(vform, i, MaxUintFromFormat(vform));
5965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      } else if (sat == kUnsignedSatNegative) {
5975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        SetUint(vform, i, 0);
5985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
5995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
6005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return *this;
6015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Getter for rounding state.
6040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  bool GetRounding(int index) { return round_[index]; }
6055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Setter for rounding state.
6070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void SetRounding(int index, bool round) { round_[index] = round; }
6085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Round lanes of a vector based on rounding state.
6105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister& Round(VectorFormat vform) {
6115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6125b24fb388927a1f1801a15d460d4c9448f7aa733Martyn Capewell      SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0));
6135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
6145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return *this;
6155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Unsigned halve lanes of a vector, and use the saturation state to set the
6185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // top bit.
6195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister& Uhalve(VectorFormat vform) {
6205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      uint64_t val = Uint(vform, i);
6225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      SetRounding(i, (val & 1) == 1);
6235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      val >>= 1;
6245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (GetUnsignedSaturation(i) != kNotSaturated) {
6255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // If the operation causes unsigned saturation, the bit shifted into the
6265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // most significant bit must be set.
6275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        val |= (MaxUintFromFormat(vform) >> 1) + 1;
6285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
6295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      SetInt(vform, i, val);
6305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
6315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return *this;
6325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Signed halve lanes of a vector, and use the carry state to set the top bit.
6355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister& Halve(VectorFormat vform) {
6365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    for (int i = 0; i < LaneCountFromFormat(vform); i++) {
6375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      int64_t val = Int(vform, i);
6385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      SetRounding(i, (val & 1) == 1);
6395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      val >>= 1;
6405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      if (GetSignedSaturation(i) != kNotSaturated) {
6415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // If the operation causes signed saturation, the sign bit must be
6425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        // inverted.
6435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        val ^= (MaxUintFromFormat(vform) >> 1) + 1;
6445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      }
6455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      SetInt(vform, i, val);
6465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
6475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return *this;
6485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
6495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl private:
6515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister& register_;
6525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Allocate one saturation state entry per lane; largest register is type Q,
6545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // and lanes can be a minimum of one byte wide.
6555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  Saturation saturated_[kQRegSizeInBytes];
6565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
6575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Allocate one rounding state entry per lane.
6585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  bool round_[kQRegSizeInBytes];
6595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl};
6605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
661578645f14e122d2b87d907e298cda7e7d0babf1farmvixl// The proper way to initialize a simulated system register (such as NZCV) is as
662578645f14e122d2b87d907e298cda7e7d0babf1farmvixl// follows:
663578645f14e122d2b87d907e298cda7e7d0babf1farmvixl//  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV);
664578645f14e122d2b87d907e298cda7e7d0babf1farmvixlclass SimSystemRegister {
665578645f14e122d2b87d907e298cda7e7d0babf1farmvixl public:
666578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // The default constructor represents a register which has no writable bits.
667578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // It is not possible to set its value to anything other than 0.
6680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) {}
669578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
67088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t GetRawValue() const { return value_; }
67188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("GetRawValue", uint32_t RawValue() const) {
67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return GetRawValue();
67388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
674578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
675330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void SetRawValue(uint32_t new_value) {
676578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    value_ = (value_ & write_ignore_mask_) | (new_value & ~write_ignore_mask_);
677578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
678578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
67988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t ExtractBits(int msb, int lsb) const {
68088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ExtractUnsignedBitfield32(msb, lsb, value_);
68188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
68288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ExtractBits", uint32_t Bits(int msb, int lsb) const) {
68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ExtractBits(msb, lsb);
684578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
685578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
68688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int32_t ExtractSignedBits(int msb, int lsb) const {
68788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ExtractSignedBitfield32(msb, lsb, value_);
68888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
68988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ExtractSignedBits",
69088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  int32_t SignedBits(int msb, int lsb) const) {
69188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ExtractSignedBits(msb, lsb);
692578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
693578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
694578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void SetBits(int msb, int lsb, uint32_t bits);
695578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
696578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Default system register values.
697578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  static SimSystemRegister DefaultValueFor(SystemRegister id);
698578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
69988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_GETTER(Name, HighBit, LowBit, Func)                            \
70088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t Get##Name() const { return this->Func(HighBit, LowBit); }          \
70188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("Get" #Name, uint32_t Name() const) { return Get##Name(); } \
702330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void Set##Name(uint32_t bits) { SetBits(HighBit, LowBit, bits); }
7030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DEFINE_WRITE_IGNORE_MASK(Name, Mask) \
704578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  static const uint32_t Name##WriteIgnoreMask = ~static_cast<uint32_t>(Mask);
705578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
706578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  SYSTEM_REGISTER_FIELDS_LIST(DEFINE_GETTER, DEFINE_WRITE_IGNORE_MASK)
707578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
708578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#undef DEFINE_ZERO_BITS
709578645f14e122d2b87d907e298cda7e7d0babf1farmvixl#undef DEFINE_GETTER
710578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
711578645f14e122d2b87d907e298cda7e7d0babf1farmvixl protected:
712578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Most system registers only implement a few of the bits in the word. Other
713578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // bits are "read-as-zero, write-ignored". The write_ignore_mask argument
714578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // describes the bits which are not modifiable.
715578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  SimSystemRegister(uint32_t value, uint32_t write_ignore_mask)
7160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      : value_(value), write_ignore_mask_(write_ignore_mask) {}
717578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
718578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  uint32_t value_;
719578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  uint32_t write_ignore_mask_;
720578645f14e122d2b87d907e298cda7e7d0babf1farmvixl};
721578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
722578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
7234a102baf640077d6794c0b33bb976f94b86c532barmvixlclass SimExclusiveLocalMonitor {
7244a102baf640077d6794c0b33bb976f94b86c532barmvixl public:
7254a102baf640077d6794c0b33bb976f94b86c532barmvixl  SimExclusiveLocalMonitor() : kSkipClearProbability(8), seed_(0x87654321) {
7264a102baf640077d6794c0b33bb976f94b86c532barmvixl    Clear();
7274a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7284a102baf640077d6794c0b33bb976f94b86c532barmvixl
7294a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Clear the exclusive monitor (like clrex).
7304a102baf640077d6794c0b33bb976f94b86c532barmvixl  void Clear() {
7314a102baf640077d6794c0b33bb976f94b86c532barmvixl    address_ = 0;
7324a102baf640077d6794c0b33bb976f94b86c532barmvixl    size_ = 0;
7334a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7344a102baf640077d6794c0b33bb976f94b86c532barmvixl
7354a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Clear the exclusive monitor most of the time.
7364a102baf640077d6794c0b33bb976f94b86c532barmvixl  void MaybeClear() {
7374a102baf640077d6794c0b33bb976f94b86c532barmvixl    if ((seed_ % kSkipClearProbability) != 0) {
7384a102baf640077d6794c0b33bb976f94b86c532barmvixl      Clear();
7394a102baf640077d6794c0b33bb976f94b86c532barmvixl    }
7404a102baf640077d6794c0b33bb976f94b86c532barmvixl
7414a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Advance seed_ using a simple linear congruential generator.
7424a102baf640077d6794c0b33bb976f94b86c532barmvixl    seed_ = (seed_ * 48271) % 2147483647;
7434a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7444a102baf640077d6794c0b33bb976f94b86c532barmvixl
7454a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Mark the address range for exclusive access (like load-exclusive).
746330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void MarkExclusive(uint64_t address, size_t size) {
747330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    address_ = address;
7484a102baf640077d6794c0b33bb976f94b86c532barmvixl    size_ = size;
7494a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7504a102baf640077d6794c0b33bb976f94b86c532barmvixl
7514a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Return true if the address range is marked (like store-exclusive).
7524a102baf640077d6794c0b33bb976f94b86c532barmvixl  // This helper doesn't implicitly clear the monitor.
753330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  bool IsExclusive(uint64_t address, size_t size) {
7544a102baf640077d6794c0b33bb976f94b86c532barmvixl    VIXL_ASSERT(size > 0);
7554a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Be pedantic: Require both the address and the size to match.
756330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    return (size == size_) && (address == address_);
7574a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7584a102baf640077d6794c0b33bb976f94b86c532barmvixl
7594a102baf640077d6794c0b33bb976f94b86c532barmvixl private:
760330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  uint64_t address_;
7614a102baf640077d6794c0b33bb976f94b86c532barmvixl  size_t size_;
7624a102baf640077d6794c0b33bb976f94b86c532barmvixl
7634a102baf640077d6794c0b33bb976f94b86c532barmvixl  const int kSkipClearProbability;
7644a102baf640077d6794c0b33bb976f94b86c532barmvixl  uint32_t seed_;
7654a102baf640077d6794c0b33bb976f94b86c532barmvixl};
7664a102baf640077d6794c0b33bb976f94b86c532barmvixl
7674a102baf640077d6794c0b33bb976f94b86c532barmvixl
7684a102baf640077d6794c0b33bb976f94b86c532barmvixl// We can't accurate simulate the global monitor since it depends on external
7694a102baf640077d6794c0b33bb976f94b86c532barmvixl// influences. Instead, this implementation occasionally causes accesses to
7704a102baf640077d6794c0b33bb976f94b86c532barmvixl// fail, according to kPassProbability.
7714a102baf640077d6794c0b33bb976f94b86c532barmvixlclass SimExclusiveGlobalMonitor {
7724a102baf640077d6794c0b33bb976f94b86c532barmvixl public:
7734a102baf640077d6794c0b33bb976f94b86c532barmvixl  SimExclusiveGlobalMonitor() : kPassProbability(8), seed_(0x87654321) {}
7744a102baf640077d6794c0b33bb976f94b86c532barmvixl
775330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  bool IsExclusive(uint64_t address, size_t size) {
776db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl    USE(address, size);
7774a102baf640077d6794c0b33bb976f94b86c532barmvixl
7784a102baf640077d6794c0b33bb976f94b86c532barmvixl    bool pass = (seed_ % kPassProbability) != 0;
7794a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Advance seed_ using a simple linear congruential generator.
7804a102baf640077d6794c0b33bb976f94b86c532barmvixl    seed_ = (seed_ * 48271) % 2147483647;
7814a102baf640077d6794c0b33bb976f94b86c532barmvixl    return pass;
7824a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
7834a102baf640077d6794c0b33bb976f94b86c532barmvixl
7844a102baf640077d6794c0b33bb976f94b86c532barmvixl private:
7854a102baf640077d6794c0b33bb976f94b86c532barmvixl  const int kPassProbability;
7864a102baf640077d6794c0b33bb976f94b86c532barmvixl  uint32_t seed_;
7874a102baf640077d6794c0b33bb976f94b86c532barmvixl};
7884a102baf640077d6794c0b33bb976f94b86c532barmvixl
7894a102baf640077d6794c0b33bb976f94b86c532barmvixl
790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Simulator : public DecoderVisitor {
791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public:
792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  explicit Simulator(Decoder* decoder, FILE* stream = stdout);
793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ~Simulator();
794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void ResetState();
796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Run the simulator.
798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  virtual void Run();
799c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void RunFrom(const Instruction* first);
800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
801f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames
802f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
803f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
804f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // Templated `RunFrom` version taking care of passing arguments and returning
805f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // the result value.
806f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // This allows code like:
807f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  //    int32_t res = simulator.RunFrom<int32_t, int32_t>(GenerateCode(),
808f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  //                                                      0x123);
809f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // It requires VIXL's ABI features, and C++11 or greater.
810f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // Also, the initialisation of tuples is incorrect in GCC before 4.9.1:
811f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
812f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  template <typename R, typename... P>
813f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  R RunFrom(const Instruction* code, P... arguments) {
814f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    return RunFromStructHelper<R, P...>::Wrapper(this, code, arguments...);
815f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  }
816f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames
817f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  template <typename R, typename... P>
818f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  struct RunFromStructHelper {
819f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    static R Wrapper(Simulator* simulator,
820f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                     const Instruction* code,
821f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                     P... arguments) {
822f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      ABI abi;
823f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      std::tuple<P...> unused_tuple{
824f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // TODO: We currently do not support arguments passed on the stack. We
825f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // could do so by using `WriteGenericOperand()` here, but may need to
826f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // add features to handle situations where the stack is or is not set
827f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // up.
828f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
829f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                                           .GetCPURegister(),
830f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                                       arguments),
831f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames           arguments)...};
832f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      simulator->RunFrom(code);
833f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      return simulator->ReadGenericOperand<R>(abi.GetReturnGenericOperand<R>());
834f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    }
835f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  };
836f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames
837f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  // Partial specialization when the return type is `void`.
838f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  template <typename... P>
839f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  struct RunFromStructHelper<void, P...> {
840f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    static void Wrapper(Simulator* simulator,
841f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                        const Instruction* code,
842f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                        P... arguments) {
843f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      ABI abi;
844f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      std::tuple<P...> unused_tuple{
845f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // TODO: We currently do not support arguments passed on the stack. We
846f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // could do so by using `WriteGenericOperand()` here, but may need to
847f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // add features to handle situations where the stack is or is not set
848f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          // up.
849f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames          (simulator->WriteCPURegister(abi.GetNextParameterGenericOperand<P>()
850f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                                           .GetCPURegister(),
851f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames                                       arguments),
852f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames           arguments)...};
853f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames      simulator->RunFrom(code);
854f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames    }
855f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames  };
856f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames#endif
857f75ec85cb9c8690e42125aea3dac1e57d46c21daAlexandre Rames
8580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  // Execution ends when the PC hits this address.
8590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  static const Instruction* kEndOfSimAddress;
8600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Simulation helpers.
86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  const Instruction* ReadPc() const { return pc_; }
86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
865e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  enum BranchLogMode { LogBranches, NoBranchLog };
866e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley
867e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  void WritePc(const Instruction* new_pc,
868e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley               BranchLogMode log_mode = LogBranches) {
869e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley    if (log_mode == LogBranches) LogTakenBranch(new_pc);
8705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    pc_ = Memory::AddressUntag(new_pc);
871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    pc_modified_ = true;
872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WritePc", void set_pc(const Instruction* new_pc)) {
87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return WritePc(new_pc);
87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void IncrementPc() {
878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (!pc_modified_) {
87988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      pc_ = pc_->GetNextInstruction();
880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
88288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("IncrementPc", void increment_pc()) { IncrementPc(); }
883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
884330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void ExecuteInstruction() {
885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // The program counter should always be aligned.
886b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl    VIXL_ASSERT(IsWordAligned(pc_));
8870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    pc_modified_ = false;
888ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    decoder_->Decode(pc_);
88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    IncrementPc();
8900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    LogAllWrittenRegisters();
891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
8930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl// Declare all Visitor functions.
8943fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois#define DECLARE(A) \
8953fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE;
896684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  VISITOR_LIST_THAT_RETURN(DECLARE)
8970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef DECLARE
898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
8993fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois#define DECLARE(A)                                                     \
9003fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois  VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr) \
9013fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois      VIXL_OVERRIDE;
902684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
9030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef DECLARE
904684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
905684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl
9064a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Integer register accessors.
907f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
9084a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Basic accessor: Read the register as the specified type.
9090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T ReadRegister(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const {
911868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    VIXL_ASSERT(
912868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames        code < kNumberOfRegisters ||
913868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
915f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      T result;
916f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      memset(&result, 0, sizeof(result));
917f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      return result;
918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
919868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
920868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      code = 31;
921868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
9224a102baf640077d6794c0b33bb976f94b86c532barmvixl    return registers_[code].Get<T>();
923f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
92488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
92588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadRegister",
92688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister)
92788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      const) {
92888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister<T>(code, r31mode);
92988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
930f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
93188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Common specialized accessors for the ReadRegister() template.
93288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int32_t ReadWRegister(unsigned code,
93388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
93488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister<int32_t>(code, r31mode);
93588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
93688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadWRegister",
93788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  int32_t wreg(unsigned code,
93888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
93988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadWRegister(code, r31mode);
940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int64_t ReadXRegister(unsigned code,
94388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                        Reg31Mode r31mode = Reg31IsZeroRegister) const {
94488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister<int64_t>(code, r31mode);
94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
94688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadXRegister",
94788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  int64_t xreg(unsigned code,
94888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               Reg31Mode r31mode = Reg31IsZeroRegister) const) {
94988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadXRegister(code, r31mode);
950f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
951f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
9524a102baf640077d6794c0b33bb976f94b86c532barmvixl  // As above, with parameterized size and return type. The value is
9534a102baf640077d6794c0b33bb976f94b86c532barmvixl  // either zero-extended or truncated to fit, as required.
9540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
95588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T ReadRegister(unsigned size,
95688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                 unsigned code,
95788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                 Reg31Mode r31mode = Reg31IsZeroRegister) const {
9584a102baf640077d6794c0b33bb976f94b86c532barmvixl    uint64_t raw;
9594a102baf640077d6794c0b33bb976f94b86c532barmvixl    switch (size) {
9600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kWRegSize:
96188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        raw = ReadRegister<uint32_t>(code, r31mode);
9620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
9630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kXRegSize:
96488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        raw = ReadRegister<uint64_t>(code, r31mode);
9650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
9664a102baf640077d6794c0b33bb976f94b86c532barmvixl      default:
9674a102baf640077d6794c0b33bb976f94b86c532barmvixl        VIXL_UNREACHABLE();
9684a102baf640077d6794c0b33bb976f94b86c532barmvixl        return 0;
9694a102baf640077d6794c0b33bb976f94b86c532barmvixl    }
9704a102baf640077d6794c0b33bb976f94b86c532barmvixl
9714a102baf640077d6794c0b33bb976f94b86c532barmvixl    T result;
9724a102baf640077d6794c0b33bb976f94b86c532barmvixl    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
9734a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Copy the result and truncate to fit. This assumes a little-endian host.
9744a102baf640077d6794c0b33bb976f94b86c532barmvixl    memcpy(&result, &raw, sizeof(result));
9754a102baf640077d6794c0b33bb976f94b86c532barmvixl    return result;
9764a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
97788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
97888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadRegister",
97988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  T reg(unsigned size,
98088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                        unsigned code,
98188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                        Reg31Mode r31mode = Reg31IsZeroRegister) const) {
98288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister<T>(size, code, r31mode);
98388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
9844a102baf640077d6794c0b33bb976f94b86c532barmvixl
9854a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Use int64_t by default if T is not specified.
98688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int64_t ReadRegister(unsigned size,
98788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                       unsigned code,
98888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                       Reg31Mode r31mode = Reg31IsZeroRegister) const {
98988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister<int64_t>(size, code, r31mode);
99088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
99188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadRegister",
99288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  int64_t reg(unsigned size,
99388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                              unsigned code,
99488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                              Reg31Mode r31mode = Reg31IsZeroRegister) const) {
99588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadRegister(size, code, r31mode);
996f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
997f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
9980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  enum RegLogMode { LogRegWrites, NoRegLog };
999330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1000330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // Write 'value' into an integer register. The value is zero-extended. This
1001330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // behaviour matches AArch64 register writes.
10020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
100388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteRegister(unsigned code,
100488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     T value,
100588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     RegLogMode log_mode = LogRegWrites,
100688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     Reg31Mode r31mode = Reg31IsZeroRegister) {
1007e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames    if (sizeof(T) < kWRegSizeInBytes) {
1008e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      // We use a C-style cast on purpose here.
1009e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      // Since we do not have access to 'constepxr if', the casts in this `if`
1010e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      // must be valid even if we know the code will never be executed, in
1011e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      // particular when `T` is a pointer type.
1012e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      int64_t tmp_64bit = (int64_t)value;
1013e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      int32_t tmp_32bit = static_cast<int32_t>(tmp_64bit);
1014e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      WriteRegister<int32_t>(code, tmp_32bit, log_mode, r31mode);
1015e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames      return;
1016e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames    }
1017e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames
1018e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames    VIXL_ASSERT((sizeof(T) == kWRegSizeInBytes) ||
1019e938c7cf229b76acf815003f5d380c2ea9e61032Alexandre Rames                (sizeof(T) == kXRegSizeInBytes));
1020868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    VIXL_ASSERT(
1021868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames        code < kNumberOfRegisters ||
1022868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames        ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)));
1023f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if ((code == 31) && (r31mode == Reg31IsZeroRegister)) {
1025f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      return;
1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1028868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if ((r31mode == Reg31IsZeroRegister) && (code == kSPRegInternalCode)) {
1029868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      code = 31;
1030868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
1031868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
103288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    registers_[code].Write(value);
1033330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1034330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    if (log_mode == LogRegWrites) LogRegister(code, r31mode);
1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
103688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
103788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteRegister",
103888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_reg(unsigned code,
103988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               T value,
104088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               RegLogMode log_mode = LogRegWrites,
104188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
104288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister<T>(code, value, log_mode, r31mode);
104388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1045f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // Common specialized accessors for the set_reg() template.
104688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteWRegister(unsigned code,
104788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      int32_t value,
104888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites,
104988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      Reg31Mode r31mode = Reg31IsZeroRegister) {
105088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister(code, value, log_mode, r31mode);
105188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
105288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteWRegister",
105388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_wreg(unsigned code,
105488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                int32_t value,
105588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites,
105688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
105788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteWRegister(code, value, log_mode, r31mode);
1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
106088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteXRegister(unsigned code,
106188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      int64_t value,
106288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites,
106388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      Reg31Mode r31mode = Reg31IsZeroRegister) {
106488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister(code, value, log_mode, r31mode);
106588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
106688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteXRegister",
106788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_xreg(unsigned code,
106888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                int64_t value,
106988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites,
107088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                Reg31Mode r31mode = Reg31IsZeroRegister)) {
107188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteXRegister(code, value, log_mode, r31mode);
10724a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
10734a102baf640077d6794c0b33bb976f94b86c532barmvixl
10744a102baf640077d6794c0b33bb976f94b86c532barmvixl  // As above, with parameterized size and type. The value is either
10754a102baf640077d6794c0b33bb976f94b86c532barmvixl  // zero-extended or truncated to fit, as required.
10760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
107788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteRegister(unsigned size,
107888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     unsigned code,
107988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     T value,
108088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     RegLogMode log_mode = LogRegWrites,
108188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                     Reg31Mode r31mode = Reg31IsZeroRegister) {
10824a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Zero-extend the input.
10834a102baf640077d6794c0b33bb976f94b86c532barmvixl    uint64_t raw = 0;
10844a102baf640077d6794c0b33bb976f94b86c532barmvixl    VIXL_STATIC_ASSERT(sizeof(value) <= sizeof(raw));
10854a102baf640077d6794c0b33bb976f94b86c532barmvixl    memcpy(&raw, &value, sizeof(value));
10864a102baf640077d6794c0b33bb976f94b86c532barmvixl
10874a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Write (and possibly truncate) the value.
10884a102baf640077d6794c0b33bb976f94b86c532barmvixl    switch (size) {
1089db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      case kWRegSize:
109088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        WriteRegister(code, static_cast<uint32_t>(raw), log_mode, r31mode);
1091db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        break;
1092db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl      case kXRegSize:
109388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        WriteRegister(code, raw, log_mode, r31mode);
1094db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl        break;
10954a102baf640077d6794c0b33bb976f94b86c532barmvixl      default:
10964a102baf640077d6794c0b33bb976f94b86c532barmvixl        VIXL_UNREACHABLE();
10974a102baf640077d6794c0b33bb976f94b86c532barmvixl        return;
10984a102baf640077d6794c0b33bb976f94b86c532barmvixl    }
1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
110088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
110188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteRegister",
110288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_reg(unsigned size,
110388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               unsigned code,
110488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               T value,
110588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               RegLogMode log_mode = LogRegWrites,
110688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                               Reg31Mode r31mode = Reg31IsZeroRegister)) {
110788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister(size, code, value, log_mode, r31mode);
110888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11104a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Common specialized accessors for the set_reg() template.
11114a102baf640077d6794c0b33bb976f94b86c532barmvixl
1112f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // Commonly-used special cases.
11130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
111488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteLr(T value) {
111588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister(kLinkRegCode, value);
111688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
111788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
111888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteLr", void set_lr(T value)) {
111988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteLr(value);
1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
112388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteSp(T value) {
112488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteRegister(31, value, LogRegWrites, Reg31IsStackPointer);
112588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
112688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
112788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteSp", void set_sp(T value)) {
112888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteSp(value);
1129f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Vector register accessors.
11325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // These are equivalent to the integer register accessors, but for vector
11334a102baf640077d6794c0b33bb976f94b86c532barmvixl  // registers.
1134f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
11355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // A structure for representing a 128-bit Q register.
11360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  struct qreg_t {
11370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    uint8_t val[kQRegSizeInBytes];
11380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  };
11395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Basic accessor: read the register as the specified type.
11410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
114288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T ReadVRegister(unsigned code) const {
11430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl    VIXL_STATIC_ASSERT(
11440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        (sizeof(T) == kBRegSizeInBytes) || (sizeof(T) == kHRegSizeInBytes) ||
11450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        (sizeof(T) == kSRegSizeInBytes) || (sizeof(T) == kDRegSizeInBytes) ||
11460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        (sizeof(T) == kQRegSizeInBytes));
11475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(code < kNumberOfVRegisters);
11485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return vregisters_[code].Get<T>();
11505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
115188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
115288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned code) const) {
115388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<T>(code);
115488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
11555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
11565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Common specialized accessors for the vreg() template.
115788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int8_t ReadBRegister(unsigned code) const {
115888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<int8_t>(code);
115988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
116088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadBRegister", int8_t breg(unsigned code) const) {
116188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadBRegister(code);
116288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
11634a102baf640077d6794c0b33bb976f94b86c532barmvixl
116488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int16_t ReadHRegister(unsigned code) const {
116588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<int16_t>(code);
116688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
116788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadHRegister", int16_t hreg(unsigned code) const) {
116888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadHRegister(code);
116988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
117188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  float ReadSRegister(unsigned code) const {
117288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<float>(code);
117388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
117488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadSRegister", float sreg(unsigned code) const) {
117588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadSRegister(code);
117688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
117888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint32_t ReadSRegisterBits(unsigned code) const {
117988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<uint32_t>(code);
118088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
118188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadSRegisterBits",
118288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  uint32_t sreg_bits(unsigned code) const) {
118388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadSRegisterBits(code);
118488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
118688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  double ReadDRegister(unsigned code) const {
118788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<double>(code);
118888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
118988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadDRegister", double dreg(unsigned code) const) {
119088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadDRegister(code);
119188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
119388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  uint64_t ReadDRegisterBits(unsigned code) const {
119488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<uint64_t>(code);
119588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
119688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadDRegisterBits",
119788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  uint64_t dreg_bits(unsigned code) const) {
119888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadDRegisterBits(code);
119988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
12005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
120188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  qreg_t ReadQRegister(unsigned code) const {
120288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<qreg_t>(code);
120388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
120488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadQRegister", qreg_t qreg(unsigned code) const) {
120588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadQRegister(code);
120688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12084a102baf640077d6794c0b33bb976f94b86c532barmvixl  // As above, with parameterized size and return type. The value is
12094a102baf640077d6794c0b33bb976f94b86c532barmvixl  // either zero-extended or truncated to fit, as required.
12100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
121188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  T ReadVRegister(unsigned size, unsigned code) const {
12125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    uint64_t raw = 0;
12135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    T result;
12145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    switch (size) {
12160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kSRegSize:
121788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        raw = ReadVRegister<uint32_t>(code);
12180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
12190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kDRegSize:
122088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        raw = ReadVRegister<uint64_t>(code);
12210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        break;
1222f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl      default:
1223b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl        VIXL_UNREACHABLE();
12244a102baf640077d6794c0b33bb976f94b86c532barmvixl        break;
1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
12264a102baf640077d6794c0b33bb976f94b86c532barmvixl
12274a102baf640077d6794c0b33bb976f94b86c532barmvixl    VIXL_STATIC_ASSERT(sizeof(result) <= sizeof(raw));
12284a102baf640077d6794c0b33bb976f94b86c532barmvixl    // Copy the result and truncate to fit. This assumes a little-endian host.
12294a102baf640077d6794c0b33bb976f94b86c532barmvixl    memcpy(&result, &raw, sizeof(result));
12304a102baf640077d6794c0b33bb976f94b86c532barmvixl    return result;
1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
123288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
123388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadVRegister", T vreg(unsigned size, unsigned code) const) {
123488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister<T>(size, code);
123588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
123788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SimVRegister& ReadVRegister(unsigned code) { return vregisters_[code]; }
123888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadVRegister", SimVRegister& vreg(unsigned code)) {
123988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadVRegister(code);
124088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
12415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
12424a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Basic accessor: Write the specified value.
12430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
124488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteVRegister(unsigned code,
124588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      T value,
124688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
12475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_STATIC_ASSERT((sizeof(value) == kBRegSizeInBytes) ||
12485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       (sizeof(value) == kHRegSizeInBytes) ||
12495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       (sizeof(value) == kSRegSizeInBytes) ||
12505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       (sizeof(value) == kDRegSizeInBytes) ||
12515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       (sizeof(value) == kQRegSizeInBytes));
12525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(code < kNumberOfVRegisters);
125388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    vregisters_[code].Write(value);
1254330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1255330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    if (log_mode == LogRegWrites) {
12565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      LogVRegister(code, GetPrintRegisterFormat(value));
1257330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    }
1258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
125988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  template <typename T>
126088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteVRegister",
126188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_vreg(unsigned code,
126288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                T value,
126388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
126588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
126788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Common specialized accessors for the WriteVRegister() template.
126888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteBRegister(unsigned code,
126988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      int8_t value,
127088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
127188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
127288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
127388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteBRegister",
127488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_breg(unsigned code,
127588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                int8_t value,
127688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
127788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return WriteBRegister(code, value, log_mode);
12785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
128088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteHRegister(unsigned code,
128188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      int16_t value,
128288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
128388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
128488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
128588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteHRegister",
128688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_hreg(unsigned code,
128788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                int16_t value,
128888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
128988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return WriteHRegister(code, value, log_mode);
12905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
12915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
129288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteSRegister(unsigned code,
129388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      float value,
129488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
129588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
129688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
129788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteSRegister",
129888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_sreg(unsigned code,
129988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                float value,
130088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
130188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteSRegister(code, value, log_mode);
1302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
130488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteSRegisterBits(unsigned code,
130588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                          uint32_t value,
130688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                          RegLogMode log_mode = LogRegWrites) {
130788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
130888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
130988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteSRegisterBits",
131088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_sreg_bits(unsigned code,
131188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                     uint32_t value,
131288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                     RegLogMode log_mode = LogRegWrites)) {
131388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteSRegisterBits(code, value, log_mode);
1314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
131688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteDRegister(unsigned code,
131788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      double value,
131888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
131988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
132088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
132188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteDRegister",
132288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_dreg(unsigned code,
132388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                double value,
132488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
132588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteDRegister(code, value, log_mode);
1326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
132888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteDRegisterBits(unsigned code,
132988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                          uint64_t value,
133088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                          RegLogMode log_mode = LogRegWrites) {
133188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
133288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
133388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteDRegisterBits",
133488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_dreg_bits(unsigned code,
133588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                     uint64_t value,
133688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                     RegLogMode log_mode = LogRegWrites)) {
133788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteDRegisterBits(code, value, log_mode);
13385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
13395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
134088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void WriteQRegister(unsigned code,
134188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      qreg_t value,
134288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                      RegLogMode log_mode = LogRegWrites) {
134388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteVRegister(code, value, log_mode);
1344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
134588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("WriteQRegister",
134688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_qreg(unsigned code,
134788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                qreg_t value,
134888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                                RegLogMode log_mode = LogRegWrites)) {
134988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    WriteQRegister(code, value, log_mode);
135088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
135188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
1352868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1353868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  T ReadRegister(Register reg) const {
1354868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    return ReadRegister<T>(reg.GetCode(), Reg31IsZeroRegister);
1355868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1356868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1357868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1358868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  void WriteRegister(Register reg,
1359868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                     T value,
1360868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                     RegLogMode log_mode = LogRegWrites) {
1361868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    WriteRegister<T>(reg.GetCode(), value, log_mode, Reg31IsZeroRegister);
1362868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1363868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1364868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1365868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  T ReadVRegister(VRegister vreg) const {
1366868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    return ReadVRegister<T>(vreg.GetCode());
1367868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1368868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1369868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1370868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  void WriteVRegister(VRegister vreg,
1371868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                      T value,
1372868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                      RegLogMode log_mode = LogRegWrites) {
1373868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    WriteVRegister<T>(vreg.GetCode(), value, log_mode);
1374868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1375868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1376868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1377868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  T ReadCPURegister(CPURegister reg) const {
1378868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if (reg.IsVRegister()) {
1379868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      return ReadVRegister<T>(VRegister(reg));
1380868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    } else {
1381868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      return ReadRegister<T>(Register(reg));
1382868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
1383868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1384868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1385868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1386868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  void WriteCPURegister(CPURegister reg,
1387868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                        T value,
1388868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                        RegLogMode log_mode = LogRegWrites) {
1389868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if (reg.IsVRegister()) {
1390868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      WriteVRegister<T>(VRegister(reg), value, log_mode);
1391868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    } else {
1392868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      WriteRegister<T>(Register(reg), value, log_mode);
1393868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
1394868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1395868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1396868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
1397868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1398868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1399868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  T ReadGenericOperand(GenericOperand operand) const {
1400868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if (operand.IsCPURegister()) {
1401868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      return ReadCPURegister<T>(operand.GetCPURegister());
1402868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    } else {
1403868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      VIXL_ASSERT(operand.IsMemOperand());
1404868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      return Memory::Read<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
1405868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
1406868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1407868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
1408868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  template <typename T>
1409868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  void WriteGenericOperand(GenericOperand operand,
1410868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                           T value,
1411868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                           RegLogMode log_mode = LogRegWrites) {
1412868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    if (operand.IsCPURegister()) {
1413868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode);
1414868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    } else {
1415868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      VIXL_ASSERT(operand.IsMemOperand());
1416868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames      Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value);
1417868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames    }
1418868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  }
1419868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames
142088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool ReadN() const { return nzcv_.GetN() != 0; }
142188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadN", bool N() const) { return ReadN(); }
1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
142388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool ReadZ() const { return nzcv_.GetZ() != 0; }
142488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadZ", bool Z() const) { return ReadZ(); }
142588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
142688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool ReadC() const { return nzcv_.GetC() != 0; }
142788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadC", bool C() const) { return ReadC(); }
142888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
142988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool ReadV() const { return nzcv_.GetV() != 0; }
143088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadV", bool V() const) { return ReadV(); }
143188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
143288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SimSystemRegister& ReadNzcv() { return nzcv_; }
143388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadNzcv", SimSystemRegister& nzcv()) { return ReadNzcv(); }
1434578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
14355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // TODO: Find a way to make the fpcr_ members return the proper types, so
14365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // these accessors are not necessary.
143788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  FPRounding ReadRMode() const {
143888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return static_cast<FPRounding>(fpcr_.GetRMode());
143988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
144088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadRMode", FPRounding RMode()) { return ReadRMode(); }
144188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
144288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool ReadDN() const { return fpcr_.GetDN() != 0; }
144388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadDN", bool DN()) { return ReadDN(); }
144488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
144588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  SimSystemRegister& ReadFpcr() { return fpcr_; }
144688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("ReadFpcr", SimSystemRegister& fpcr()) { return ReadFpcr(); }
1447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
14485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Specify relevant register formats for Print(V)Register and related helpers.
14495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  enum PrintRegisterFormat {
14505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // The lane size.
14515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeB = 0 << 0,
14525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeH = 1 << 0,
14535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeS = 2 << 0,
14545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeW = kPrintRegLaneSizeS,
14555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeD = 3 << 0,
14565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeX = kPrintRegLaneSizeD,
14575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeQ = 4 << 0,
14585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeOffset = 0,
14605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegLaneSizeMask = 7 << 0,
14615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // The lane count.
14635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegAsScalar = 0,
14645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegAsDVector = 1 << 3,
14655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegAsQVector = 2 << 3,
14665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegAsVectorMask = 3 << 3,
14685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Indicate floating-point format lanes. (This flag is only supported for S-
14705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // and D-sized lanes.)
14715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintRegAsFP = 1 << 5,
14725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Supported combinations.
14745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar,
14765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar,
14775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
14785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
14795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar,
14815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector,
14825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector,
14835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar,
14845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector,
14855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector,
14865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar,
14875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector,
14885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector,
14895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP,
14905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP,
14915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP,
14925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar,
14935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector,
14945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP,
14955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP,
14965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar
14975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  };
14985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
14995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) {
15005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset;
15015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) {
15045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 1 << GetPrintRegLaneSizeInBytesLog2(format);
15055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) {
15085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (format & kPrintRegAsDVector) return kDRegSizeInBytesLog2;
15095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if (format & kPrintRegAsQVector) return kQRegSizeInBytesLog2;
15105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    // Scalar types.
15125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return GetPrintRegLaneSizeInBytesLog2(format);
15135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) {
15165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 1 << GetPrintRegSizeInBytesLog2(format);
15175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  unsigned GetPrintRegLaneCount(PrintRegisterFormat format) {
15205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format);
15215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format);
15225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_ASSERT(reg_size_log2 >= lane_size_log2);
15235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return 1 << (reg_size_log2 - lane_size_log2);
15245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned reg_size,
15275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                    unsigned lane_size);
15285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormatForSize(unsigned size) {
15305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return GetPrintRegisterFormatForSize(size, size);
15315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormatForSizeFP(unsigned size) {
15345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    switch (size) {
15350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      default:
15360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        VIXL_UNREACHABLE();
15370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return kPrintDReg;
15380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kDRegSizeInBytes:
15390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return kPrintDReg;
15400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl      case kSRegSizeInBytes:
15410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl        return kPrintSReg;
15425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
15435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) {
15465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    if ((GetPrintRegLaneSizeInBytes(format) == kSRegSizeInBytes) ||
15475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl        (GetPrintRegLaneSizeInBytes(format) == kDRegSizeInBytes)) {
15485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP);
15495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
15505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return format;
15515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>
15545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormat(T value) {
15555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return GetPrintRegisterFormatForSize(sizeof(value));
15565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormat(double value) {
15595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_STATIC_ASSERT(sizeof(value) == kDRegSizeInBytes);
15605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return GetPrintRegisterFormatForSizeFP(sizeof(value));
15615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormat(float value) {
15645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    VIXL_STATIC_ASSERT(sizeof(value) == kSRegSizeInBytes);
15655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    return GetPrintRegisterFormatForSizeFP(sizeof(value));
15665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  }
15675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform);
15690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform);
15705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
1571330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // Print all registers of the specified types.
1572330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void PrintRegisters();
15735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void PrintVRegisters();
1574330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void PrintSystemRegisters();
1575330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
15765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // As above, but only print the registers that have been updated.
15775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void PrintWrittenRegisters();
15785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void PrintWrittenVRegisters();
15795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
15805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // As above, but respect LOG_REG and LOG_VREG.
15815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void LogWrittenRegisters() {
158288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_REGS) PrintWrittenRegisters();
1583330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
15845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void LogWrittenVRegisters() {
158588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_VREGS) PrintWrittenVRegisters();
1586330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
15875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void LogAllWrittenRegisters() {
15885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogWrittenRegisters();
15895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    LogWrittenVRegisters();
1590330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
1591330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1592330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // Print individual register values (after update).
1593330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer);
15945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void PrintVRegister(unsigned code, PrintRegisterFormat format);
1595330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void PrintSystemRegister(SystemRegister id);
1596e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  void PrintTakenBranch(const Instruction* target);
1597330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
159888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Like Print* (above), but respect GetTraceParameters().
1599330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) {
160088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_REGS) PrintRegister(code, r31mode);
1601330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
16025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void LogVRegister(unsigned code, PrintRegisterFormat format) {
160388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_VREGS) PrintVRegister(code, format);
1604330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
1605330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void LogSystemRegister(SystemRegister id) {
160688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_SYSREGS) PrintSystemRegister(id);
1607330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
1608e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  void LogTakenBranch(const Instruction* target) {
1609e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley    if (GetTraceParameters() & LOG_BRANCH) PrintTakenBranch(target);
1610e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  }
1611330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1612330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // Print memory accesses.
16130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintRead(uintptr_t address,
16140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 unsigned reg_code,
16155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                 PrintRegisterFormat format);
16160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintWrite(uintptr_t address,
16170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                  unsigned reg_code,
16180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                  PrintRegisterFormat format);
16190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintVRead(uintptr_t address,
16200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                  unsigned reg_code,
16210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                  PrintRegisterFormat format,
16220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                  unsigned lane);
16230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintVWrite(uintptr_t address,
16240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                   unsigned reg_code,
16250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                   PrintRegisterFormat format,
16260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                   unsigned lane);
1627330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
162888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // Like Print* (above), but respect GetTraceParameters().
16290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void LogRead(uintptr_t address,
16300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl               unsigned reg_code,
16315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl               PrintRegisterFormat format) {
163288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_REGS) PrintRead(address, reg_code, format);
1633330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
16340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void LogWrite(uintptr_t address,
16350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                unsigned reg_code,
16365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                PrintRegisterFormat format) {
163788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_WRITE) PrintWrite(address, reg_code, format);
1638330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
16390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void LogVRead(uintptr_t address,
16400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                unsigned reg_code,
16410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                PrintRegisterFormat format,
16420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                unsigned lane = 0) {
164388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_VREGS) {
16445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      PrintVRead(address, reg_code, format, lane);
16455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
1646330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
16470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void LogVWrite(uintptr_t address,
16480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 unsigned reg_code,
16490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 PrintRegisterFormat format,
16500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                 unsigned lane = 0) {
165188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    if (GetTraceParameters() & LOG_WRITE) {
16525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl      PrintVWrite(address, reg_code, format, lane);
16535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl    }
1654330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  }
1655330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
16565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Helper functions for register tracing.
16570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintRegisterRawHelper(unsigned code,
16580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                              Reg31Mode r31mode,
16595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                              int size_in_bytes = kXRegSizeInBytes);
16600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintVRegisterRawHelper(unsigned code,
16610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                               int bytes = kQRegSizeInBytes,
16625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int lsb = 0);
16630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void PrintVRegisterFPHelper(unsigned code,
16640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                              unsigned lane_size_in_bytes,
16650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                              int lane_count = 1,
16660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                              int rightmost_lane = 0);
16675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
1668684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
1669330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void DoTrace(const Instruction* instr);
1670330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void DoLog(const Instruction* instr);
1671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* WRegNameForCode(unsigned code,
1673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                     Reg31Mode mode = Reg31IsZeroRegister);
1674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* XRegNameForCode(unsigned code,
1675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                     Reg31Mode mode = Reg31IsZeroRegister);
1676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* SRegNameForCode(unsigned code);
1677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* DRegNameForCode(unsigned code);
1678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* VRegNameForCode(unsigned code);
1679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
168088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  bool IsColouredTrace() const { return coloured_trace_; }
168188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("IsColouredTrace", bool coloured_trace() const) {
168288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return IsColouredTrace();
168388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
168588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void SetColouredTrace(bool value);
168688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("SetColouredTrace", void set_coloured_trace(bool value)) {
168788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    SetColouredTrace(value);
168888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1689330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
1690d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames  // Values for traces parameters defined in simulator-constants-aarch64.h in
169188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  // enum TraceParameters.
169288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  int GetTraceParameters() const { return trace_parameters_; }
169388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("GetTraceParameters", int trace_parameters() const) {
169488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return GetTraceParameters();
169588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
169688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
169788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void SetTraceParameters(int parameters);
169888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("SetTraceParameters",
169988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_trace_parameters(int parameters)) {
170088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    SetTraceParameters(parameters);
170188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
170288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
170388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  void SetInstructionStats(bool value);
170488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  VIXL_DEPRECATED("SetInstructionStats",
170588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                  void set_instruction_stats(bool value)) {
170688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    SetInstructionStats(value);
170788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois  }
1708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
17094a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Clear the simulated local monitor to force the next store-exclusive
17104a102baf640077d6794c0b33bb976f94b86c532barmvixl  // instruction to fail.
17110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void ClearLocalMonitor() { local_monitor_.Clear(); }
17124a102baf640077d6794c0b33bb976f94b86c532barmvixl
1713330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  void SilenceExclusiveAccessWarning() {
17144a102baf640077d6794c0b33bb976f94b86c532barmvixl    print_exclusive_access_warning_ = false;
17154a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
17164a102baf640077d6794c0b33bb976f94b86c532barmvixl
1717064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// Runtime call emulation support.
1718064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// It requires VIXL's ABI features, and C++11 or greater.
1719482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley// Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
1720482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley// in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
1721482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
1722482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley    (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
1723064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1724ca73ba046c11d65b6dce59cfd26847d14aba06abAlexandre Rames#define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
1725064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1726064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// The implementation of the runtime call helpers require the functionality
1727064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// provided by `std::index_sequence`. It is only available from C++14, but
1728064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// we want runtime call simulation to work from C++11, so we emulate if
1729064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// necessary.
1730064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#if __cplusplus >= 201402L
1731064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <std::size_t... I>
1732064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  using local_index_sequence = std::index_sequence<I...>;
1733064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename... P>
1734064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  using __local_index_sequence_for = std::index_sequence_for<P...>;
1735064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#else
1736064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // Emulate the behaviour of `std::index_sequence` and
1737064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // `std::index_sequence_for`.
1738064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // Naming follow the `std` names, prefixed with `emulated_`.
1739064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <size_t... I>
1740064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct emulated_index_sequence {};
1741064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1742064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // A recursive template to create a sequence of indexes.
1743064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // The base case (for `N == 0`) is declared outside of the class scope, as
1744064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // required by C++.
1745064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <std::size_t N, size_t... I>
1746064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct emulated_make_index_sequence_helper
1747064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      : emulated_make_index_sequence_helper<N - 1, N - 1, I...> {};
1748064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1749064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <std::size_t N>
1750064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct emulated_make_index_sequence : emulated_make_index_sequence_helper<N> {
1751064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  };
1752064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1753064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename... P>
1754064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct emulated_index_sequence_for
1755064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      : emulated_make_index_sequence<sizeof...(P)> {};
1756064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1757064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <std::size_t... I>
1758064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  using local_index_sequence = emulated_index_sequence<I...>;
1759064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename... P>
1760064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  using __local_index_sequence_for = emulated_index_sequence_for<P...>;
1761064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
1762064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1763064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // Expand the argument tuple and perform the call.
1764064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename R, typename... P, std::size_t... I>
1765064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  R DoRuntimeCall(R (*function)(P...),
1766064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                  std::tuple<P...> arguments,
1767064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                  local_index_sequence<I...>) {
1768064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    return function(std::get<I>(arguments)...);
1769064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  }
1770064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1771064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename R, typename... P>
1772064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  void RuntimeCallNonVoid(R (*function)(P...)) {
1773064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    ABI abi;
1774064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    std::tuple<P...> argument_operands{
1775064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1776064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    R return_value = DoRuntimeCall(function,
1777064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                                   argument_operands,
1778064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                                   __local_index_sequence_for<P...>{});
1779064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
1780064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  }
1781064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1782064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename R, typename... P>
1783064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  void RuntimeCallVoid(R (*function)(P...)) {
1784064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    ABI abi;
1785064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    std::tuple<P...> argument_operands{
1786064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames        ReadGenericOperand<P>(abi.GetNextParameterGenericOperand<P>())...};
1787064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    DoRuntimeCall(function,
1788064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                  argument_operands,
1789064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames                  __local_index_sequence_for<P...>{});
1790064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  }
1791064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1792064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // We use `struct` for `void` return type specialisation.
1793064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename R, typename... P>
1794064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct RuntimeCallStructHelper {
1795482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1796064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      R (*function)(P...) = reinterpret_cast<R (*)(P...)>(function_pointer);
1797064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      simulator->RuntimeCallNonVoid(function);
1798064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    }
1799064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  };
1800064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1801064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  // Partial specialization when the return type is `void`.
1802064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  template <typename... P>
1803064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  struct RuntimeCallStructHelper<void, P...> {
1804482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley    static void Wrapper(Simulator* simulator, uintptr_t function_pointer) {
1805064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      void (*function)(P...) =
1806064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames          reinterpret_cast<void (*)(P...)>(function_pointer);
1807064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames      simulator->RuntimeCallVoid(function);
1808064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    }
1809064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  };
1810064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
1811064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
1812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl protected:
1813b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_normal;
1814b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_flag_name;
1815b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_flag_value;
1816b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_reg_name;
1817b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_reg_value;
18185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  const char* clr_vreg_name;
18195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  const char* clr_vreg_value;
1820b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_memory_address;
18214a102baf640077d6794c0b33bb976f94b86c532barmvixl  const char* clr_warning;
18224a102baf640077d6794c0b33bb976f94b86c532barmvixl  const char* clr_warning_message;
1823b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  const char* clr_printf;
1824e79723a010a6f42fe78e2515c7b0eb9308b93093Jacob Bramley  const char* clr_branch_marker;
1825b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
1826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Simulation helpers ------------------------------------
1827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool ConditionPassed(Condition cond) {
1828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    switch (cond) {
1829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case eq:
183088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadZ();
1831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case ne:
183288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !ReadZ();
1833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case hs:
183488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadC();
1835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case lo:
183688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !ReadC();
1837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case mi:
183888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadN();
1839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case pl:
184088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !ReadN();
1841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case vs:
184288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadV();
1843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case vc:
184488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !ReadV();
1845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case hi:
184688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadC() && !ReadZ();
1847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case ls:
184888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !(ReadC() && !ReadZ());
1849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case ge:
185088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadN() == ReadV();
1851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case lt:
185288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return ReadN() != ReadV();
1853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case gt:
185488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !ReadZ() && (ReadN() == ReadV());
1855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case le:
185688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois        return !(!ReadZ() && (ReadN() == ReadV()));
18576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      case nv:
18586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl        VIXL_FALLTHROUGH();
1859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case al:
1860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        return true;
1861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      default:
1862b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl        VIXL_UNREACHABLE();
1863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        return false;
1864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
18674a102baf640077d6794c0b33bb976f94b86c532barmvixl  bool ConditionPassed(Instr cond) {
18684a102baf640077d6794c0b33bb976f94b86c532barmvixl    return ConditionPassed(static_cast<Condition>(cond));
18694a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
18704a102baf640077d6794c0b33bb976f94b86c532barmvixl
18710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  bool ConditionFailed(Condition cond) { return !ConditionPassed(cond); }
1872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1873c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void AddSubHelper(const Instruction* instr, int64_t op2);
1874684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl  uint64_t AddWithCarry(unsigned reg_size,
1875684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl                        bool set_flags,
1876684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl                        uint64_t left,
1877684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl                        uint64_t right,
1878684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl                        int carry_in = 0);
1879c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void LogicalHelper(const Instruction* instr, int64_t op2);
1880c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
1881c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void LoadStoreHelper(const Instruction* instr,
1882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       int64_t offset,
1883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       AddrMode addrmode);
1884c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void LoadStorePairHelper(const Instruction* instr, AddrMode addrmode);
1885330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  uintptr_t AddressModeHelper(unsigned addr_reg,
1886330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl                              int64_t offset,
1887330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl                              AddrMode addrmode);
18885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void NEONLoadStoreMultiStructHelper(const Instruction* instr,
18895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                      AddrMode addr_mode);
18905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void NEONLoadStoreSingleStructHelper(const Instruction* instr,
18915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                       AddrMode addr_mode);
1892330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl
18930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  uint64_t AddressUntag(uint64_t address) { return address & ~kAddressTagMask; }
1894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
18954a102baf640077d6794c0b33bb976f94b86c532barmvixl  template <typename T>
1896330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  T* AddressUntag(T* address) {
1897330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    uintptr_t address_raw = reinterpret_cast<uintptr_t>(address);
1898330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl    return reinterpret_cast<T*>(AddressUntag(address_raw));
18994a102baf640077d6794c0b33bb976f94b86c532barmvixl  }
1900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t ShiftOperand(unsigned reg_size,
1902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       int64_t value,
1903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       Shift shift_type,
1904868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                       unsigned amount) const;
1905ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t ExtendValue(unsigned reg_width,
1906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      int64_t value,
1907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Extend extend_type,
1908868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames                      unsigned left_shift = 0) const;
1909868bfc49d722d6a233390ec847fa1407820a1eabAlexandre Rames  uint16_t PolynomialMult(uint8_t op1, uint8_t op2) const;
19105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
19110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
19120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
19130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
19145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld2(VectorFormat vform,
19155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld2(VectorFormat vform,
19195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld2r(VectorFormat vform,
19240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst1,
19250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst2,
19260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            uint64_t addr);
19275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld3(VectorFormat vform,
19285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst3,
19315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld3(VectorFormat vform,
19335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst3,
19365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld3r(VectorFormat vform,
19390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst1,
19400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst2,
19410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst3,
19420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            uint64_t addr);
19435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld4(VectorFormat vform,
19445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst3,
19475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst4,
19485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld4(VectorFormat vform,
19505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst1,
19515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst2,
19525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst3,
19535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister dst4,
19545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void ld4r(VectorFormat vform,
19570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst1,
19580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst2,
19590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst3,
19600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            LogicVRegister dst4,
19610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl            uint64_t addr);
19620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
19630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
19645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st2(VectorFormat vform,
19655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st2(VectorFormat vform,
19695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st3(VectorFormat vform,
19745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src3,
19775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st3(VectorFormat vform,
19795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src3,
19825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st4(VectorFormat vform,
19855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src3,
19885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src4,
19895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void st4(VectorFormat vform,
19915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src,
19925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src2,
19935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src3,
19945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           LogicVRegister src4,
19955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           int index,
19965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl           uint64_t addr);
19975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister cmp(VectorFormat vform,
19985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
19995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2,
20015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     Condition cond);
20025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister cmp(VectorFormat vform,
20035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int imm,
20065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     Condition cond);
20075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister cmptst(VectorFormat vform,
20085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
20095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
20105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
20115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister add(VectorFormat vform,
20125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
20155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister addp(VectorFormat vform,
20165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
20175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
20185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
20195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mla(VectorFormat vform,
20205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
20235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mls(VectorFormat vform,
20245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
20275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mul(VectorFormat vform,
20285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
20315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mul(VectorFormat vform,
20325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2,
20355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int index);
20365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mla(VectorFormat vform,
20375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2,
20405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int index);
20415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister mls(VectorFormat vform,
20425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
20435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
20445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2,
20455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int index);
20465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister pmul(VectorFormat vform,
20475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
20485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
20495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
20505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
20515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform,
20525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                   LogicVRegister dst,
20535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                   const LogicVRegister& src1,
20545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                   const LogicVRegister& src2,
20555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                                                   int index);
20565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmul(VectorFormat vform,
20575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
20585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
20595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2,
20605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int index);
20615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmla(VectorFormat vform,
20625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
20635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
20645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2,
20655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int index);
20665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmls(VectorFormat vform,
20675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
20685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
20695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2,
20705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int index);
20715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmulx(VectorFormat vform,
20725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
20735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
20745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
20755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
20765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smull(VectorFormat vform,
20775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
20785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
20795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
20805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
20815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smull2(VectorFormat vform,
20825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
20835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
20845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
20855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
20865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umull(VectorFormat vform,
20875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
20885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
20895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
20905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
20915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umull2(VectorFormat vform,
20925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
20935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
20945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
20955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
20965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smlal(VectorFormat vform,
20975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
20985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
20995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
21005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
21015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smlal2(VectorFormat vform,
21025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
21035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
21045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
21055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
21065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umlal(VectorFormat vform,
21075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
21085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
21095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
21105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
21115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umlal2(VectorFormat vform,
21125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
21135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
21145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
21155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
21165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smlsl(VectorFormat vform,
21175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
21185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
21195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
21205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
21215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smlsl2(VectorFormat vform,
21225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
21235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
21245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
21255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
21265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umlsl(VectorFormat vform,
21275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
21285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
21295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2,
21305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int index);
21315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umlsl2(VectorFormat vform,
21325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
21335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
21345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2,
21355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int index);
21365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmull(VectorFormat vform,
21375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
21385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
21395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
21405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int index);
21415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmull2(VectorFormat vform,
21425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
21435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src1,
21445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src2,
21455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int index);
21465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmlal(VectorFormat vform,
21475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
21485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
21495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
21505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int index);
21515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmlal2(VectorFormat vform,
21525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
21535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src1,
21545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src2,
21555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int index);
21565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmlsl(VectorFormat vform,
21575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
21585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
21595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
21605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int index);
21615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmlsl2(VectorFormat vform,
21625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
21635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src1,
21645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src2,
21655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int index);
21665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmulh(VectorFormat vform,
21675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
21685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
21695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
21705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int index);
21715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrdmulh(VectorFormat vform,
21725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
21735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src1,
21745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src2,
21755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int index);
21765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sub(VectorFormat vform,
21775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
21785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
21795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
21805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister and_(VectorFormat vform,
21815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
21825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
21835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
21845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister orr(VectorFormat vform,
21855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
21865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
21875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
21885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister orn(VectorFormat vform,
21895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
21905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
21915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
21925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister eor(VectorFormat vform,
21935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
21945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
21955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
21965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister bic(VectorFormat vform,
21975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
21985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
21995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
22005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister bic(VectorFormat vform,
22015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
22035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     uint64_t imm);
22045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister bif(VectorFormat vform,
22055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
22075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
22085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister bit(VectorFormat vform,
22095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
22115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
22125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister bsl(VectorFormat vform,
22135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
22155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2);
22165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister cls(VectorFormat vform,
22175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
22195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister clz(VectorFormat vform,
22205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
22225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister cnt(VectorFormat vform,
22235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
22255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister not_(VectorFormat vform,
22265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
22275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
22285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rbit(VectorFormat vform,
22295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
22305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
22315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rev(VectorFormat vform,
22325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
22345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int revSize);
22355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rev16(VectorFormat vform,
22365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
22375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
22385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rev32(VectorFormat vform,
22395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
22405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
22415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rev64(VectorFormat vform,
22425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
22435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
22445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister addlp(VectorFormat vform,
22455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
22465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
22475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       bool is_signed,
22485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       bool do_accumulate);
22495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddlp(VectorFormat vform,
22505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
22515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
22525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddlp(VectorFormat vform,
22535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
22545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
22555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sadalp(VectorFormat vform,
22565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
22575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
22585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uadalp(VectorFormat vform,
22595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
22605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
22615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ext(VectorFormat vform,
22625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src1,
22645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src2,
22655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int index);
22665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ins_element(VectorFormat vform,
22675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             LogicVRegister dst,
22685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             int dst_index,
22695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             const LogicVRegister& src,
22705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             int src_index);
22715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ins_immediate(VectorFormat vform,
22725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               int dst_index,
22745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               uint64_t imm);
22755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister dup_element(VectorFormat vform,
22765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             LogicVRegister dst,
22775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             const LogicVRegister& src,
22785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                             int src_index);
22795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister dup_immediate(VectorFormat vform,
22805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
22815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               uint64_t imm);
22820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm);
22830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm);
22845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister orr(VectorFormat vform,
22855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
22865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
22875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     uint64_t imm);
22885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sshl(VectorFormat vform,
22895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
22905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
22915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
22925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ushl(VectorFormat vform,
22935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
22945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
22955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
22965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sminmax(VectorFormat vform,
22975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
22985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
22995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
23005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         bool max);
23015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smax(VectorFormat vform,
23020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      LogicVRegister dst,
23030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src1,
23040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src2);
23055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smin(VectorFormat vform,
23060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      LogicVRegister dst,
23070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src1,
23080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src2);
23095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sminmaxp(VectorFormat vform,
23105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
2311b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                          const LogicVRegister& src1,
2312b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                          const LogicVRegister& src2,
23135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          bool max);
23145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smaxp(VectorFormat vform,
23155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
23175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
23185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sminp(VectorFormat vform,
23195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
23215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
23225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister addp(VectorFormat vform,
23235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
23245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
23255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister addv(VectorFormat vform,
23265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
23275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
23285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddlv(VectorFormat vform,
23295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
23305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
23315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddlv(VectorFormat vform,
23325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
23335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
23345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sminmaxv(VectorFormat vform,
23355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
23365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
23375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          bool max);
23385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister smaxv(VectorFormat vform,
23395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
23415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sminv(VectorFormat vform,
23425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
23445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uxtl(VectorFormat vform,
23455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
23465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
23475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uxtl2(VectorFormat vform,
23485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
23505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sxtl(VectorFormat vform,
23515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
23525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
23535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sxtl2(VectorFormat vform,
23545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
23555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
23565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbl(VectorFormat vform,
23575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
23605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbl(VectorFormat vform,
23615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
23645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
23655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbl(VectorFormat vform,
23665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
23695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab3,
23705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
23715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbl(VectorFormat vform,
23725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
23755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab3,
23765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab4,
23775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
2378b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell  LogicVRegister Table(VectorFormat vform,
2379b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       LogicVRegister dst,
2380b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       const LogicVRegister& ind,
2381b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       bool zero_out_of_bounds,
2382b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       const LogicVRegister* tab1,
2383b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       const LogicVRegister* tab2 = NULL,
2384b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       const LogicVRegister* tab3 = NULL,
2385b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                       const LogicVRegister* tab4 = NULL);
23865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbx(VectorFormat vform,
23875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
23905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbx(VectorFormat vform,
23915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
23945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
23955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbx(VectorFormat vform,
23965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
23975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
23985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
23995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab3,
24005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
24015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister tbx(VectorFormat vform,
24025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
24035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab,
24045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab2,
24055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab3,
24065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& tab4,
24075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& ind);
24085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddl(VectorFormat vform,
24095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddl2(VectorFormat vform,
24135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddw(VectorFormat vform,
24175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaddw2(VectorFormat vform,
24215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddl(VectorFormat vform,
24255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddl2(VectorFormat vform,
24295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddw(VectorFormat vform,
24335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saddw2(VectorFormat vform,
24375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usubl(VectorFormat vform,
24410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       LogicVRegister dst,
24420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       const LogicVRegister& src1,
24430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       const LogicVRegister& src2);
24445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usubl2(VectorFormat vform,
24455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usubw(VectorFormat vform,
24495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usubw2(VectorFormat vform,
24535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ssubl(VectorFormat vform,
24575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ssubl2(VectorFormat vform,
24615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ssubw(VectorFormat vform,
24655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ssubw2(VectorFormat vform,
24695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
24705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
24715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
24725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uminmax(VectorFormat vform,
24735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
24745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
24755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
24765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         bool max);
24775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umax(VectorFormat vform,
24780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      LogicVRegister dst,
24790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src1,
24800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src2);
24815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umin(VectorFormat vform,
24820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      LogicVRegister dst,
24830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src1,
24840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                      const LogicVRegister& src2);
24855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uminmaxp(VectorFormat vform,
24865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
2487b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                          const LogicVRegister& src1,
2488b953ea8255b36e27834f17941429cd17af12f6f2Martyn Capewell                          const LogicVRegister& src2,
24895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          bool max);
24905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umaxp(VectorFormat vform,
24915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uminp(VectorFormat vform,
24955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
24965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
24975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
24985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uminmaxv(VectorFormat vform,
24995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
25005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
25015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          bool max);
25025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister umaxv(VectorFormat vform,
25035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
25055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uminv(VectorFormat vform,
25065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
25085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister trn1(VectorFormat vform,
25095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister trn2(VectorFormat vform,
25135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister zip1(VectorFormat vform,
25175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister zip2(VectorFormat vform,
25215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uzp1(VectorFormat vform,
25255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uzp2(VectorFormat vform,
25295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
25315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
25325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shl(VectorFormat vform,
25335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
25345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
25355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int shift);
25365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister scvtf(VectorFormat vform,
25375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int fbits,
25405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       FPRounding rounding_mode);
25415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ucvtf(VectorFormat vform,
25425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int fbits,
25455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       FPRounding rounding_mode);
25465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sshll(VectorFormat vform,
25475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
25505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sshll2(VectorFormat vform,
25515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
25525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
25535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
25545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shll(VectorFormat vform,
25555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
25575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shll2(VectorFormat vform,
25585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
25605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ushll(VectorFormat vform,
25615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
25645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ushll2(VectorFormat vform,
25655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
25665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
25675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
25685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sli(VectorFormat vform,
25695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
25705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
25715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int shift);
25725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sri(VectorFormat vform,
25735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
25745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src,
25755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     int shift);
25765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sshr(VectorFormat vform,
25775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src,
25795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int shift);
25805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ushr(VectorFormat vform,
25815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src,
25835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int shift);
25845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ssra(VectorFormat vform,
25855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src,
25875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int shift);
25885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usra(VectorFormat vform,
25895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
25905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src,
25915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int shift);
25925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister srsra(VectorFormat vform,
25935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
25965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ursra(VectorFormat vform,
25975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
25985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
25995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
26005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister suqadd(VectorFormat vform,
26010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                        LogicVRegister dst,
26020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                        const LogicVRegister& src);
26035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister usqadd(VectorFormat vform,
26040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                        LogicVRegister dst,
26050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                        const LogicVRegister& src);
26065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshl(VectorFormat vform,
26075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
26085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
26095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
26105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqshl(VectorFormat vform,
26115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
26125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
26135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
26145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshlu(VectorFormat vform,
26155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
26165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
26175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
26185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister abs(VectorFormat vform,
26195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
26205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
26215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister neg(VectorFormat vform,
26225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
26235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
26245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister extractnarrow(VectorFormat vform,
26255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               LogicVRegister dst,
26265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               bool dstIsSigned,
26275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               const LogicVRegister& src,
26285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                               bool srcIsSigned);
26295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister xtn(VectorFormat vform,
26305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     LogicVRegister dst,
26315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                     const LogicVRegister& src);
26325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqxtn(VectorFormat vform,
26335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
26345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
26355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqxtn(VectorFormat vform,
26365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
26375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
26385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqxtun(VectorFormat vform,
26395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
26405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
26415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister absdiff(VectorFormat vform,
26425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
26435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
26445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
26455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         bool issigned);
26465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister saba(VectorFormat vform,
26475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
26485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
26495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
26505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uaba(VectorFormat vform,
26515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
26525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
26535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
26545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shrn(VectorFormat vform,
26555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
26565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src,
26575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      int shift);
26585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister shrn2(VectorFormat vform,
26590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       LogicVRegister dst,
26600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       const LogicVRegister& src,
26610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                       int shift);
26625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rshrn(VectorFormat vform,
26635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
26645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
26655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int shift);
26665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister rshrn2(VectorFormat vform,
26675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
26685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
26695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
26705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqshrn(VectorFormat vform,
26715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
26725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
26735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
26745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqshrn2(VectorFormat vform,
26755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
26765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src,
26775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int shift);
26785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqrshrn(VectorFormat vform,
26795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
26805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src,
26815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int shift);
26825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister uqrshrn2(VectorFormat vform,
26835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
26845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
26855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int shift);
26865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshrn(VectorFormat vform,
26875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
26885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
26895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        int shift);
26905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshrn2(VectorFormat vform,
26915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
26925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src,
26935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int shift);
26945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrshrn(VectorFormat vform,
26955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
26965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src,
26975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int shift);
26985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrshrn2(VectorFormat vform,
26995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
27005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
27015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int shift);
27025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshrun(VectorFormat vform,
27035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
27045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src,
27055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         int shift);
27065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqshrun2(VectorFormat vform,
27075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
27085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
27095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int shift);
27105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrshrun(VectorFormat vform,
27115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
27125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
27135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          int shift);
27145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrshrun2(VectorFormat vform,
27155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           LogicVRegister dst,
27165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           const LogicVRegister& src,
27175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           int shift);
27185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqrdmulh(VectorFormat vform,
27195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
27205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src1,
27215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src2,
27225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          bool round = true);
27235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister sqdmulh(VectorFormat vform,
27245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
27255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
27265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2);
27270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define NEON_3VREG_LOGIC_LIST(V) \
27280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(addhn)                       \
27290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(addhn2)                      \
27300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(raddhn)                      \
27310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(raddhn2)                     \
27320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(subhn)                       \
27330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(subhn2)                      \
27340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(rsubhn)                      \
27350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(rsubhn2)                     \
27360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(pmull)                       \
27370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(pmull2)                      \
27380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sabal)                       \
27390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sabal2)                      \
27400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(uabal)                       \
27410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(uabal2)                      \
27420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sabdl)                       \
27430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sabdl2)                      \
27440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(uabdl)                       \
27450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(uabdl2)                      \
27460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smull)                       \
27470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smull2)                      \
27480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umull)                       \
27490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umull2)                      \
27500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smlal)                       \
27510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smlal2)                      \
27520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umlal)                       \
27530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umlal2)                      \
27540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smlsl)                       \
27550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(smlsl2)                      \
27560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umlsl)                       \
27570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(umlsl2)                      \
27580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmlal)                     \
27590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmlal2)                    \
27600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmlsl)                     \
27610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmlsl2)                    \
27620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmull)                     \
27630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(sqdmull2)
27640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
27650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DEFINE_LOGIC_FUNC(FXN)                   \
27660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister FXN(VectorFormat vform,         \
27670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     LogicVRegister dst,         \
27680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     const LogicVRegister& src1, \
27690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     const LogicVRegister& src2);
27705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC)
27710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef DEFINE_LOGIC_FUNC
27720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
27730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define NEON_FP3SAME_LIST(V) \
27740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fadd, FPAdd, false)      \
27750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fsub, FPSub, true)       \
27760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmul, FPMul, true)       \
27770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmulx, FPMulx, true)     \
27780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fdiv, FPDiv, true)       \
27790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmax, FPMax, false)      \
27800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmin, FPMin, false)      \
27810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmaxnm, FPMaxNM, false)  \
27820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fminnm, FPMinNM, false)
27830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
27840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN) \
27850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  template <typename T>                            \
27860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister FN(VectorFormat vform,            \
27870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    LogicVRegister dst,            \
27880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    const LogicVRegister& src1,    \
27890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    const LogicVRegister& src2);   \
27900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister FN(VectorFormat vform,            \
27910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    LogicVRegister dst,            \
27920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    const LogicVRegister& src1,    \
27930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                    const LogicVRegister& src2);
27945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP)
27950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef DECLARE_NEON_FP_VECTOR_OP
27960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
27970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define NEON_FPPAIRWISE_LIST(V) \
27980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(faddp, fadd, FPAdd)         \
27990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmaxp, fmax, FPMax)         \
28000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fmaxnmp, fmaxnm, FPMaxNM)   \
28010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fminp, fmin, FPMin)         \
28020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  V(fminnmp, fminnm, FPMinNM)
28030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl
28040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)      \
28050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister FNP(VectorFormat vform,          \
28060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     LogicVRegister dst,          \
28070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     const LogicVRegister& src1,  \
28080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     const LogicVRegister& src2); \
28090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  LogicVRegister FNP(VectorFormat vform,          \
28100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     LogicVRegister dst,          \
28110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl                     const LogicVRegister& src);
28125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP)
28130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef DECLARE_NEON_FP_PAIR_OP
28145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frecps(VectorFormat vform,
28175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
28185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
28195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
28205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frecps(VectorFormat vform,
28215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
28225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src1,
28235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src2);
28245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frsqrts(VectorFormat vform,
28265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
28275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
28285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2);
28295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frsqrts(VectorFormat vform,
28305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
28315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
28325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2);
28335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmla(VectorFormat vform,
28355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
28385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmla(VectorFormat vform,
28395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
28425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmls(VectorFormat vform,
28445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
28475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmls(VectorFormat vform,
28485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
28515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fnmul(VectorFormat vform,
28525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
28535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src1,
28545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src2);
28555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcmp(VectorFormat vform,
28585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2,
28615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      Condition cond);
28625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcmp(VectorFormat vform,
28635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
28655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2,
28665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      Condition cond);
28675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fabscmp(VectorFormat vform,
28685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
28695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src1,
28705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src2,
28715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         Condition cond);
28725289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcmp_zero(VectorFormat vform,
28735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           LogicVRegister dst,
28745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           const LogicVRegister& src,
28755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                           Condition cond);
28765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
28775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fneg(VectorFormat vform,
28795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28805289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
28815289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fneg(VectorFormat vform,
28825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
28835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src);
28845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frecpx(VectorFormat vform,
28865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
28875289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
28885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frecpx(VectorFormat vform,
28895289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
28905289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
28915289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
28925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fabs_(VectorFormat vform,
28935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
28945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
28955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fabs_(VectorFormat vform,
28965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
28975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
28985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fabd(VectorFormat vform,
28995289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      LogicVRegister dst,
29005289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src1,
29015289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                      const LogicVRegister& src2);
29025289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frint(VectorFormat vform,
29035289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29045289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
29055289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       FPRounding rounding_mode,
29065289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       bool inexact_exception = false);
29075289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvts(VectorFormat vform,
29085289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29095289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
29105289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       FPRounding rounding_mode,
29115289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int fbits = 0);
29125289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtu(VectorFormat vform,
29135289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29145289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src,
29155289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       FPRounding rounding_mode,
29165289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       int fbits = 0);
29175289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtl(VectorFormat vform,
29185289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29195289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
29205289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtl2(VectorFormat vform,
29215289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
29225289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
29235289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtn(VectorFormat vform,
29245289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29255289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
29265289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtn2(VectorFormat vform,
29275289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
29285289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
29295289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtxn(VectorFormat vform,
29305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
29315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
29325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fcvtxn2(VectorFormat vform,
29335289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
29345289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src);
29355289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fsqrt(VectorFormat vform,
29365289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29375289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
29385289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frsqrte(VectorFormat vform,
29395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
29405289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src);
29415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister frecpe(VectorFormat vform,
29425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
29435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src,
29445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        FPRounding rounding);
29455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister ursqrte(VectorFormat vform,
29465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
29475289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src);
29485289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister urecpe(VectorFormat vform,
29495289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        LogicVRegister dst,
29505289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                        const LogicVRegister& src);
29515289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29525289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  typedef float (Simulator::*FPMinMaxOp)(float a, float b);
29535289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29545289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fminmaxv(VectorFormat vform,
29555289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          LogicVRegister dst,
29565289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          const LogicVRegister& src,
29575289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                          FPMinMaxOp Op);
29585289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29595289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fminv(VectorFormat vform,
29605289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29615289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
29625289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmaxv(VectorFormat vform,
29635289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       LogicVRegister dst,
29645289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                       const LogicVRegister& src);
29655289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fminnmv(VectorFormat vform,
29665289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
29675289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src);
29685289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  LogicVRegister fmaxnmv(VectorFormat vform,
29695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         LogicVRegister dst,
29705289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl                         const LogicVRegister& src);
29715289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  static const uint32_t CRC32_POLY = 0x04C11DB7;
29735289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  static const uint32_t CRC32C_POLY = 0x1EDC6F41;
29745289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint32_t Poly32Mod2(unsigned n, uint64_t data, uint32_t poly);
29755289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
29765289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint32_t Crc32Checksum(uint32_t acc, T val, uint32_t poly);
29775289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  uint32_t Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly);
29785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
29795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  void SysOp_W(int op, int64_t val);
2980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2981b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
29825289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T FPRecipSqrtEstimate(T op);
29835289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
29845289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T FPRecipEstimate(T op, FPRounding rounding);
29855289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T, typename R>
29865289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding);
2987b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
29886e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  void FPCompare(double val0, double val1, FPTrapFlags trap);
2989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  double FPRoundInt(double value, FPRounding round_mode);
2990578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  double FPToDouble(float value);
2991578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  float FPToFloat(double value, FPRounding round_mode);
29925289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float FPToFloat(float16 value);
29935289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float16 FPToFloat16(float value, FPRounding round_mode);
29945289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  float16 FPToFloat16(double value, FPRounding round_mode);
29955289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double recip_sqrt_estimate(double a);
29965289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double recip_estimate(double a);
29975289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double FPRecipSqrtEstimate(double a);
29985289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  double FPRecipEstimate(double a);
2999578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  double FixedToDouble(int64_t src, int fbits, FPRounding round_mode);
3000578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode);
3001578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  float FixedToFloat(int64_t src, int fbits, FPRounding round_mode);
3002578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode);
3003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int32_t FPToInt32(double value, FPRounding rmode);
3004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int64_t FPToInt64(double value, FPRounding rmode);
3005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t FPToUInt32(double value, FPRounding rmode);
3006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t FPToUInt64(double value, FPRounding rmode);
3007f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
3008f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  template <typename T>
3009b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPAdd(T op1, T op2);
3010f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
3011f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  template <typename T>
3012b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPDiv(T op1, T op2);
3013b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3014b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
3015b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPMax(T a, T b);
3016f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
3017f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  template <typename T>
3018f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  T FPMaxNM(T a, T b);
3019f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
3020f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  template <typename T>
3021b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPMin(T a, T b);
3022b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3023b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
3024f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  T FPMinNM(T a, T b);
3025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3026b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
3027b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPMul(T op1, T op2);
3028b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3029b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
30305289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T FPMulx(T op1, T op2);
30315289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30325289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
3033b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPMulAdd(T a, T op1, T op2);
3034b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3035b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
3036b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPSqrt(T op);
3037b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3038b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  template <typename T>
3039b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  T FPSub(T op1, T op2);
3040b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
30415289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
30425289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T FPRecipStepFused(T op1, T op2);
30435289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
30445289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  template <typename T>
30455289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  T FPRSqrtStepFused(T op1, T op2);
30465289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl
3047b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  // This doesn't do anything at the moment. We'll need it if we want support
3048b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl  // for cumulative exception bits or floating-point exceptions.
30490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  void FPProcessException() {}
3050b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3051c68cb64496485710cdb5b8480f8fee287058c93farmvixl  bool FPProcessNaNs(const Instruction* instr);
3052b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl
3053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Pseudo Printf instruction
3054c68cb64496485710cdb5b8480f8fee287058c93farmvixl  void DoPrintf(const Instruction* instr);
3055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3056064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// Simulate a runtime call.
3057ca73ba046c11d65b6dce59cfd26847d14aba06abAlexandre Rames#ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
3058064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  VIXL_NO_RETURN_IN_DEBUG_MODE
3059064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
3060064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames  void DoRuntimeCall(const Instruction* instr);
3061064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
3062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Processor state ---------------------------------------
3063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
30644a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Simulated monitors for exclusive access instructions.
30654a102baf640077d6794c0b33bb976f94b86c532barmvixl  SimExclusiveLocalMonitor local_monitor_;
30664a102baf640077d6794c0b33bb976f94b86c532barmvixl  SimExclusiveGlobalMonitor global_monitor_;
30674a102baf640077d6794c0b33bb976f94b86c532barmvixl
3068ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Output stream.
3069ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FILE* stream_;
3070ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  PrintDisassembler* print_disasm_;
3071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3072578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Instruction statistics instrumentation.
3073578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  Instrument* instrumentation_;
3074578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
3075ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // General purpose registers. Register 31 is the stack pointer.
3076ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  SimRegister registers_[kNumberOfRegisters];
3077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
30785289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  // Vector registers
30795289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl  SimVRegister vregisters_[kNumberOfVRegisters];
3080ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3081ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Program Status Register.
3082ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits[31, 27]: Condition flags N, Z, C, and V.
3083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //               (Negative, Zero, Carry, Overflow)
3084578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  SimSystemRegister nzcv_;
3085578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
3086578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Floating-Point Control Register
3087578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  SimSystemRegister fpcr_;
3088578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
3089578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Only a subset of FPCR features are supported by the simulator. This helper
3090578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // checks that the FPCR settings are supported.
3091578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  //
3092578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // This is checked when floating-point instructions are executed, not when
3093578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // FPCR is set. This allows generated code to modify FPCR for external
3094578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // functions, or to save and restore it when entering and leaving generated
3095578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // code.
3096578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  void AssertSupportedFPCR() {
309788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    // No flush-to-zero support.
309888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    VIXL_ASSERT(ReadFpcr().GetFZ() == 0);
309988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    // Ties-to-even rounding only.
310088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    VIXL_ASSERT(ReadFpcr().GetRMode() == FPTieEven);
3101578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
310288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    // The simulator does not support half-precision operations so
310388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    // GetFpcr().AHP() is irrelevant, and is not checked here.
3104578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
3105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3106330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  static int CalcNFlag(uint64_t result, unsigned reg_size) {
3107578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    return (result >> (reg_size - 1)) & 1;
3108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
3109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
31100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl  static int CalcZFlag(uint64_t result) { return (result == 0) ? 1 : 0; }
3111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const uint32_t kConditionFlagsMask = 0xf0000000;
3113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Stack
3115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  byte* stack_;
3116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const int stack_protection_size_ = 256;
3117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 2 KB stack.
3118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
3119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  byte* stack_limit_;
3120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Decoder* decoder_;
3122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Indicates if the pc has been modified by the instruction and should not be
3123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // automatically incremented.
3124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool pc_modified_;
3125c68cb64496485710cdb5b8480f8fee287058c93farmvixl  const Instruction* pc_;
3126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* xreg_names[];
3128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* wreg_names[];
3129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* sreg_names[];
3130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* dreg_names[];
3131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  static const char* vreg_names[];
3132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private:
31346e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  template <typename T>
31356e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  static T FPDefaultNaN();
31366e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
31376e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  // Standard NaN processing.
31386e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  template <typename T>
31396e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  T FPProcessNaN(T op) {
31406e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    VIXL_ASSERT(std::isnan(op));
31416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (IsSignallingNaN(op)) {
31426e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      FPProcessException();
31436e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
314488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois    return ReadDN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
31456e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
31466e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
31476e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  template <typename T>
31486e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  T FPProcessNaNs(T op1, T op2) {
31496e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (IsSignallingNaN(op1)) {
31506e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op1);
31516e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (IsSignallingNaN(op2)) {
31526e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op2);
31536e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnan(op1)) {
31546e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(IsQuietNaN(op1));
31556e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op1);
31566e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnan(op2)) {
31576e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(IsQuietNaN(op2));
31586e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op2);
31596e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else {
31606e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return 0.0;
31616e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
31626e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
31636e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
31646e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  template <typename T>
31656e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  T FPProcessNaNs3(T op1, T op2, T op3) {
31666e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    if (IsSignallingNaN(op1)) {
31676e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op1);
31686e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (IsSignallingNaN(op2)) {
31696e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op2);
31706e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (IsSignallingNaN(op3)) {
31716e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op3);
31726e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnan(op1)) {
31736e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(IsQuietNaN(op1));
31746e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op1);
31756e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnan(op2)) {
31766e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(IsQuietNaN(op2));
31776e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op2);
31786e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else if (std::isnan(op3)) {
31796e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      VIXL_ASSERT(IsQuietNaN(op3));
31806e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return FPProcessNaN(op3);
31816e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    } else {
31826e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl      return 0.0;
31836e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl    }
31846e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl  }
31856e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl
3186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool coloured_trace_;
3187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
3188330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  // A set of TraceParameters flags.
3189330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl  int trace_parameters_;
3190578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
3191578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // Indicates whether the instruction instrumentation is active.
3192578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  bool instruction_stats_;
31934a102baf640077d6794c0b33bb976f94b86c532barmvixl
31944a102baf640077d6794c0b33bb976f94b86c532barmvixl  // Indicates whether the exclusive-access warning has been printed.
31954a102baf640077d6794c0b33bb976f94b86c532barmvixl  bool print_exclusive_access_warning_;
31964a102baf640077d6794c0b33bb976f94b86c532barmvixl  void PrintExclusiveAccessWarning();
3197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
3198064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
3199482d4df29d1466ff87d94e74034f1a8659f1b354Jacob Bramley#if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
3200064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// Base case of the recursive template used to emulate C++14
3201064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames// `std::index_sequence`.
3202064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Ramestemplate <size_t... I>
3203064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Ramesstruct Simulator::emulated_make_index_sequence_helper<0, I...>
3204064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames    : Simulator::emulated_index_sequence<I...> {};
3205064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames#endif
3206064e02d4e85938b2e2be4d4b37a2691b2e015ebbAlexandre Rames
320788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}  // namespace aarch64
3208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
3209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3210a4055d25c688d1397fc369a40abf57fa4f1ab805Pierre Langlois#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
3211a4055d25c688d1397fc369a40abf57fa4f1ab805Pierre Langlois
3212d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#endif  // VIXL_AARCH64_SIMULATOR_AARCH64_H_
3213