10cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Copyright 2015, ARM Limited
20cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// All rights reserved.
30cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
40cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Redistribution and use in source and binary forms, with or without
50cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// modification, are permitted provided that the following conditions are met:
60cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
70cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Redistributions of source code must retain the above copyright notice,
80cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     this list of conditions and the following disclaimer.
90cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     this list of conditions and the following disclaimer in the documentation
110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     and/or other materials provided with the distribution.
120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     used to endorse or promote products derived from this software without
140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//     specific prior written permission.
150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include <cmath>
290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/assembler-a64.h"
300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlnamespace vixl {
320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// CPURegList utilities.
340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegister CPURegList::PopLowestIndex() {
350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (IsEmpty()) {
360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return NoCPUReg;
370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int index = CountTrailingZeros(list_);
390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((1 << index) & list_);
400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Remove(index);
410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return CPURegister(index, size_, type_);
420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegister CPURegList::PopHighestIndex() {
460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValid());
470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (IsEmpty()) {
480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return NoCPUReg;
490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int index = CountLeadingZeros(list_);
510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  index = kRegListSizeInBits - 1 - index;
520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((1 << index) & list_);
530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Remove(index);
540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return CPURegister(index, size_, type_);
550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool CPURegList::IsValid() const {
590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((type_ == CPURegister::kRegister) ||
600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (type_ == CPURegister::kVRegister)) {
610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool is_valid = true;
620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Try to create a CPURegister for each element in the list.
630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < kRegListSizeInBits; i++) {
640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (((list_ >> i) & 1) != 0) {
650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        is_valid &= CPURegister(i, size_, type_).IsValid();
660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return is_valid;
690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (type_ == CPURegister::kNoRegister) {
700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // We can't use IsEmpty here because that asserts IsValid().
710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return list_ == 0;
720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid CPURegList::RemoveCalleeSaved() {
790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (type() == CPURegister::kRegister) {
800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Remove(GetCalleeSaved(RegisterSizeInBits()));
810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (type() == CPURegister::kVRegister) {
820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Remove(GetCalleeSavedV(RegisterSizeInBits()));
830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(type() == CPURegister::kNoRegister);
850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(IsEmpty());
860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // The list must already be empty, so do nothing.
870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
910cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::Union(const CPURegList& list_1,
920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const CPURegList& list_2,
930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const CPURegList& list_3) {
940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Union(list_1, Union(list_2, list_3));
950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
980cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::Union(const CPURegList& list_1,
990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const CPURegList& list_2,
1000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const CPURegList& list_3,
1010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const CPURegList& list_4) {
1020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Union(Union(list_1, list_2), Union(list_3, list_4));
1030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1060cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::Intersection(const CPURegList& list_1,
1070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const CPURegList& list_2,
1080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const CPURegList& list_3) {
1090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Intersection(list_1, Intersection(list_2, list_3));
1100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1130cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::Intersection(const CPURegList& list_1,
1140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const CPURegList& list_2,
1150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const CPURegList& list_3,
1160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const CPURegList& list_4) {
1170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Intersection(Intersection(list_1, list_2),
1180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Intersection(list_3, list_4));
1190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::GetCalleeSaved(unsigned size) {
1230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return CPURegList(CPURegister::kRegister, size, 19, 29);
1240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::GetCalleeSavedV(unsigned size) {
1280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return CPURegList(CPURegister::kVRegister, size, 8, 15);
1290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::GetCallerSaved(unsigned size) {
1330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Registers x0-x18 and lr (x30) are caller-saved.
1340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18);
135dc661669ef2e2fd18c4e21333d6a12112b520436Pirama Arumuga Nainar  // Temporary workaround for bug 21273194: Create a Register object equivalent
136dc661669ef2e2fd18c4e21333d6a12112b520436Pirama Arumuga Nainar  // to register lr (x30)
137dc661669ef2e2fd18c4e21333d6a12112b520436Pirama Arumuga Nainar  // list.Combine(lr);
138dc661669ef2e2fd18c4e21333d6a12112b520436Pirama Arumuga Nainar  list.Combine(Register(30, size));
1390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return list;
1400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlCPURegList CPURegList::GetCallerSavedV(unsigned size) {
1440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Registers d0-d7 and d16-d31 are caller-saved.
1450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  CPURegList list = CPURegList(CPURegister::kVRegister, size, 0, 7);
1460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  list.Combine(CPURegList(CPURegister::kVRegister, size, 16, 31));
1470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return list;
1480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
1490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst CPURegList kCalleeSaved = CPURegList::GetCalleeSaved();
1520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst CPURegList kCalleeSavedV = CPURegList::GetCalleeSavedV();
1530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst CPURegList kCallerSaved = CPURegList::GetCallerSaved();
1540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst CPURegList kCallerSavedV = CPURegList::GetCallerSavedV();
1550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Registers.
1580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define WREG(n) w##n,
1590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register Register::wregisters[] = {
1600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(WREG)
1610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef WREG
1630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define XREG(n) x##n,
1650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register Register::xregisters[] = {
1660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(XREG)
1670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef XREG
1690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define BREG(n) b##n,
1710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::bregisters[] = {
1720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(BREG)
1730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef BREG
1750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define HREG(n) h##n,
1770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::hregisters[] = {
1780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(HREG)
1790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef HREG
1810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define SREG(n) s##n,
1830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::sregisters[] = {
1840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(SREG)
1850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef SREG
1870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DREG(n) d##n,
1890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::dregisters[] = {
1900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(DREG)
1910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DREG
1930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
1940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define QREG(n) q##n,
1950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::qregisters[] = {
1960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(QREG)
1970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
1980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef QREG
1990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define VREG(n) v##n,
2010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister VRegister::vregisters[] = {
2020cc8b6ece4b3e757e11a906a81ece292437713abarmvixlREGISTER_CODE_LIST(VREG)
2030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl};
2040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef VREG
2050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register& Register::WRegFromCode(unsigned code) {
2080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (code == kSPRegInternalCode) {
2090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return wsp;
2100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
2110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(code < kNumberOfRegisters);
2120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return wregisters[code];
2130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
2140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register& Register::XRegFromCode(unsigned code) {
2180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (code == kSPRegInternalCode) {
2190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return sp;
2200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
2210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(code < kNumberOfRegisters);
2220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return xregisters[code];
2230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
2240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::BRegFromCode(unsigned code) {
2280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return bregisters[code];
2300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::HRegFromCode(unsigned code) {
2340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return hregisters[code];
2360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::SRegFromCode(unsigned code) {
2400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return sregisters[code];
2420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::DRegFromCode(unsigned code) {
2460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return dregisters[code];
2480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::QRegFromCode(unsigned code) {
2520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return qregisters[code];
2540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& VRegister::VRegFromCode(unsigned code) {
2580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(code < kNumberOfVRegisters);
2590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return vregisters[code];
2600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register& CPURegister::W() const {
2640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidRegister());
2650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Register::WRegFromCode(code_);
2660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst Register& CPURegister::X() const {
2700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidRegister());
2710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Register::XRegFromCode(code_);
2720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2750cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::B() const {
2760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
2770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::BRegFromCode(code_);
2780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::H() const {
2820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
2830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::HRegFromCode(code_);
2840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::S() const {
2880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
2890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::SRegFromCode(code_);
2900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::D() const {
2940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
2950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::DRegFromCode(code_);
2960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
2970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
2990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::Q() const {
3000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
3010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::QRegFromCode(code_);
3020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlconst VRegister& CPURegister::V() const {
3060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsValidVRegister());
3070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return VRegister::VRegFromCode(code_);
3080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Operand.
3120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlOperand::Operand(int64_t immediate)
3130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    : immediate_(immediate),
3140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      reg_(NoReg),
3150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_(NO_SHIFT),
3160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      extend_(NO_EXTEND),
3170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_amount_(0) {}
3180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlOperand::Operand(Register reg, Shift shift, unsigned shift_amount)
3210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    : reg_(reg),
3220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_(shift),
3230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      extend_(NO_EXTEND),
3240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_amount_(shift_amount) {
3250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift != MSL);
3260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg.Is64Bits() || (shift_amount < kWRegSize));
3270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg.Is32Bits() || (shift_amount < kXRegSize));
3280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!reg.IsSP());
3290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlOperand::Operand(Register reg, Extend extend, unsigned shift_amount)
3330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    : reg_(reg),
3340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_(NO_SHIFT),
3350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      extend_(extend),
3360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift_amount_(shift_amount) {
3370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg.IsValid());
3380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift_amount <= 4);
3390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!reg.IsSP());
3400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Extend modes SXTX and UXTX require a 64-bit register.
3420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg.Is64Bits() || ((extend != SXTX) && (extend != UXTX)));
3430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Operand::IsImmediate() const {
3470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return reg_.Is(NoReg);
3480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Operand::IsShiftedRegister() const {
3520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return reg_.IsValid() && (shift_ != NO_SHIFT);
3530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Operand::IsExtendedRegister() const {
3570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return reg_.IsValid() && (extend_ != NO_EXTEND);
3580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Operand::IsZero() const {
3620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (IsImmediate()) {
3630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return immediate() == 0;
3640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
3650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return reg().IsZero();
3660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
3670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3700cc8b6ece4b3e757e11a906a81ece292437713abarmvixlOperand Operand::ToExtendedRegister() const {
3710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsShiftedRegister());
3720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift_ == LSL) && (shift_amount_ <= 4));
3730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return Operand(reg_, reg_.Is64Bits() ? UXTX : UXTW, shift_amount_);
3740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// MemOperand
3780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlMemOperand::MemOperand(Register base, int64_t offset, AddrMode addrmode)
3790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  : base_(base), regoffset_(NoReg), offset_(offset), addrmode_(addrmode) {
3800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
3810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlMemOperand::MemOperand(Register base,
3850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       Register regoffset,
3860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       Extend extend,
3870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       unsigned shift_amount)
3880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset),
3890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_(NO_SHIFT), extend_(extend), shift_amount_(shift_amount) {
3900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
3910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!regoffset.IsSP());
3920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((extend == UXTW) || (extend == SXTW) || (extend == SXTX));
3930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // SXTX extend mode requires a 64-bit offset register.
3950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(regoffset.Is64Bits() || (extend != SXTX));
3960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
3970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
3990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlMemOperand::MemOperand(Register base,
4000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       Register regoffset,
4010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       Shift shift,
4020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       unsigned shift_amount)
4030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset),
4040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_(shift), extend_(NO_EXTEND), shift_amount_(shift_amount) {
4050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
4060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(regoffset.Is64Bits() && !regoffset.IsSP());
4070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(shift == LSL);
4080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlMemOperand::MemOperand(Register base, const Operand& offset, AddrMode addrmode)
4120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  : base_(base), regoffset_(NoReg), addrmode_(addrmode) {
4130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
4140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (offset.IsImmediate()) {
4160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset_ = offset.immediate();
4170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (offset.IsShiftedRegister()) {
4180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((addrmode == Offset) || (addrmode == PostIndex));
4190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    regoffset_ = offset.reg();
4210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_ = offset.shift();
4220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_amount_ = offset.shift_amount();
4230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    extend_ = NO_EXTEND;
4250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset_ = 0;
4260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // These assertions match those in the shifted-register constructor.
4280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(regoffset_.Is64Bits() && !regoffset_.IsSP());
4290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(shift_ == LSL);
4300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
4310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(offset.IsExtendedRegister());
4320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(addrmode == Offset);
4330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    regoffset_ = offset.reg();
4350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    extend_ = offset.extend();
4360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_amount_ = offset.shift_amount();
4370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift_ = NO_SHIFT;
4390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset_ = 0;
4400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // These assertions match those in the extended-register constructor.
4420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(!regoffset_.IsSP());
4430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((extend_ == UXTW) || (extend_ == SXTW) || (extend_ == SXTX));
4440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((regoffset_.Is64Bits() || (extend_ != SXTX)));
4450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
4460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool MemOperand::IsImmediateOffset() const {
4500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return (addrmode_ == Offset) && regoffset_.Is(NoReg);
4510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool MemOperand::IsRegisterOffset() const {
4550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return (addrmode_ == Offset) && !regoffset_.Is(NoReg);
4560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool MemOperand::IsPreIndex() const {
4600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addrmode_ == PreIndex;
4610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4640cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool MemOperand::IsPostIndex() const {
4650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addrmode_ == PostIndex;
4660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid MemOperand::AddOffset(int64_t offset) {
4700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsImmediateOffset());
4710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  offset_ += offset;
4720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Assembler
4760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlAssembler::Assembler(byte* buffer, size_t capacity,
4770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     PositionIndependentCodeOption pic)
4780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    : pic_(pic) {
4790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#ifdef VIXL_DEBUG
4800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_monitor_ = 0;
4810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#endif
4820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_ = new CodeBuffer(buffer, capacity);
4830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlAssembler::Assembler(size_t capacity, PositionIndependentCodeOption pic)
4870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    : pic_(pic) {
4880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#ifdef VIXL_DEBUG
4890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_monitor_ = 0;
4900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#endif
4910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_ = new CodeBuffer(capacity);
4920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
4950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlAssembler::~Assembler() {
4960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(buffer_monitor_ == 0);
4970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  delete buffer_;
4980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
4990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::Reset() {
5020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_->Reset();
5030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5060cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FinalizeCode() {
5070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  buffer_->SetClean();
5080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bind(Label* label) {
5120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  BindToOffset(label, buffer_->CursorOffset());
5130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::BindToOffset(Label* label, ptrdiff_t offset) {
5170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((offset >= 0) && (offset <= buffer_->CursorOffset()));
5180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(offset % kInstructionSize == 0);
5190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  label->Bind(offset);
5210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (Label::LabelLinksIterator it(label); !it.Done(); it.Advance()) {
5230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instruction* link = GetOffsetAddress<Instruction*>(*it.Current());
5240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    link->SetImmPCOffsetTarget(GetLabelAddress<Instruction*>(label));
5250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  label->ClearAllLinks();
5270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// A common implementation for the LinkAndGet<Type>OffsetTo helpers.
5310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl//
5320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// The offset is calculated by aligning the PC and label addresses down to a
5330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// multiple of 1 << element_shift, then calculating the (scaled) offset between
5340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// them. This matches the semantics of adrp, for example.
5350cc8b6ece4b3e757e11a906a81ece292437713abarmvixltemplate <int element_shift>
5360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlptrdiff_t Assembler::LinkAndGetOffsetTo(Label* label) {
5370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_STATIC_ASSERT(element_shift < (sizeof(ptrdiff_t) * 8));
5380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (label->IsBound()) {
5400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uintptr_t pc_offset = GetCursorAddress<uintptr_t>() >> element_shift;
5410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uintptr_t label_offset =
5420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        GetLabelAddress<uintptr_t>(label) >> element_shift;
5430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return label_offset - pc_offset;
5440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
5450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    label->AddLink(buffer_->CursorOffset());
5460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return 0;
5470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlptrdiff_t Assembler::LinkAndGetByteOffsetTo(Label* label) {
5520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return LinkAndGetOffsetTo<0>(label);
5530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlptrdiff_t Assembler::LinkAndGetInstructionOffsetTo(Label* label) {
5570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return LinkAndGetOffsetTo<kInstructionSizeLog2>(label);
5580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlptrdiff_t Assembler::LinkAndGetPageOffsetTo(Label* label) {
5620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return LinkAndGetOffsetTo<kPageSizeLog2>(label);
5630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::place(RawLiteral* literal) {
5670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!literal->IsPlaced());
5680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Patch instructions using this literal.
5700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (literal->IsUsed()) {
5710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instruction* target = GetCursorAddress<Instruction*>();
5720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    ptrdiff_t offset = literal->last_use();
5730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool done;
5740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    do {
5750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      Instruction* ldr = GetOffsetAddress<Instruction*>(offset);
5760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(ldr->IsLoadLiteral());
5770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      ptrdiff_t imm19 = ldr->ImmLLiteral();
5790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(imm19 <= 0);
5800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      done = (imm19 == 0);
5810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      offset += imm19 * kLiteralEntrySize;
5820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      ldr->SetImmLLiteral(target);
5840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } while (!done);
5850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
5870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // "bind" the literal.
5880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  literal->set_offset(CursorOffset());
5890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Copy the data into the pool.
5900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (literal->size()) {
5910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kSRegSizeInBytes: dc32(literal->raw_value32()); break;
5920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case kDRegSizeInBytes: dc64(literal->raw_value64()); break;
5930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
5940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(literal->size() == kQRegSizeInBytes);
5950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dc64(literal->raw_value128_low64());
5960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      dc64(literal->raw_value128_high64());
5970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
5980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
5990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlptrdiff_t Assembler::LinkAndGetWordOffsetTo(RawLiteral* literal) {
6020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsWordAligned(CursorOffset()));
6030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (literal->IsPlaced()) {
6050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // The literal is "behind", the offset will be negative.
6060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((literal->offset() - CursorOffset()) <= 0);
6070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return (literal->offset() - CursorOffset()) >> kLiteralEntrySizeLog2;
6080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
6090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ptrdiff_t offset = 0;
6110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Link all uses together.
6120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (literal->IsUsed()) {
6130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    offset = (literal->last_use() - CursorOffset()) >> kLiteralEntrySizeLog2;
6140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
6150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  literal->set_last_use(CursorOffset());
6160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return offset;
6180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Code generation.
6220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::br(const Register& xn) {
6230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(xn.Is64Bits());
6240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(BR | Rn(xn));
6250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::blr(const Register& xn) {
6290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(xn.Is64Bits());
6300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(BLR | Rn(xn));
6310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ret(const Register& xn) {
6350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(xn.Is64Bits());
6360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(RET | Rn(xn));
6370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::b(int imm26) {
6410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(B | ImmUncondBranch(imm26));
6420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::b(int imm19, Condition cond) {
6460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(B_cond | ImmCondBranch(imm19) | cond);
6470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6500cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::b(Label* label) {
6510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  b(LinkAndGetInstructionOffsetTo(label));
6520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::b(Label* label, Condition cond) {
6560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  b(LinkAndGetInstructionOffsetTo(label), cond);
6570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bl(int imm26) {
6610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(BL | ImmUncondBranch(imm26));
6620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bl(Label* label) {
6660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bl(LinkAndGetInstructionOffsetTo(label));
6670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6700cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cbz(const Register& rt,
6710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int imm19) {
6720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rt) | CBZ | ImmCmpBranch(imm19) | Rt(rt));
6730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cbz(const Register& rt,
6770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    Label* label) {
6780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  cbz(rt, LinkAndGetInstructionOffsetTo(label));
6790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6820cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cbnz(const Register& rt,
6830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int imm19) {
6840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rt) | CBNZ | ImmCmpBranch(imm19) | Rt(rt));
6850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cbnz(const Register& rt,
6890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Label* label) {
6900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  cbnz(rt, LinkAndGetInstructionOffsetTo(label));
6910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
6920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
6940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONTable(const VRegister& vd,
6950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vn,
6960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vm,
6970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          NEONTableOp op) {
6980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is16B() || vd.Is8B());
6990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is16B());
7000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vm));
7010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | (vd.IsQ() ? NEON_Q : 0) | Rm(vm) | Rn(vn) | Rd(vd));
7020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbl(const VRegister& vd,
7060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBL_1v);
7090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbl(const VRegister& vd,
7130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2));
7180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
7190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBL_2v);
7210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbl(const VRegister& vd,
7250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn3,
7280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn3);
7310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2, vn3));
7320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
7330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn3.code() == ((vn.code() + 2) % kNumberOfVRegisters));
7340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBL_3v);
7360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbl(const VRegister& vd,
7400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn3,
7430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn4,
7440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn3);
7470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn4);
7480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2, vn3, vn4));
7490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
7500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn3.code() == ((vn.code() + 2) % kNumberOfVRegisters));
7510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn4.code() == ((vn.code() + 3) % kNumberOfVRegisters));
7520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBL_4v);
7540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbx(const VRegister& vd,
7580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBX_1v);
7610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7640cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbx(const VRegister& vd,
7650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2));
7700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
7710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBX_2v);
7730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbx(const VRegister& vd,
7770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn3,
7800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn3);
7830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2, vn3));
7840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
7850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn3.code() == ((vn.code() + 2) % kNumberOfVRegisters));
7860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBX_3v);
7880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
7890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
7910cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbx(const VRegister& vd,
7920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
7930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn2,
7940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn3,
7950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn4,
7960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm) {
7970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn2);
7980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn3);
7990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vn4);
8000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vn2, vn3, vn4));
8010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn2.code() == ((vn.code() + 1) % kNumberOfVRegisters));
8020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn3.code() == ((vn.code() + 2) % kNumberOfVRegisters));
8030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn4.code() == ((vn.code() + 3) % kNumberOfVRegisters));
8040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONTable(vd, vn, vm, NEON_TBX_4v);
8060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbz(const Register& rt,
8100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    unsigned bit_pos,
8110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int imm14) {
8120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSize)));
8130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(TBZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt));
8140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbz(const Register& rt,
8180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    unsigned bit_pos,
8190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    Label* label) {
8200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  tbz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label));
8210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbnz(const Register& rt,
8250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned bit_pos,
8260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int imm14) {
8270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSize)));
8280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(TBNZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt));
8290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tbnz(const Register& rt,
8330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned bit_pos,
8340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Label* label) {
8350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  tbnz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label));
8360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adr(const Register& rd, int imm21) {
8400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits());
8410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(ADR | ImmPCRelAddress(imm21) | Rd(rd));
8420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adr(const Register& rd, Label* label) {
8460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  adr(rd, LinkAndGetByteOffsetTo(label));
8470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8500cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adrp(const Register& rd, int imm21) {
8510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits());
8520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(ADRP | ImmPCRelAddress(imm21) | Rd(rd));
8530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adrp(const Register& rd, Label* label) {
8570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AllowPageOffsetDependentCode());
8580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  adrp(rd, LinkAndGetPageOffsetTo(label));
8590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::add(const Register& rd,
8630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
8640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
8650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSub(rd, rn, operand, LeaveFlags, ADD);
8660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adds(const Register& rd,
8700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
8710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
8720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSub(rd, rn, operand, SetFlags, ADD);
8730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmn(const Register& rn,
8770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
8780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rn);
8790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  adds(zr, rn, operand);
8800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sub(const Register& rd,
8840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
8850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
8860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSub(rd, rn, operand, LeaveFlags, SUB);
8870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::subs(const Register& rd,
8910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
8920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
8930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSub(rd, rn, operand, SetFlags, SUB);
8940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
8950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
8970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmp(const Register& rn, const Operand& operand) {
8980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rn);
8990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  subs(zr, rn, operand);
9000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::neg(const Register& rd, const Operand& operand) {
9040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
9050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sub(rd, zr, operand);
9060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::negs(const Register& rd, const Operand& operand) {
9100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
9110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  subs(rd, zr, operand);
9120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adc(const Register& rd,
9160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
9170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
9180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSubWithCarry(rd, rn, operand, LeaveFlags, ADC);
9190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::adcs(const Register& rd,
9230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
9240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
9250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSubWithCarry(rd, rn, operand, SetFlags, ADC);
9260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sbc(const Register& rd,
9300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
9310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
9320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSubWithCarry(rd, rn, operand, LeaveFlags, SBC);
9330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sbcs(const Register& rd,
9370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
9380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
9390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  AddSubWithCarry(rd, rn, operand, SetFlags, SBC);
9400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ngc(const Register& rd, const Operand& operand) {
9440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
9450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sbc(rd, zr, operand);
9460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ngcs(const Register& rd, const Operand& operand) {
9500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
9510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sbcs(rd, zr, operand);
9520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Logical instructions.
9560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::and_(const Register& rd,
9570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
9580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
9590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, AND);
9600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ands(const Register& rd,
9640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
9650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
9660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, ANDS);
9670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9700cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::tst(const Register& rn,
9710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
9720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ands(AppropriateZeroRegFor(rn), rn, operand);
9730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bic(const Register& rd,
9770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
9780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
9790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, BIC);
9800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bics(const Register& rd,
9840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
9850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand) {
9860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, BICS);
9870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::orr(const Register& rd,
9910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
9920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
9930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, ORR);
9940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
9950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
9970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::orn(const Register& rd,
9980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
9990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
10000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, ORN);
10010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::eor(const Register& rd,
10050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
10060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
10070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, EOR);
10080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::eon(const Register& rd,
10120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
10130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Operand& operand) {
10140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Logical(rd, rn, operand, EON);
10150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::lslv(const Register& rd,
10190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
10210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
10230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | LSLV | Rm(rm) | Rn(rn) | Rd(rd));
10240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::lsrv(const Register& rd,
10280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
10300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
10320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | LSRV | Rm(rm) | Rn(rn) | Rd(rd));
10330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::asrv(const Register& rd,
10370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
10390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
10410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | ASRV | Rm(rm) | Rn(rn) | Rd(rd));
10420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rorv(const Register& rd,
10460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
10480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
10500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | RORV | Rm(rm) | Rn(rn) | Rd(rd));
10510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Bitfield operations.
10550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bfm(const Register& rd,
10560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
10570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    unsigned immr,
10580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    unsigned imms) {
10590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
10610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | BFM | N |
10620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
10630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sbfm(const Register& rd,
10670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned immr,
10690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned imms) {
10700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits() || rn.Is32Bits());
10710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
10720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | SBFM | N |
10730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
10740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ubfm(const Register& rd,
10780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned immr,
10800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned imms) {
10810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
10830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | UBFM | N |
10840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
10850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::extr(const Register& rd,
10890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
10900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm,
10910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     unsigned lsb) {
10920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
10930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
10940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
10950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | EXTR | N | Rm(rm) | ImmS(lsb, rn.size()) | Rn(rn) | Rd(rd));
10960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
10970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
10990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::csel(const Register& rd,
11000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
11010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm,
11020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Condition cond) {
11030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalSelect(rd, rn, rm, cond, CSEL);
11040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::csinc(const Register& rd,
11080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
11090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rm,
11100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Condition cond) {
11110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalSelect(rd, rn, rm, cond, CSINC);
11120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::csinv(const Register& rd,
11160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
11170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rm,
11180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Condition cond) {
11190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalSelect(rd, rn, rm, cond, CSINV);
11200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::csneg(const Register& rd,
11240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
11250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rm,
11260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Condition cond) {
11270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalSelect(rd, rn, rm, cond, CSNEG);
11280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cset(const Register &rd, Condition cond) {
11320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((cond != al) && (cond != nv));
11330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
11340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  csinc(rd, zr, zr, InvertCondition(cond));
11350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11380cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::csetm(const Register &rd, Condition cond) {
11390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((cond != al) && (cond != nv));
11400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register zr = AppropriateZeroRegFor(rd);
11410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  csinv(rd, zr, zr, InvertCondition(cond));
11420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cinc(const Register &rd, const Register &rn, Condition cond) {
11460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((cond != al) && (cond != nv));
11470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  csinc(rd, rn, rn, InvertCondition(cond));
11480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cinv(const Register &rd, const Register &rn, Condition cond) {
11520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((cond != al) && (cond != nv));
11530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  csinv(rd, rn, rn, InvertCondition(cond));
11540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11570cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cneg(const Register &rd, const Register &rn, Condition cond) {
11580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((cond != al) && (cond != nv));
11590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  csneg(rd, rn, rn, InvertCondition(cond));
11600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ConditionalSelect(const Register& rd,
11640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const Register& rn,
11650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  const Register& rm,
11660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  Condition cond,
11670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                  ConditionalSelectOp op) {
11680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
11690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
11700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | op | Rm(rm) | Cond(cond) | Rn(rn) | Rd(rd));
11710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ccmn(const Register& rn,
11750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand,
11760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     StatusFlags nzcv,
11770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Condition cond) {
11780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalCompare(rn, operand, nzcv, cond, CCMN);
11790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11820cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ccmp(const Register& rn,
11830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Operand& operand,
11840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     StatusFlags nzcv,
11850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Condition cond) {
11860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ConditionalCompare(rn, operand, nzcv, cond, CCMP);
11870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::DataProcessing3Source(const Register& rd,
11910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
11920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm,
11930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& ra,
11940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     DataProcessing3SourceOp op) {
11950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | op | Rm(rm) | Ra(ra) | Rn(rn) | Rd(rd));
11960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
11970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
11990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32b(const Register& rd,
12000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
12010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm) {
12020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32B | Rn(rn) | Rd(rd));
12040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32h(const Register& rd,
12080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
12090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm) {
12100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32H | Rn(rn) | Rd(rd));
12120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32w(const Register& rd,
12160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
12170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm) {
12180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32W | Rn(rn) | Rd(rd));
12200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32x(const Register& rd,
12240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
12250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm) {
12260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is64Bits());
12270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32X | Rn(rn) | Rd(rd));
12280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32cb(const Register& rd,
12320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rn,
12330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rm) {
12340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32CB | Rn(rn) | Rd(rd));
12360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32ch(const Register& rd,
12400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rn,
12410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rm) {
12420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32CH | Rn(rn) | Rd(rd));
12440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32cw(const Register& rd,
12480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rn,
12490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rm) {
12500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is32Bits());
12510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32CW | Rn(rn) | Rd(rd));
12520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::crc32cx(const Register& rd,
12560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rn,
12570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rm) {
12580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is32Bits() && rn.Is32Bits() && rm.Is64Bits());
12590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rm) | Rm(rm) | CRC32CX | Rn(rn) | Rd(rd));
12600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mul(const Register& rd,
12640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn,
12650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rm) {
12660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rd, rn, rm));
12670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, AppropriateZeroRegFor(rd), MADD);
12680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::madd(const Register& rd,
12720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
12730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm,
12740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& ra) {
12750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, MADD);
12760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mneg(const Register& rd,
12800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
12810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
12820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rd, rn, rm));
12830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, AppropriateZeroRegFor(rd), MSUB);
12840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::msub(const Register& rd,
12880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
12890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm,
12900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& ra) {
12910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, MSUB);
12920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
12930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
12950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::umaddl(const Register& rd,
12960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
12970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm,
12980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& ra) {
12990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
13000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
13010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, UMADDL_x);
13020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::smaddl(const Register& rd,
13060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
13070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm,
13080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& ra) {
13090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
13100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
13110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, SMADDL_x);
13120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::umsubl(const Register& rd,
13160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
13170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm,
13180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& ra) {
13190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
13200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
13210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, UMSUBL_x);
13220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::smsubl(const Register& rd,
13260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
13270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rm,
13280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& ra) {
13290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
13300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
13310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, ra, SMSUBL_x);
13320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::smull(const Register& rd,
13360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
13370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rm) {
13380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits());
13390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
13400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(rd, rn, rm, xzr, SMADDL_x);
13410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sdiv(const Register& rd,
13450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
13460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
13470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
13480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
13490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | SDIV | Rm(rm) | Rn(rn) | Rd(rd));
13500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::smulh(const Register& xd,
13540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& xn,
13550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& xm) {
13560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(xd.Is64Bits() && xn.Is64Bits() && xm.Is64Bits());
13570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(xd, xn, xm, xzr, SMULH_x);
13580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::umulh(const Register& xd,
13620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& xn,
13630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& xm) {
13640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(xd.Is64Bits() && xn.Is64Bits() && xm.Is64Bits());
13650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing3Source(xd, xn, xm, xzr, UMULH_x);
13660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::udiv(const Register& rd,
13700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn,
13710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rm) {
13720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
13730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rm.size());
13740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | UDIV | Rm(rm) | Rn(rn) | Rd(rd));
13750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rbit(const Register& rd,
13790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rn) {
13800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, RBIT);
13810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev16(const Register& rd,
13850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn) {
13860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, REV16);
13870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev32(const Register& rd,
13910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn) {
13920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.Is64Bits());
13930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, REV);
13940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
13950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
13970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev(const Register& rd,
13980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn) {
13990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, rd.Is64Bits() ? REV_x : REV_w);
14000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::clz(const Register& rd,
14040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn) {
14050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, CLZ);
14060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cls(const Register& rd,
14100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn) {
14110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  DataProcessing1Source(rd, rn, CLS);
14120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldp(const CPURegister& rt,
14160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const CPURegister& rt2,
14170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
14180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStorePair(rt, rt2, src, LoadPairOpFor(rt, rt2));
14190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stp(const CPURegister& rt,
14230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const CPURegister& rt2,
14240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
14250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2));
14260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldpsw(const Register& rt,
14300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt2,
14310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
14320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
14330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStorePair(rt, rt2, src, LDPSW_x);
14340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStorePair(const CPURegister& rt,
14380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const CPURegister& rt2,
14390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const MemOperand& addr,
14400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              LoadStorePairOp op) {
14410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 'rt' and 'rt2' can only be aliased for stores.
14420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2));
14430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
14440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) |
14460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                ImmLSPair(addr.offset(), CalcLSPairDataSize(op));
14470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr addrmodeop;
14490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsImmediateOffset()) {
14500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addrmodeop = LoadStorePairOffsetFixed;
14510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
14520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(addr.offset() != 0);
14530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (addr.IsPreIndex()) {
14540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      addrmodeop = LoadStorePairPreIndexFixed;
14550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
14560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(addr.IsPostIndex());
14570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      addrmodeop = LoadStorePairPostIndexFixed;
14580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
14590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
14600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(addrmodeop | memop);
14610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14640cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldnp(const CPURegister& rt,
14650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const CPURegister& rt2,
14660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
14670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStorePairNonTemporal(rt, rt2, src,
14680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                           LoadPairNonTemporalOpFor(rt, rt2));
14690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stnp(const CPURegister& rt,
14730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const CPURegister& rt2,
14740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& dst) {
14750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStorePairNonTemporal(rt, rt2, dst,
14760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                           StorePairNonTemporalOpFor(rt, rt2));
14770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStorePairNonTemporal(const CPURegister& rt,
14810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         const CPURegister& rt2,
14820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         const MemOperand& addr,
14830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         LoadStorePairNonTemporalOp op) {
14840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!rt.Is(rt2));
14850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
14860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(addr.IsImmediateOffset());
14870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned size = CalcLSPairDataSize(
14890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    static_cast<LoadStorePairOp>(op & LoadStorePairMask));
14900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) |
14910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmLSPair(addr.offset(), size));
14920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
14930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
14950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Memory instructions.
14960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrb(const Register& rt, const MemOperand& src,
14970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
14980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
14990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRB_w, option);
15010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::strb(const Register& rt, const MemOperand& dst,
15050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
15060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, STRB_w, option);
15090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrsb(const Register& rt, const MemOperand& src,
15130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w, option);
15170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrh(const Register& rt, const MemOperand& src,
15210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
15220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRH_w, option);
15250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::strh(const Register& rt, const MemOperand& dst,
15290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
15300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, STRH_w, option);
15330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrsh(const Register& rt, const MemOperand& src,
15370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w, option);
15410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldr(const CPURegister& rt, const MemOperand& src,
15450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LoadStoreScalingOption option) {
15460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LoadOpFor(rt), option);
15490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::str(const CPURegister& rt, const MemOperand& dst,
15530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    LoadStoreScalingOption option) {
15540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, StoreOpFor(rt), option);
15570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrsw(const Register& rt, const MemOperand& src,
15610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
15630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
15640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
15650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRSW_x, option);
15660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldurb(const Register& rt, const MemOperand& src,
15700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
15720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
15730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRB_w, option);
15740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sturb(const Register& rt, const MemOperand& dst,
15780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
15800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
15810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, STRB_w, option);
15820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldursb(const Register& rt, const MemOperand& src,
15860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       LoadStoreScalingOption option) {
15870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
15880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
15890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w, option);
15900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
15930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldurh(const Register& rt, const MemOperand& src,
15940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
15950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
15960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
15970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRH_w, option);
15980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
15990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sturh(const Register& rt, const MemOperand& dst,
16020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
16030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
16040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
16050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, STRH_w, option);
16060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldursh(const Register& rt, const MemOperand& src,
16100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       LoadStoreScalingOption option) {
16110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
16120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
16130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w, option);
16140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldur(const CPURegister& rt, const MemOperand& src,
16180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
16190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
16200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
16210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LoadOpFor(rt), option);
16220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stur(const CPURegister& rt, const MemOperand& dst,
16260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
16270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
16280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
16290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, dst, StoreOpFor(rt), option);
16300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldursw(const Register& rt, const MemOperand& src,
16340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       LoadStoreScalingOption option) {
16350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
16360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
16370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
16380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStore(rt, src, LDRSW_x, option);
16390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16420cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrsw(const Register& rt, RawLiteral* literal) {
16430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
16440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(literal->size() == kWRegSizeInBytes);
16450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ldrsw(rt, LinkAndGetWordOffsetTo(literal));
16460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldr(const CPURegister& rt, RawLiteral* literal) {
16500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(literal->size() == static_cast<size_t>(rt.SizeInBytes()));
16510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ldr(rt, LinkAndGetWordOffsetTo(literal));
16520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldrsw(const Register& rt, int imm19) {
16560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDRSW_x_lit | ImmLLiteral(imm19) | Rt(rt));
16570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldr(const CPURegister& rt, int imm19) {
16610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadLiteralOp op = LoadLiteralOpFor(rt);
16620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | ImmLLiteral(imm19) | Rt(rt));
16630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::prfm(PrefetchOperation op, int imm19) {
16670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(PRFM_lit | ImmPrefetchOperation(op) | ImmLLiteral(imm19));
16680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Exclusive-access instructions.
16720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stxrb(const Register& rs,
16730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt,
16740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
16750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
16760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STXRB_w | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
16770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stxrh(const Register& rs,
16810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt,
16820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
16830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
16840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STXRH_w | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
16850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stxr(const Register& rs,
16890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rt,
16900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& dst) {
16910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
16920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? STXR_x : STXR_w;
16930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
16940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
16950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
16970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldxrb(const Register& rt,
16980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
16990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDXRB_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldxrh(const Register& rt,
17050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
17060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDXRH_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldxr(const Register& rt,
17120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
17130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? LDXR_x : LDXR_w;
17150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stxp(const Register& rs,
17200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rt,
17210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rt2,
17220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& dst) {
17230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.size() == rt2.size());
17240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
17250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? STXP_x : STXP_w;
17260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs(rs) | Rt(rt) | Rt2(rt2) | RnSP(dst.base()));
17270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldxp(const Register& rt,
17310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const Register& rt2,
17320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
17330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.size() == rt2.size());
17340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? LDXP_x : LDXP_w;
17360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2(rt2) | RnSP(src.base()));
17370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlxrb(const Register& rs,
17410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rt,
17420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const MemOperand& dst) {
17430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
17440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STLXRB_w | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
17450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlxrh(const Register& rs,
17490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rt,
17500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const MemOperand& dst) {
17510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
17520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STLXRH_w | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
17530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlxr(const Register& rs,
17570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt,
17580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
17590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
17600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? STLXR_x : STLXR_w;
17610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs(rs) | Rt(rt) | Rt2_mask | RnSP(dst.base()));
17620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldaxrb(const Register& rt,
17660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const MemOperand& src) {
17670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDAXRB_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldaxrh(const Register& rt,
17730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const MemOperand& src) {
17740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDAXRH_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17790cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldaxr(const Register& rt,
17800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
17810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
17820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? LDAXR_x : LDAXR_w;
17830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
17840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlxp(const Register& rs,
17880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt,
17890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt2,
17900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
17910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.size() == rt2.size());
17920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
17930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? STLXP_x : STLXP_w;
17940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs(rs) | Rt(rt) | Rt2(rt2) | RnSP(dst.base()));
17950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
17960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
17980cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldaxp(const Register& rt,
17990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rt2,
18000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
18010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.size() == rt2.size());
18020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
18030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? LDAXP_x : LDAXP_w;
18040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2(rt2) | RnSP(src.base()));
18050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlrb(const Register& rt,
18090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
18100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
18110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STLRB_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(dst.base()));
18120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlrh(const Register& rt,
18160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& dst) {
18170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
18180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(STLRH_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(dst.base()));
18190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::stlr(const Register& rt,
18230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& dst) {
18240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(dst.IsImmediateOffset() && (dst.offset() == 0));
18250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? STLR_x : STLR_w;
18260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2_mask | RnSP(dst.base()));
18270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldarb(const Register& rt,
18310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
18320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
18330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDARB_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
18340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldarh(const Register& rt,
18380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const MemOperand& src) {
18390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
18400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(LDARH_w | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
18410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ldar(const Register& rt,
18450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
18460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(src.IsImmediateOffset() && (src.offset() == 0));
18470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreExclusive op = rt.Is64Bits() ? LDAR_x : LDAR_w;
18480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rs_mask | Rt(rt) | Rt2_mask | RnSP(src.base()));
18490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::prfm(PrefetchOperation op, const MemOperand& address,
18530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     LoadStoreScalingOption option) {
18540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireUnscaledOffset);
18550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferUnscaledOffset);
18560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Prefetch(op, address, option);
18570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::prfum(PrefetchOperation op, const MemOperand& address,
18610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      LoadStoreScalingOption option) {
18620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != RequireScaledOffset);
18630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(option != PreferScaledOffset);
18640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Prefetch(op, address, option);
18650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::prfm(PrefetchOperation op, RawLiteral* literal) {
18690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  prfm(op, LinkAndGetWordOffsetTo(literal));
18700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sys(int op1, int crn, int crm, int op2, const Register& rt) {
18740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SYS | ImmSysOp1(op1) | CRn(crn) | CRm(crm) | ImmSysOp2(op2) | Rt(rt));
18750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sys(int op, const Register& rt) {
18790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SYS | SysOp(op) | Rt(rt));
18800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::dc(DataCacheOp op, const Register& rt) {
18840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((op == CVAC) || (op == CVAU) || (op == CIVAC) || (op == ZVA));
18850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sys(op, rt);
18860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ic(InstructionCacheOp op, const Register& rt) {
18900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(op == IVAU);
18910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sys(op, rt);
18920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::hint(SystemHint code) {
18960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(HINT | ImmHint(code) | Rt(xzr));
18970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
18980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
18990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// NEON structure loads and stores.
19010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlInstr Assembler::LoadStoreStructAddrModeField(const MemOperand& addr) {
19020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr addr_field = RnSP(addr.base());
19030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsPostIndex()) {
19050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_STATIC_ASSERT(NEONLoadStoreMultiStructPostIndex ==
19060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        static_cast<NEONLoadStoreMultiStructPostIndexOp>(
19070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl            NEONLoadStoreSingleStructPostIndex));
19080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    addr_field |= NEONLoadStoreMultiStructPostIndex;
19100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (addr.offset() == 0) {
19110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      addr_field |= RmNot31(addr.regoffset());
19120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
19130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // The immediate post index addressing mode is indicated by rm = 31.
19140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // The immediate is implied by the number of vector registers used.
19150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      addr_field |= (0x1f << Rm_offset);
19160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
19180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(addr.IsImmediateOffset() && (addr.offset() == 0));
19190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return addr_field;
19210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStoreStructVerify(const VRegister& vt,
19240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const MemOperand& addr,
19250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      Instr op) {
19260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#ifdef VIXL_DEBUG
19270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Assert that addressing mode is either offset (with immediate 0), post
19280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // index by immediate of the size of the register list, or post index by a
19290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // value in a core register.
19300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsImmediateOffset()) {
19310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(addr.offset() == 0);
19320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
19330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int offset = vt.SizeInBytes();
19340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (op) {
19350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD1_1v:
19360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST1_1v:
19370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset *= 1; break;
19380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructLoad1:
19390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructStore1:
19400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD1R:
19410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset = (offset / vt.lanes()) * 1; break;
19420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD1_2v:
19440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST1_2v:
19450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD2:
19460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST2:
19470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset *= 2;
19480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        break;
19490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructLoad2:
19500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructStore2:
19510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD2R:
19520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset = (offset / vt.lanes()) * 2; break;
19530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD1_3v:
19550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST1_3v:
19560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD3:
19570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST3:
19580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset *= 3; break;
19590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructLoad3:
19600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructStore3:
19610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD3R:
19620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset = (offset / vt.lanes()) * 3; break;
19630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD1_4v:
19650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST1_4v:
19660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD4:
19670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_ST4:
19680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset *= 4; break;
19690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructLoad4:
19700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEONLoadStoreSingleStructStore4:
19710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case NEON_LD4R:
19720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        offset = (offset / vt.lanes()) * 4; break;
19730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
19740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_UNREACHABLE();
19750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
19760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(!addr.regoffset().Is(NoReg) ||
19770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                addr.offset() == offset);
19780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
19790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#else
19800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt);
19810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(addr);
19820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(op);
19830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#endif
19840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStoreStruct(const VRegister& vt,
19870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const MemOperand& addr,
19880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                NEONLoadStoreMultiStructOp op) {
19890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructVerify(vt, addr, op);
19900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vt.IsVector() || vt.Is1D());
19910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | LoadStoreStructAddrModeField(addr) | LSVFormat(vt) | Rt(vt));
19920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
19930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
19950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStoreStructSingleAllLanes(const VRegister& vt,
19960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const MemOperand& addr,
19970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      NEONLoadStoreSingleStructOp op) {
19980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructVerify(vt, addr, op);
19990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | LoadStoreStructAddrModeField(addr) | LSVFormat(vt) | Rt(vt));
20000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1(const VRegister& vt,
20040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD1_1v);
20060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1(const VRegister& vt,
20100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
20130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
20140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
20150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD1_2v);
20160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1(const VRegister& vt,
20200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
20220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
20240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
20250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
20260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD1_3v);
20270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1(const VRegister& vt,
20310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
20330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
20340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
20360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
20370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
20380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD1_4v);
20390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20420cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld2(const VRegister& vt,
20430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
20460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
20470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
20480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD2);
20490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld2(const VRegister& vt,
20530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
20550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
20570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
20580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
20590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, src, NEONLoadStoreSingleStructLoad2);
20600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld2r(const VRegister& vt,
20640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vt2,
20650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
20660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
20670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
20680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
20690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingleAllLanes(vt, src, NEON_LD2R);
20700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld3(const VRegister& vt,
20740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
20760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
20780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
20790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
20800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD3);
20810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld3(const VRegister& vt,
20850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
20870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
20880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
20890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
20900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
20910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
20920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, src, NEONLoadStoreSingleStructLoad3);
20930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
20940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
20960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld3r(const VRegister& vt,
20970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
20980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
20990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
21010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
21020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
21030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingleAllLanes(vt, src, NEON_LD3R);
21040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld4(const VRegister& vt,
21080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
21100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
21110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
21130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
21140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
21150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_LD4);
21160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld4(const VRegister& vt,
21200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
21220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
21230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
21240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
21260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
21270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
21280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, src, NEONLoadStoreSingleStructLoad4);
21290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld4r(const VRegister& vt,
21330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
21350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
21360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
21380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
21390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
21400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingleAllLanes(vt, src, NEON_LD4R);
21410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st1(const VRegister& vt,
21450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_ST1_1v);
21470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21500cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st1(const VRegister& vt,
21510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
21540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
21550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
21560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_ST1_2v);
21570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st1(const VRegister& vt,
21610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
21630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
21650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
21660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
21670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_ST1_3v);
21680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st1(const VRegister& vt,
21720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
21740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
21750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
21760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
21770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
21780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
21790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, src, NEON_ST1_4v);
21800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st2(const VRegister& vt,
21840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
21860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
21870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
21880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
21890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, dst, NEON_ST2);
21900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
21910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
21930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st2(const VRegister& vt,
21940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
21950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
21960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
21970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2);
21980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2));
21990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2));
22000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, dst, NEONLoadStoreSingleStructStore2);
22010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st3(const VRegister& vt,
22050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
22060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
22070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
22080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
22090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
22100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
22110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, dst, NEON_ST3);
22120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st3(const VRegister& vt,
22160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
22170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
22180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
22190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
22200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3);
22210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3));
22220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3));
22230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, dst, NEONLoadStoreSingleStructStore3);
22240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st4(const VRegister& vt,
22280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
22290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
22300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
22310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
22320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
22330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
22340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
22350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStruct(vt, dst, NEON_ST4);
22360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st4(const VRegister& vt,
22400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt2,
22410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt3,
22420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vt4,
22430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
22440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
22450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(vt2, vt3, vt4);
22460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vt, vt2, vt3, vt4));
22470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreConsecutive(vt, vt2, vt3, vt4));
22480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, dst, NEONLoadStoreSingleStructStore4);
22490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStoreStructSingle(const VRegister& vt,
22530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      uint32_t lane,
22540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const MemOperand& addr,
22550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      NEONLoadStoreSingleStructOp op) {
22560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructVerify(vt, addr, op);
22570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vt arguments of the form vt.VxT() or vt.T(), where x is the
22590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s or d.
22600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned lane_size = vt.LaneSizeInBytes();
22610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(lane < (kQRegSizeInBytes / lane_size));
22620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Lane size is encoded in the opcode field. Lane index is encoded in the Q,
22640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // S and size fields.
22650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  lane *= lane_size;
22660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (lane_size == 8) lane++;
22670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr size = (lane << NEONLSSize_offset) & NEONLSSize_mask;
22690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr s = (lane << (NEONS_offset - 2)) & NEONS_mask;
22700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q = (lane << (NEONQ_offset - 3)) & NEONQ_mask;
22710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr instr = op;
22730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
22740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: instr |= NEONLoadStoreSingle_b; break;
22750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: instr |= NEONLoadStoreSingle_h; break;
22760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 4: instr |= NEONLoadStoreSingle_s; break;
22770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
22780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 8);
22790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      instr |= NEONLoadStoreSingle_d;
22800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
22810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(instr | LoadStoreStructAddrModeField(addr) | q | size | s | Rt(vt));
22830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1(const VRegister& vt,
22870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
22880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& src) {
22890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, src, NEONLoadStoreSingleStructLoad1);
22900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ld1r(const VRegister& vt,
22940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const MemOperand& src) {
22950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingleAllLanes(vt, src, NEON_LD1R);
22960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
22970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
22990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::st1(const VRegister& vt,
23000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int lane,
23010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const MemOperand& dst) {
23020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  LoadStoreStructSingle(vt, lane, dst, NEONLoadStoreSingleStructStore1);
23030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23060cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEON3DifferentL(const VRegister& vd,
23070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vn,
23080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vm,
23090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                NEON3DifferentOp vop) {
23100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vn, vm));
23110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is1H() && vd.Is1S()) ||
23120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is1S() && vd.Is1D()) ||
23130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8B() && vd.Is8H()) ||
23140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4H() && vd.Is4S()) ||
23150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is2S() && vd.Is2D()) ||
23160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is16B() && vd.Is8H())||
23170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8H() && vd.Is4S()) ||
23180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4S() && vd.Is2D()));
23190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
23200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
23210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
23220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vn);
23230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
23240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vn);
23250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
23260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | Rm(vm) | Rn(vn) | Rd(vd));
23270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEON3DifferentW(const VRegister& vd,
23310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vn,
23320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vm,
23330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                NEON3DifferentOp vop) {
23340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
23350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vm.Is8B() && vd.Is8H()) ||
23360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is4H() && vd.Is4S()) ||
23370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is2S() && vd.Is2D()) ||
23380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is16B() && vd.Is8H())||
23390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is8H() && vd.Is4S()) ||
23400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is4S() && vd.Is2D()));
23410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vm) | vop | Rm(vm) | Rn(vn) | Rd(vd));
23420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEON3DifferentHN(const VRegister& vd,
23460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const VRegister& vn,
23470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const VRegister& vm,
23480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 NEON3DifferentOp vop) {
23490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vm, vn));
23500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is8B() && vn.Is8H()) ||
23510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4H() && vn.Is4S()) ||
23520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2S() && vn.Is2D()) ||
23530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is16B() && vn.Is8H())||
23540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is8H() && vn.Is4S()) ||
23550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vn.Is2D()));
23560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vd) | vop | Rm(vm) | Rn(vn) | Rd(vd));
23570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
23580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_3DIFF_LONG_LIST(V) \
23610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(pmull,  NEON_PMULL,  vn.IsVector() && vn.Is8B())                           \
23620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(pmull2, NEON_PMULL2, vn.IsVector() && vn.Is16B())                          \
23630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(saddl,  NEON_SADDL,  vn.IsVector() && vn.IsD())                            \
23640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(saddl2, NEON_SADDL2, vn.IsVector() && vn.IsQ())                            \
23650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sabal,  NEON_SABAL,  vn.IsVector() && vn.IsD())                            \
23660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sabal2, NEON_SABAL2, vn.IsVector() && vn.IsQ())                            \
23670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uabal,  NEON_UABAL,  vn.IsVector() && vn.IsD())                            \
23680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uabal2, NEON_UABAL2, vn.IsVector() && vn.IsQ())                            \
23690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sabdl,  NEON_SABDL,  vn.IsVector() && vn.IsD())                            \
23700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sabdl2, NEON_SABDL2, vn.IsVector() && vn.IsQ())                            \
23710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uabdl,  NEON_UABDL,  vn.IsVector() && vn.IsD())                            \
23720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uabdl2, NEON_UABDL2, vn.IsVector() && vn.IsQ())                            \
23730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlal,  NEON_SMLAL,  vn.IsVector() && vn.IsD())                            \
23740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlal2, NEON_SMLAL2, vn.IsVector() && vn.IsQ())                            \
23750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlal,  NEON_UMLAL,  vn.IsVector() && vn.IsD())                            \
23760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlal2, NEON_UMLAL2, vn.IsVector() && vn.IsQ())                            \
23770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlsl,  NEON_SMLSL,  vn.IsVector() && vn.IsD())                            \
23780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlsl2, NEON_SMLSL2, vn.IsVector() && vn.IsQ())                            \
23790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlsl,  NEON_UMLSL,  vn.IsVector() && vn.IsD())                            \
23800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlsl2, NEON_UMLSL2, vn.IsVector() && vn.IsQ())                            \
23810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smull,  NEON_SMULL,  vn.IsVector() && vn.IsD())                            \
23820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smull2, NEON_SMULL2, vn.IsVector() && vn.IsQ())                            \
23830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umull,  NEON_UMULL,  vn.IsVector() && vn.IsD())                            \
23840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umull2, NEON_UMULL2, vn.IsVector() && vn.IsQ())                            \
23850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(ssubl,  NEON_SSUBL,  vn.IsVector() && vn.IsD())                            \
23860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(ssubl2, NEON_SSUBL2, vn.IsVector() && vn.IsQ())                            \
23870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uaddl,  NEON_UADDL,  vn.IsVector() && vn.IsD())                            \
23880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uaddl2, NEON_UADDL2, vn.IsVector() && vn.IsQ())                            \
23890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(usubl,  NEON_USUBL,  vn.IsVector() && vn.IsD())                            \
23900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(usubl2, NEON_USUBL2, vn.IsVector() && vn.IsQ())                            \
23910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlal,  NEON_SQDMLAL,  vn.Is1H() || vn.Is1S() || vn.Is4H() || vn.Is2S()) \
23920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlal2, NEON_SQDMLAL2, vn.Is1H() || vn.Is1S() || vn.Is8H() || vn.Is4S()) \
23930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlsl,  NEON_SQDMLSL,  vn.Is1H() || vn.Is1S() || vn.Is4H() || vn.Is2S()) \
23940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlsl2, NEON_SQDMLSL2, vn.Is1H() || vn.Is1S() || vn.Is8H() || vn.Is4S()) \
23950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmull,  NEON_SQDMULL,  vn.Is1H() || vn.Is1S() || vn.Is4H() || vn.Is2S()) \
23960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmull2, NEON_SQDMULL2, vn.Is1H() || vn.Is1S() || vn.Is8H() || vn.Is4S()) \
23970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
23990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)        \
24000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,    \
24010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,    \
24020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm) {  \
24030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                         \
24040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentL(vd, vn, vm, OP);         \
24050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24060cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_3DIFF_LONG_LIST(DEFINE_ASM_FUNC)
24070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
24080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_3DIFF_HN_LIST(V)         \
24100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(addhn,   NEON_ADDHN,   vd.IsD())  \
24110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(addhn2,  NEON_ADDHN2,  vd.IsQ())  \
24120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(raddhn,  NEON_RADDHN,  vd.IsD())  \
24130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(raddhn2, NEON_RADDHN2, vd.IsQ())  \
24140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(subhn,   NEON_SUBHN,   vd.IsD())  \
24150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(subhn2,  NEON_SUBHN2,  vd.IsQ())  \
24160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(rsubhn,  NEON_RSUBHN,  vd.IsD())  \
24170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(rsubhn2, NEON_RSUBHN2, vd.IsQ())
24180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)        \
24200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,    \
24210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,    \
24220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm) {  \
24230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                         \
24240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentHN(vd, vn, vm, OP);        \
24250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24260cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_3DIFF_HN_LIST(DEFINE_ASM_FUNC)
24270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
24280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uaddw(const VRegister& vd,
24300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
24310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
24320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsD());
24330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_UADDW);
24340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uaddw2(const VRegister& vd,
24380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
24390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm) {
24400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsQ());
24410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_UADDW2);
24420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::saddw(const VRegister& vd,
24460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
24470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
24480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsD());
24490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_SADDW);
24500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::saddw2(const VRegister& vd,
24540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
24550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm) {
24560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsQ());
24570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_SADDW2);
24580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24610cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::usubw(const VRegister& vd,
24620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
24630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
24640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsD());
24650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_USUBW);
24660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::usubw2(const VRegister& vd,
24700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
24710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm) {
24720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsQ());
24730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_USUBW2);
24740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24770cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ssubw(const VRegister& vd,
24780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
24790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
24800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsD());
24810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_SSUBW);
24820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ssubw2(const VRegister& vd,
24860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
24870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm) {
24880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vm.IsQ());
24890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3DifferentW(vd, vn, vm, NEON_SSUBW2);
24900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
24910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
24930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const Register& rd, const Register& rm) {
24940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Moves involving the stack pointer are encoded as add immediate with
24950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // second operand of zero. Otherwise, orr with first operand zr is
24960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // used.
24970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rd.IsSP() || rm.IsSP()) {
24980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    add(rd, rm, 0);
24990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
25000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    orr(rd, AppropriateZeroRegFor(rd), rm);
25010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
25020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mvn(const Register& rd, const Operand& operand) {
25060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  orn(rd, AppropriateZeroRegFor(rd), operand);
25070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25100cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mrs(const Register& rt, SystemRegister sysreg) {
25110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
25120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(MRS | ImmSystemRegister(sysreg) | Rt(rt));
25130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::msr(SystemRegister sysreg, const Register& rt) {
25170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.Is64Bits());
25180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(MSR | Rt(rt) | ImmSystemRegister(sysreg));
25190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::clrex(int imm4) {
25230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(CLREX | CRm(imm4));
25240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::dmb(BarrierDomain domain, BarrierType type) {
25280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(DMB | ImmBarrierDomain(domain) | ImmBarrierType(type));
25290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::dsb(BarrierDomain domain, BarrierType type) {
25330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(DSB | ImmBarrierDomain(domain) | ImmBarrierType(type));
25340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::isb() {
25380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(ISB | ImmBarrierDomain(FullSystem) | ImmBarrierType(BarrierAll));
25390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25420cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const VRegister& vd, double imm) {
25430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
25440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1D());
25450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(FMOV_d_imm | Rd(vd) | ImmFP64(imm));
25460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
25470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2D());
25480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr op = NEONModifiedImmediate_MOVI | NEONModifiedImmediateOpBit;
25490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr q = NEON_Q;
25500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint32_t encoded_imm = FP64ToImm8(imm);
25510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(q | op | ImmNEONabcdefgh(encoded_imm) | NEONCmode(0xf) | Rd(vd));
25520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
25530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const VRegister& vd, float imm) {
25570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
25580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1S());
25590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(FMOV_s_imm | Rd(vd) | ImmFP32(imm));
25600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
25610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2S() | vd.Is4S());
25620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr op = NEONModifiedImmediate_MOVI;
25630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr q = vd.Is4S() ?  NEON_Q : 0;
25640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    uint32_t encoded_imm = FP32ToImm8(imm);
25650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(q | op | ImmNEONabcdefgh(encoded_imm) | NEONCmode(0xf) | Rd(vd));
25660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
25670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25700cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const Register& rd, const VRegister& vn) {
25710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
25720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == vn.size());
25730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPIntegerConvertOp op = rd.Is32Bits() ? FMOV_ws : FMOV_xd;
25740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rd(rd) | Rn(vn));
25750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const VRegister& vd, const Register& rn) {
25790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
25800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.size() == rn.size());
25810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPIntegerConvertOp op = vd.Is32Bits() ? FMOV_sw : FMOV_dx;
25820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rd(vd) | Rn(rn));
25830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25860cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const VRegister& vd, const VRegister& vn) {
25870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
25880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsSameFormat(vn));
25890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vd) | FMOV | Rd(vd) | Rn(vn));
25900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25930cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const VRegister& vd, int index, const Register& rn) {
25940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((index == 1) && vd.Is1D() && rn.IsX());
25950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(index);
25960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FMOV_d1_x | Rd(vd) | Rn(rn));
25970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
25980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
25990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmov(const Register& rd, const VRegister& vn, int index) {
26010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((index == 1) && vn.Is1D() && rd.IsX());
26020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(index);
26030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FMOV_x_d1 | Rd(rd) | Rn(vn));
26040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmadd(const VRegister& vd,
26080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
26090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm,
26100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& va) {
26110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing3Source(vd, vn, vm, va, vd.Is1S() ? FMADD_s : FMADD_d);
26120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmsub(const VRegister& vd,
26160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
26170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm,
26180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& va) {
26190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing3Source(vd, vn, vm, va, vd.Is1S() ? FMSUB_s : FMSUB_d);
26200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fnmadd(const VRegister& vd,
26240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
26250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm,
26260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& va) {
26270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing3Source(vd, vn, vm, va, vd.Is1S() ? FNMADD_s : FNMADD_d);
26280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fnmsub(const VRegister& vd,
26320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
26330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm,
26340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& va) {
26350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing3Source(vd, vn, vm, va, vd.Is1S() ? FNMSUB_s : FNMSUB_d);
26360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fnmul(const VRegister& vd,
26400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
26410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
26420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(vd, vn, vm));
26430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = vd.Is1S() ? FNMUL_s : FNMUL_d;
26440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vd) | op | Rm(vm) | Rn(vn) | Rd(vd));
26450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FPCompareMacro(const VRegister& vn,
26490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               double value,
26500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               FPTrapFlags trap) {
26510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(value);
26520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Although the fcmp{e} instructions can strictly only take an immediate
26530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // value of +0.0, we don't need to check for -0.0 because the sign of 0.0
26540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // doesn't affect the result of the comparison.
26550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(value == 0.0);
26560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
26570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = (trap == EnableTrap) ? FCMPE_zero : FCMP_zero;
26580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vn) | op | Rn(vn));
26590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FPCompareMacro(const VRegister& vn,
26630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const VRegister& vm,
26640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               FPTrapFlags trap) {
26650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
26660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsSameSizeAndType(vm));
26670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = (trap == EnableTrap) ? FCMPE : FCMP;
26680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vn) | op | Rm(vm) | Rn(vn));
26690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmp(const VRegister& vn,
26730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
26740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCompareMacro(vn, vm, DisableTrap);
26750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmpe(const VRegister& vn,
26790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm) {
26800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCompareMacro(vn, vm, EnableTrap);
26810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmp(const VRegister& vn,
26850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     double value) {
26860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCompareMacro(vn, value, DisableTrap);
26870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmpe(const VRegister& vn,
26910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
26920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCompareMacro(vn, value, EnableTrap);
26930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
26940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
26960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FPCCompareMacro(const VRegister& vn,
26970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vm,
26980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                StatusFlags nzcv,
26990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                Condition cond,
27000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FPTrapFlags trap) {
27010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
27020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsSameSizeAndType(vm));
27030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = (trap == EnableTrap) ? FCCMPE : FCCMP;
27040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vn) | op | Rm(vm) | Cond(cond) | Rn(vn) | Nzcv(nzcv));
27050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fccmp(const VRegister& vn,
27080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm,
27090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      StatusFlags nzcv,
27100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Condition cond) {
27110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCCompareMacro(vn, vm, nzcv, cond, DisableTrap);
27120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fccmpe(const VRegister& vn,
27160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vm,
27170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       StatusFlags nzcv,
27180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       Condition cond) {
27190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPCCompareMacro(vn, vm, nzcv, cond, EnableTrap);
27200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcsel(const VRegister& vd,
27240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
27250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vm,
27260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      Condition cond) {
27270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
27280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn, vm));
27290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vd) | FCSEL | Rm(vm) | Cond(cond) | Rn(vn) | Rd(vd));
27300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFPConvertToInt(const Register& rd,
27340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const VRegister& vn,
27350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   Instr op) {
27360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | FPType(vn) | op | Rn(vn) | Rd(rd));
27370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFPConvertToInt(const VRegister& vd,
27410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const VRegister& vn,
27420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   Instr op) {
27430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vn.IsScalar()) {
27440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((vd.Is1S() && vn.Is1S()) || (vd.Is1D() && vn.Is1D()));
27450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
27460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
27470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vn) | op | Rn(vn) | Rd(vd));
27480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvt(const VRegister& vd,
27520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
27530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing1SourceOp op;
27540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.Is1D()) {
27550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vn.Is1S() || vn.Is1H());
27560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = vn.Is1S() ? FCVT_ds : FCVT_dh;
27570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (vd.Is1S()) {
27580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vn.Is1D() || vn.Is1H());
27590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = vn.Is1D() ? FCVT_sd : FCVT_sh;
27600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
27610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1H());
27620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vn.Is1D() || vn.Is1S());
27630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = vn.Is1D() ? FCVT_hd : FCVT_hs;
27640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
27650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  FPDataProcessing1Source(vd, vn, op);
27660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtl(const VRegister& vd,
27700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
27710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is4S() && vn.Is4H()) ||
27720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is2S()));
27730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = vd.Is2D() ? (1 << NEONSize_offset) : 0;
27740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | NEON_FCVTL | Rn(vn) | Rd(vd));
27750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27780cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtl2(const VRegister& vd,
27790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
27800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is4S() && vn.Is8H()) ||
27810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is4S()));
27820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = vd.Is2D() ? (1 << NEONSize_offset) : 0;
27830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(NEON_Q | format | NEON_FCVTL | Rn(vn) | Rd(vd));
27840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtn(const VRegister& vd,
27880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
27890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is4S() && vd.Is4H()) ||
27900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is2D() && vd.Is2S()));
27910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = vn.Is2D() ? (1 << NEONSize_offset) : 0;
27920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | NEON_FCVTN | Rn(vn) | Rd(vd));
27930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
27940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
27960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtn2(const VRegister& vd,
27970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
27980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is4S() && vd.Is8H()) ||
27990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is2D() && vd.Is4S()));
28000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = vn.Is2D() ? (1 << NEONSize_offset) : 0;
28010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(NEON_Q | format | NEON_FCVTN | Rn(vn) | Rd(vd));
28020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtxn(const VRegister& vd,
28060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
28070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = 1 << NEONSize_offset;
28080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
28090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1S() && vn.Is1D());
28100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(format | NEON_FCVTXN_scalar | Rn(vn) | Rd(vd));
28110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
28120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2S() && vn.Is2D());
28130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(format | NEON_FCVTXN | Rn(vn) | Rd(vd));
28140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
28150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtxn2(const VRegister& vd,
28190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn) {
28200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is4S() && vn.Is2D());
28210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format = 1 << NEONSize_offset;
28220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(NEON_Q | format | NEON_FCVTXN | Rn(vn) | Rd(vd));
28230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_FP2REGMISC_FCVT_LIST(V)  \
28270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtnu, NEON_FCVTNU, FCVTNU)      \
28280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtns, NEON_FCVTNS, FCVTNS)      \
28290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtpu, NEON_FCVTPU, FCVTPU)      \
28300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtps, NEON_FCVTPS, FCVTPS)      \
28310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtmu, NEON_FCVTMU, FCVTMU)      \
28320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtms, NEON_FCVTMS, FCVTMS)      \
28330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtau, NEON_FCVTAU, FCVTAU)      \
28340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcvtas, NEON_FCVTAS, FCVTAS)
28350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNCS(FN, VEC_OP, SCA_OP)  \
28370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const Register& rd,        \
28380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn) {     \
28390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFPConvertToInt(rd, vn, SCA_OP);         \
28400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}                                             \
28410cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,       \
28420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn) {     \
28430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFPConvertToInt(vd, vn, VEC_OP);         \
28440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FP2REGMISC_FCVT_LIST(DEFINE_ASM_FUNCS)
28460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNCS
28470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtzs(const Register& rd,
28500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
28510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int fbits) {
28520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
28530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((fbits >= 0) && (fbits <= rd.SizeInBits()));
28540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
28550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rd) | FPType(vn) | FCVTZS | Rn(vn) | Rd(rd));
28560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
28570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rd) | FPType(vn) | FCVTZS_fixed | FPScale(64 - fbits) | Rn(vn) |
28580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         Rd(rd));
28590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
28600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtzs(const VRegister& vd,
28640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
28650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int fbits) {
28660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
28670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
28680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONFP2RegMisc(vd, vn, NEON_FCVTZS);
28690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
28700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1D() || vd.Is1S() || vd.Is2D() || vd.Is2S() || vd.Is4S());
28710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONShiftRightImmediate(vd, vn, fbits, NEON_FCVTZS_imm);
28720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
28730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtzu(const Register& rd,
28770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
28780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int fbits) {
28790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.Is1S() || vn.Is1D());
28800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((fbits >= 0) && (fbits <= rd.SizeInBits()));
28810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
28820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rd) | FPType(vn) | FCVTZU | Rn(vn) | Rd(rd));
28830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
28840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rd) | FPType(vn) | FCVTZU_fixed | FPScale(64 - fbits) | Rn(vn) |
28850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         Rd(rd));
28860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
28870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
28880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
28900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcvtzu(const VRegister& vd,
28910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
28920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int fbits) {
28930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
28940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
28950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONFP2RegMisc(vd, vn, NEON_FCVTZU);
28960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
28970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1D() || vd.Is1S() || vd.Is2D() || vd.Is2S() || vd.Is4S());
28980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONShiftRightImmediate(vd, vn, fbits, NEON_FCVTZU_imm);
28990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29020cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ucvtf(const VRegister& vd,
29030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
29040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int fbits) {
29050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
29060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
29070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONFP2RegMisc(vd, vn, NEON_UCVTF);
29080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
29090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1D() || vd.Is1S() || vd.Is2D() || vd.Is2S() || vd.Is4S());
29100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONShiftRightImmediate(vd, vn, fbits, NEON_UCVTF_imm);
29110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29140cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::scvtf(const VRegister& vd,
29150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
29160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int fbits) {
29170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
29180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
29190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONFP2RegMisc(vd, vn, NEON_SCVTF);
29200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
29210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1D() || vd.Is1S() || vd.Is2D() || vd.Is2S() || vd.Is4S());
29220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONShiftRightImmediate(vd, vn, fbits, NEON_SCVTF_imm);
29230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::scvtf(const VRegister& vd,
29280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
29290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int fbits) {
29300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
29310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
29320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
29330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rn) | FPType(vd) | SCVTF | Rn(rn) | Rd(vd));
29340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
29350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rn) | FPType(vd) | SCVTF_fixed | FPScale(64 - fbits) | Rn(rn) |
29360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         Rd(vd));
29370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29410cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ucvtf(const VRegister& vd,
29420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const Register& rn,
29430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int fbits) {
29440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
29450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(fbits >= 0);
29460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (fbits == 0) {
29470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rn) | FPType(vd) | UCVTF | Rn(rn) | Rd(vd));
29480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
29490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rn) | FPType(vd) | UCVTF_fixed | FPScale(64 - fbits) | Rn(rn) |
29500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         Rd(vd));
29510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEON3Same(const VRegister& vd,
29560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vn,
29570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vm,
29580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          NEON3SameOp vop) {
29590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn, vm));
29600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || !vd.IsQ());
29610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
29630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
29640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
29650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vd);
29660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
29670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vd);
29680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
29690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | Rm(vm) | Rn(vn) | Rd(vd));
29710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFP3Same(const VRegister& vd,
29750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            const VRegister& vn,
29760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            const VRegister& vm,
29770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            Instr op) {
29780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn, vm));
29790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | op | Rm(vm) | Rn(vn) | Rd(vd));
29800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
29810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_FP2REGMISC_LIST(V)                 \
29840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fabs,    NEON_FABS,    FABS)                \
29850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fneg,    NEON_FNEG,    FNEG)                \
29860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fsqrt,   NEON_FSQRT,   FSQRT)               \
29870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frintn,  NEON_FRINTN,  FRINTN)              \
29880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frinta,  NEON_FRINTA,  FRINTA)              \
29890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frintp,  NEON_FRINTP,  FRINTP)              \
29900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frintm,  NEON_FRINTM,  FRINTM)              \
29910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frintx,  NEON_FRINTX,  FRINTX)              \
29920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frintz,  NEON_FRINTZ,  FRINTZ)              \
29930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frinti,  NEON_FRINTI,  FRINTI)              \
29940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frsqrte, NEON_FRSQRTE, NEON_FRSQRTE_scalar) \
29950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frecpe,  NEON_FRECPE,  NEON_FRECPE_scalar )
29960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
29980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, VEC_OP, SCA_OP)            \
29990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,                \
30000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn) {              \
30010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op;                                            \
30020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {                                 \
30030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1S() || vd.Is1D());               \
30040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = SCA_OP;                                       \
30050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {                                             \
30060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2S() || vd.Is2D() || vd.Is4S());  \
30070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = VEC_OP;                                       \
30080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }                                                    \
30090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, op);                          \
30100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FP2REGMISC_LIST(DEFINE_ASM_FUNC)
30120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
30130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFP2RegMisc(const VRegister& vd,
30160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const VRegister& vn,
30170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               Instr op) {
30180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
30190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | op | Rn(vn) | Rd(vd));
30200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEON2RegMisc(const VRegister& vd,
30240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             const VRegister& vn,
30250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             NEON2RegMiscOp vop,
30260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             int value) {
30270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
30280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(value == 0);
30290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(value);
30300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
30320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
30330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
30340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vd);
30350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
30360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vd);
30370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
30380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | Rn(vn) | Rd(vd));
30400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30430cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmeq(const VRegister& vd,
30440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int value) {
30460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
30470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_CMEQ_zero, value);
30480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmge(const VRegister& vd,
30520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int value) {
30540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
30550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_CMGE_zero, value);
30560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmgt(const VRegister& vd,
30600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int value) {
30620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
30630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_CMGT_zero, value);
30640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30670cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmle(const VRegister& vd,
30680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int value) {
30700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
30710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_CMLE_zero, value);
30720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30750cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cmlt(const VRegister& vd,
30760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int value) {
30780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
30790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_CMLT_zero, value);
30800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::shll(const VRegister& vd,
30840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
30850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
30860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is8H() && vn.Is8B() && shift == 8) ||
30870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vn.Is4H() && shift == 16) ||
30880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is2S() && shift == 32));
30890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(shift);
30900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_SHLL | Rn(vn) | Rd(vd));
30910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
30920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
30940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::shll2(const VRegister& vd,
30950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
30960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
30970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(shift);
30980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is8H() && vn.Is16B() && shift == 8) ||
30990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vn.Is8H() && shift == 16) ||
31000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is4S() && shift == 32));
31010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_SHLL | Rn(vn) | Rd(vd));
31020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFP2RegMisc(const VRegister& vd,
31060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const VRegister& vn,
31070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               NEON2RegMiscOp vop,
31080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               double value) {
31090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
31100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(value == 0.0);
31110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(value);
31120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = vop;
31140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
31150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1S() || vd.Is1D());
31160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
31170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
31180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2S() || vd.Is2D() || vd.Is4S());
31190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
31200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | op | Rn(vn) | Rd(vd));
31220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmeq(const VRegister& vd,
31260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
31270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
31280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, NEON_FCMEQ_zero, value);
31290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmge(const VRegister& vd,
31330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
31340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
31350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, NEON_FCMGE_zero, value);
31360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmgt(const VRegister& vd,
31400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
31410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
31420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, NEON_FCMGT_zero, value);
31430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmle(const VRegister& vd,
31470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
31480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
31490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, NEON_FCMLE_zero, value);
31500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31530cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fcmlt(const VRegister& vd,
31540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
31550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      double value) {
31560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP2RegMisc(vd, vn, NEON_FCMLT_zero, value);
31570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::frecpx(const VRegister& vd,
31610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
31620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsScalar());
31630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
31640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
31650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FRECPX_scalar | Rn(vn) | Rd(vd));
31660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
31670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
31690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_3SAME_LIST(V) \
31700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(add,      NEON_ADD,      vd.IsVector() || vd.Is1D())            \
31710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(addp,     NEON_ADDP,     vd.IsVector() || vd.Is1D())            \
31720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sub,      NEON_SUB,      vd.IsVector() || vd.Is1D())            \
31730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmeq,     NEON_CMEQ,     vd.IsVector() || vd.Is1D())            \
31740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmge,     NEON_CMGE,     vd.IsVector() || vd.Is1D())            \
31750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmgt,     NEON_CMGT,     vd.IsVector() || vd.Is1D())            \
31760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmhi,     NEON_CMHI,     vd.IsVector() || vd.Is1D())            \
31770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmhs,     NEON_CMHS,     vd.IsVector() || vd.Is1D())            \
31780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(cmtst,    NEON_CMTST,    vd.IsVector() || vd.Is1D())            \
31790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sshl,     NEON_SSHL,     vd.IsVector() || vd.Is1D())            \
31800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(ushl,     NEON_USHL,     vd.IsVector() || vd.Is1D())            \
31810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(srshl,    NEON_SRSHL,    vd.IsVector() || vd.Is1D())            \
31820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(urshl,    NEON_URSHL,    vd.IsVector() || vd.Is1D())            \
31830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmulh,  NEON_SQDMULH,  vd.IsLaneSizeH() || vd.IsLaneSizeS())  \
31840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqrdmulh, NEON_SQRDMULH, vd.IsLaneSizeH() || vd.IsLaneSizeS())  \
31850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(shadd,    NEON_SHADD,    vd.IsVector() && !vd.IsLaneSizeD())    \
31860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uhadd,    NEON_UHADD,    vd.IsVector() && !vd.IsLaneSizeD())    \
31870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(srhadd,   NEON_SRHADD,   vd.IsVector() && !vd.IsLaneSizeD())    \
31880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(urhadd,   NEON_URHADD,   vd.IsVector() && !vd.IsLaneSizeD())    \
31890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(shsub,    NEON_SHSUB,    vd.IsVector() && !vd.IsLaneSizeD())    \
31900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uhsub,    NEON_UHSUB,    vd.IsVector() && !vd.IsLaneSizeD())    \
31910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smax,     NEON_SMAX,     vd.IsVector() && !vd.IsLaneSizeD())    \
31920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smaxp,    NEON_SMAXP,    vd.IsVector() && !vd.IsLaneSizeD())    \
31930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smin,     NEON_SMIN,     vd.IsVector() && !vd.IsLaneSizeD())    \
31940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sminp,    NEON_SMINP,    vd.IsVector() && !vd.IsLaneSizeD())    \
31950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umax,     NEON_UMAX,     vd.IsVector() && !vd.IsLaneSizeD())    \
31960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umaxp,    NEON_UMAXP,    vd.IsVector() && !vd.IsLaneSizeD())    \
31970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umin,     NEON_UMIN,     vd.IsVector() && !vd.IsLaneSizeD())    \
31980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uminp,    NEON_UMINP,    vd.IsVector() && !vd.IsLaneSizeD())    \
31990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(saba,     NEON_SABA,     vd.IsVector() && !vd.IsLaneSizeD())    \
32000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sabd,     NEON_SABD,     vd.IsVector() && !vd.IsLaneSizeD())    \
32010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uaba,     NEON_UABA,     vd.IsVector() && !vd.IsLaneSizeD())    \
32020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uabd,     NEON_UABD,     vd.IsVector() && !vd.IsLaneSizeD())    \
32030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mla,      NEON_MLA,      vd.IsVector() && !vd.IsLaneSizeD())    \
32040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mls,      NEON_MLS,      vd.IsVector() && !vd.IsLaneSizeD())    \
32050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mul,      NEON_MUL,      vd.IsVector() && !vd.IsLaneSizeD())    \
32060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(and_,     NEON_AND,      vd.Is8B() || vd.Is16B())               \
32070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(orr,      NEON_ORR,      vd.Is8B() || vd.Is16B())               \
32080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(orn,      NEON_ORN,      vd.Is8B() || vd.Is16B())               \
32090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(eor,      NEON_EOR,      vd.Is8B() || vd.Is16B())               \
32100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(bic,      NEON_BIC,      vd.Is8B() || vd.Is16B())               \
32110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(bit,      NEON_BIT,      vd.Is8B() || vd.Is16B())               \
32120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(bif,      NEON_BIF,      vd.Is8B() || vd.Is16B())               \
32130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(bsl,      NEON_BSL,      vd.Is8B() || vd.Is16B())               \
32140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(pmul,     NEON_PMUL,     vd.Is8B() || vd.Is16B())               \
32150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uqadd,    NEON_UQADD,    true)                                  \
32160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqadd,    NEON_SQADD,    true)                                  \
32170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uqsub,    NEON_UQSUB,    true)                                  \
32180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqsub,    NEON_SQSUB,    true)                                  \
32190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqshl,    NEON_SQSHL,    true)                                  \
32200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uqshl,    NEON_UQSHL,    true)                                  \
32210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqrshl,   NEON_SQRSHL,   true)                                  \
32220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uqrshl,   NEON_UQRSHL,   true)
32230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)        \
32250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,    \
32260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,    \
32270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm) {  \
32280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                         \
32290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON3Same(vd, vn, vm, OP);               \
32300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32310cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_3SAME_LIST(DEFINE_ASM_FUNC)
32320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
32330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_FP3SAME_LIST(V)                     \
32360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fadd,    NEON_FADD,    FADD)                 \
32370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fsub,    NEON_FSUB,    FSUB)                 \
32380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmul,    NEON_FMUL,    FMUL)                 \
32390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fdiv,    NEON_FDIV,    FDIV)                 \
32400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmax,    NEON_FMAX,    FMAX)                 \
32410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmaxnm,  NEON_FMAXNM,  FMAXNM)               \
32420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmin,    NEON_FMIN,    FMIN)                 \
32430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fminnm,  NEON_FMINNM,  FMINNM)               \
32440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmulx,   NEON_FMULX,   NEON_FMULX_scalar)    \
32450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frecps,  NEON_FRECPS,  NEON_FRECPS_scalar)   \
32460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(frsqrts, NEON_FRSQRTS, NEON_FRSQRTS_scalar)  \
32470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fabd,    NEON_FABD,    NEON_FABD_scalar)     \
32480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmla,    NEON_FMLA,    0)                    \
32490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmls,    NEON_FMLS,    0)                    \
32500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(facge,   NEON_FACGE,   NEON_FACGE_scalar)    \
32510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(facgt,   NEON_FACGT,   NEON_FACGT_scalar)    \
32520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcmeq,   NEON_FCMEQ,   NEON_FCMEQ_scalar)    \
32530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcmge,   NEON_FCMGE,   NEON_FCMGE_scalar)    \
32540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fcmgt,   NEON_FCMGT,   NEON_FCMGT_scalar)    \
32550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(faddp,   NEON_FADDP,   0)                    \
32560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmaxp,   NEON_FMAXP,   0)                    \
32570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fminp,   NEON_FMINP,   0)                    \
32580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmaxnmp, NEON_FMAXNMP, 0)                    \
32590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fminnmp, NEON_FMINNMP, 0)
32600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, VEC_OP, SCA_OP)            \
32620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,                \
32630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,                \
32640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm) {              \
32650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op;                                            \
32660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((SCA_OP != 0) && vd.IsScalar()) {                \
32670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is1S() || vd.Is1D());               \
32680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = SCA_OP;                                       \
32690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {                                             \
32700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.IsVector());                        \
32710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.Is2S() || vd.Is2D() || vd.Is4S());  \
32720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op = VEC_OP;                                       \
32730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }                                                    \
32740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFP3Same(vd, vn, vm, op);                         \
32750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FP3SAME_LIST(DEFINE_ASM_FUNC)
32770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
32780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::addp(const VRegister& vd,
32810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
32820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1D() && vn.Is2D()));
32830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SFormat(vd) | NEON_ADDP_scalar | Rn(vn) | Rd(vd));
32840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::faddp(const VRegister& vd,
32880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
32890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1S() && vn.Is2S()) ||
32900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is2D()));
32910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FADDP_scalar | Rn(vn) | Rd(vd));
32920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
32930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
32950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmaxp(const VRegister& vd,
32960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
32970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1S() && vn.Is2S()) ||
32980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is2D()));
32990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FMAXP_scalar | Rn(vn) | Rd(vd));
33000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fminp(const VRegister& vd,
33040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
33050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1S() && vn.Is2S()) ||
33060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is2D()));
33070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FMINP_scalar | Rn(vn) | Rd(vd));
33080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fmaxnmp(const VRegister& vd,
33120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn) {
33130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1S() && vn.Is2S()) ||
33140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is2D()));
33150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FMAXNMP_scalar | Rn(vn) | Rd(vd));
33160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::fminnmp(const VRegister& vd,
33200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn) {
33210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is1S() && vn.Is2S()) ||
33220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is2D()));
33230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | NEON_FMINNMP_scalar | Rn(vn) | Rd(vd));
33240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::orr(const VRegister& vd,
33280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const int imm8,
33290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const int left_shift) {
33300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONModifiedImmShiftLsl(vd, imm8, left_shift,
33310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          NEONModifiedImmediate_ORR);
33320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const VRegister& vd,
33360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
33370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
33380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsD()) {
33390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    orr(vd.V8B(), vn.V8B(), vn.V8B());
33400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
33410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.IsQ());
33420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    orr(vd.V16B(), vn.V16B(), vn.V16B());
33430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
33440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::bic(const VRegister& vd,
33480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const int imm8,
33490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const int left_shift) {
33500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONModifiedImmShiftLsl(vd, imm8, left_shift,
33510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          NEONModifiedImmediate_BIC);
33520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::movi(const VRegister& vd,
33560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const uint64_t imm,
33570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Shift shift,
33580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const int shift_amount) {
33590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift == LSL) || (shift == MSL));
33600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.Is2D() || vd.Is1D()) {
33610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(shift_amount == 0);
33620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int imm8 = 0;
33630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    for (int i = 0; i < 8; ++i) {
33640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      int byte = (imm >> (i * 8)) & 0xff;
33650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT((byte == 0) || (byte == 0xff));
33660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      if (byte == 0xff) {
33670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        imm8 |= (1 << i);
33680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
33690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
33700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int q = vd.Is2D() ? NEON_Q : 0;
33710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(q | NEONModImmOp(1) | NEONModifiedImmediate_MOVI |
33720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         ImmNEONabcdefgh(imm8) | NEONCmode(0xe) | Rd(vd));
33730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (shift == LSL) {
33740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONModifiedImmShiftLsl(vd, imm, shift_amount,
33750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            NEONModifiedImmediate_MOVI);
33760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
33770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONModifiedImmShiftMsl(vd, imm, shift_amount,
33780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            NEONModifiedImmediate_MOVI);
33790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
33800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mvn(const VRegister& vd,
33840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
33850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
33860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsD()) {
33870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    not_(vd.V8B(), vn.V8B());
33880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
33890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(vd.IsQ());
33900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    not_(vd.V16B(), vn.V16B());
33910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
33920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
33930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
33950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mvni(const VRegister& vd,
33960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const int imm8,
33970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     Shift shift,
33980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const int shift_amount) {
33990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift == LSL) || (shift == MSL));
34000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (shift == LSL) {
34010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONModifiedImmShiftLsl(vd, imm8, shift_amount,
34020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            NEONModifiedImmediate_MVNI);
34030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
34040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    NEONModifiedImmShiftMsl(vd, imm8, shift_amount,
34050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                            NEONModifiedImmediate_MVNI);
34060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34100cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONFPByElement(const VRegister& vd,
34110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vn,
34120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vm,
34130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                int vm_index,
34140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                NEONByIndexedElementOp vop) {
34150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
34160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is2S() && vm.Is1S()) ||
34170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vm.Is1S()) ||
34180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1S() && vm.Is1S()) ||
34190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vm.Is1D()) ||
34200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vm.Is1D()));
34210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vm.Is1S() && (vm_index < 4)) ||
34220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is1D() && (vm_index < 2)));
34230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr op = vop;
34250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int index_num_bits = vm.Is1S() ? 2 : 1;
34260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
34270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
34280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPFormat(vd) | op | ImmNEONHLM(vm_index, index_num_bits) |
34310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rm(vm) | Rn(vn) | Rd(vd));
34320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONByElement(const VRegister& vd,
34360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const VRegister& vn,
34370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              const VRegister& vm,
34380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              int vm_index,
34390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                              NEONByIndexedElementOp vop) {
34400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
34410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is4H() && vm.Is1H()) ||
34420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is8H() && vm.Is1H()) ||
34430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1H() && vm.Is1H()) ||
34440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2S() && vm.Is1S()) ||
34450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vm.Is1S()) ||
34460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1S() && vm.Is1S()));
34470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vm.Is1H() && (vm.code() < 16) && (vm_index < 8)) ||
34480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is1S() && (vm_index < 4)));
34490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
34510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int index_num_bits = vm.Is1H() ? 3 : 2;
34520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
34530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEONScalar | NEON_Q;
34540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vn);
34550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
34560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vn);
34570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | ImmNEONHLM(vm_index, index_num_bits) |
34590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rm(vm) | Rn(vn) | Rd(vd));
34600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONByElementL(const VRegister& vd,
34640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const VRegister& vn,
34650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               const VRegister& vm,
34660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               int vm_index,
34670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               NEONByIndexedElementOp vop) {
34680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vd.Is4S() && vn.Is4H() && vm.Is1H()) ||
34690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is4S() && vn.Is8H() && vm.Is1H()) ||
34700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1S() && vn.Is1H() && vm.Is1H()) ||
34710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is2S() && vm.Is1S()) ||
34720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is2D() && vn.Is4S() && vm.Is1S()) ||
34730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vd.Is1D() && vn.Is1S() && vm.Is1S()));
34740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vm.Is1H() && (vm.code() < 16) && (vm_index < 8)) ||
34760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vm.Is1S() && (vm_index < 4)));
34770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
34790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int index_num_bits = vm.Is1H() ? 3 : 2;
34800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
34810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEONScalar | NEON_Q;
34820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vn);
34830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
34840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vn);
34850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
34860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | ImmNEONHLM(vm_index, index_num_bits) |
34870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rm(vm) | Rn(vn) | Rd(vd));
34880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
34890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_BYELEMENT_LIST(V)                         \
34920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mul,      NEON_MUL_byelement,      vn.IsVector())  \
34930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mla,      NEON_MLA_byelement,      vn.IsVector())  \
34940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(mls,      NEON_MLS_byelement,      vn.IsVector())  \
34950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmulh,  NEON_SQDMULH_byelement,  true)           \
34960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqrdmulh, NEON_SQRDMULH_byelement, true)
34970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
34990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)        \
35000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,    \
35010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,    \
35020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm,    \
35030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   int vm_index) {         \
35040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                         \
35050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONByElement(vd, vn, vm, vm_index, OP); \
35060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_BYELEMENT_LIST(DEFINE_ASM_FUNC)
35080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
35090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_FPBYELEMENT_LIST(V) \
35120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmul,  NEON_FMUL_byelement)  \
35130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmla,  NEON_FMLA_byelement)  \
35140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmls,  NEON_FMLS_byelement)  \
35150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmulx, NEON_FMULX_byelement)
35160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP)              \
35190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,      \
35200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,      \
35210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm,      \
35220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   int vm_index) {           \
35230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFPByElement(vd, vn, vm, vm_index, OP); \
35240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_FPBYELEMENT_LIST(DEFINE_ASM_FUNC)
35260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
35270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_BYELEMENT_LONG_LIST(V)                               \
35300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmull,  NEON_SQDMULL_byelement, vn.IsScalar() || vn.IsD())  \
35310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmull2, NEON_SQDMULL_byelement, vn.IsVector() && vn.IsQ())  \
35320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlal,  NEON_SQDMLAL_byelement, vn.IsScalar() || vn.IsD())  \
35330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlal2, NEON_SQDMLAL_byelement, vn.IsVector() && vn.IsQ())  \
35340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlsl,  NEON_SQDMLSL_byelement, vn.IsScalar() || vn.IsD())  \
35350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sqdmlsl2, NEON_SQDMLSL_byelement, vn.IsVector() && vn.IsQ())  \
35360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smull,    NEON_SMULL_byelement,   vn.IsVector() && vn.IsD())  \
35370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smull2,   NEON_SMULL_byelement,   vn.IsVector() && vn.IsQ())  \
35380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umull,    NEON_UMULL_byelement,   vn.IsVector() && vn.IsD())  \
35390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umull2,   NEON_UMULL_byelement,   vn.IsVector() && vn.IsQ())  \
35400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlal,    NEON_SMLAL_byelement,   vn.IsVector() && vn.IsD())  \
35410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlal2,   NEON_SMLAL_byelement,   vn.IsVector() && vn.IsQ())  \
35420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlal,    NEON_UMLAL_byelement,   vn.IsVector() && vn.IsD())  \
35430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlal2,   NEON_UMLAL_byelement,   vn.IsVector() && vn.IsQ())  \
35440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlsl,    NEON_SMLSL_byelement,   vn.IsVector() && vn.IsD())  \
35450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smlsl2,   NEON_SMLSL_byelement,   vn.IsVector() && vn.IsQ())  \
35460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlsl,    NEON_UMLSL_byelement,   vn.IsVector() && vn.IsD())  \
35470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umlsl2,   NEON_UMLSL_byelement,   vn.IsVector() && vn.IsQ())
35480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)         \
35510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,     \
35520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn,     \
35530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vm,     \
35540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   int vm_index) {          \
35550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                          \
35560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONByElementL(vd, vn, vm, vm_index, OP); \
35570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_BYELEMENT_LONG_LIST(DEFINE_ASM_FUNC)
35590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
35600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::suqadd(const VRegister& vd,
35630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
35640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_SUQADD);
35650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::usqadd(const VRegister& vd,
35690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
35700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_USQADD);
35710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::abs(const VRegister& vd,
35750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
35760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
35770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_ABS);
35780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqabs(const VRegister& vd,
35820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
35830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_SQABS);
35840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::neg(const VRegister& vd,
35880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
35890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
35900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_NEG);
35910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqneg(const VRegister& vd,
35950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
35960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEON2RegMisc(vd, vn, NEON_SQNEG);
35970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
35980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
35990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONXtn(const VRegister& vd,
36010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
36020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        NEON2RegMiscOp vop) {
36030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr format, op = vop;
36040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
36050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((vd.Is1B() && vn.Is1H()) ||
36060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is1H() && vn.Is1S()) ||
36070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is1S() && vn.Is1D()));
36080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    op |= NEON_Q | NEONScalar;
36090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = SFormat(vd);
36100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
36110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((vd.Is8B() && vn.Is8H())  ||
36120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is4H() && vn.Is4S())  ||
36130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is2S() && vn.Is2D())  ||
36140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is16B() && vn.Is8H()) ||
36150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is8H() && vn.Is4S())  ||
36160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is4S() && vn.Is2D()));
36170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    format = VFormat(vd);
36180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
36190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(format | op | Rn(vn) | Rd(vd));
36200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36230cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::xtn(const VRegister& vd,
36240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
36250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() && vd.IsD());
36260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_XTN);
36270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36300cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::xtn2(const VRegister& vd,
36310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
36320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() && vd.IsQ());
36330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_XTN);
36340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqxtn(const VRegister& vd,
36380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
36390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsScalar() || vd.IsD());
36400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_SQXTN);
36410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqxtn2(const VRegister& vd,
36450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
36460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() && vd.IsQ());
36470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_SQXTN);
36480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36510cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqxtun(const VRegister& vd,
36520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
36530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsScalar() || vd.IsD());
36540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_SQXTUN);
36550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqxtun2(const VRegister& vd,
36590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn) {
36600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() && vd.IsQ());
36610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_SQXTUN);
36620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36650cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqxtn(const VRegister& vd,
36660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
36670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsScalar() || vd.IsD());
36680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_UQXTN);
36690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqxtn2(const VRegister& vd,
36730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
36740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() && vd.IsQ());
36750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONXtn(vd, vn, NEON_UQXTN);
36760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// NEON NOT and RBIT are distinguised by bit 22, the bottom bit of "size".
36800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::not_(const VRegister& vd,
36810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
36820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
36830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B());
36840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vd) | NEON_RBIT_NOT | Rn(vn) | Rd(vd));
36850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rbit(const VRegister& vd,
36890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
36900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
36910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B());
36920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | (1 << NEONSize_offset) | NEON_RBIT_NOT | Rn(vn) | Rd(vd));
36930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
36940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
36960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ext(const VRegister& vd,
36970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
36980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vm,
36990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int index) {
37000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn, vm));
37010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B());
37020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= index) && (index < vd.lanes()));
37030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vd) | NEON_EXT | Rm(vm) | ImmNEONExt(index) | Rn(vn) | Rd(vd));
37040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37070cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::dup(const VRegister& vd,
37080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
37090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vn_index) {
37100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q, scalar;
37110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vn arguments of the form vn.VxT() or vn.T(), where x is the
37130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s or d.
37140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_size = vn.LaneSizeInBytes();
37150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFormatField format;
37160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
37170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: format = NEON_16B; break;
37180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: format = NEON_8H;  break;
37190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 4: format = NEON_4S;  break;
37200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
37210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 8);
37220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      format = NEON_2D;
37230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
37240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.IsScalar()) {
37270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = NEON_Q;
37280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = NEONScalar;
37290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
37300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(!vd.Is1D());
37310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = vd.IsD() ? 0 : NEON_Q;
37320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = 0;
37330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | scalar | NEON_DUP_ELEMENT |
37350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmNEON5(format, vn_index) | Rn(vn) | Rd(vd));
37360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37390cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const VRegister& vd,
37400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
37410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vn_index) {
37420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsScalar());
37430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  dup(vd, vn, vn_index);
37440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37470cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::dup(const VRegister& vd, const Register& rn) {
37480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!vd.Is1D());
37490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is2D() == rn.IsX());
37500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int q = vd.IsD() ? 0 : NEON_Q;
37510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | NEON_DUP_GENERAL | ImmNEON5(VFormat(vd), 0) | Rn(rn) | Rd(vd));
37520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ins(const VRegister& vd,
37560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vd_index,
37570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
37580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vn_index) {
37590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
37600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vd arguments of the form vd.VxT() or vd.T(), where x is the
37610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s or d.
37620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_size = vd.LaneSizeInBytes();
37630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFormatField format;
37640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
37650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: format = NEON_16B; break;
37660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: format = NEON_8H;  break;
37670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 4: format = NEON_4S;  break;
37680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
37690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 8);
37700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      format = NEON_2D;
37710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
37720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
37730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= vd_index) &&
37750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          (vd_index < LaneCountFromFormat(static_cast<VectorFormat>(format))));
37760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= vn_index) &&
37770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          (vn_index < LaneCountFromFormat(static_cast<VectorFormat>(format))));
37780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(NEON_INS_ELEMENT | ImmNEON5(format, vd_index) |
37790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmNEON4(format, vn_index) | Rn(vn) | Rd(vd));
37800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37830cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const VRegister& vd,
37840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vd_index,
37850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
37860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vn_index) {
37870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ins(vd, vd_index, vn, vn_index);
37880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
37890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
37910cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ins(const VRegister& vd,
37920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vd_index,
37930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn) {
37940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vd arguments of the form vd.VxT() or vd.T(), where x is the
37950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s or d.
37960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_size = vd.LaneSizeInBytes();
37970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFormatField format;
37980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
37990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: format = NEON_16B; VIXL_ASSERT(rn.IsW()); break;
38000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: format = NEON_8H;  VIXL_ASSERT(rn.IsW()); break;
38010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 4: format = NEON_4S;  VIXL_ASSERT(rn.IsW()); break;
38020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
38030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 8);
38040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(rn.IsX());
38050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      format = NEON_2D;
38060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
38070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= vd_index) &&
38100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          (vd_index < LaneCountFromFormat(static_cast<VectorFormat>(format))));
38110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(NEON_INS_GENERAL | ImmNEON5(format, vd_index) | Rn(rn) | Rd(vd));
38120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38150cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const VRegister& vd,
38160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vd_index,
38170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const Register& rn) {
38180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ins(vd, vd_index, rn);
38190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38220cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::umov(const Register& rd,
38230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
38240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int vn_index) {
38250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vd arguments of the form vd.VxT() or vd.T(), where x is the
38260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s or d.
38270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_size = vn.LaneSizeInBytes();
38280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFormatField format;
38290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q = 0;
38300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
38310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: format = NEON_16B; VIXL_ASSERT(rd.IsW()); break;
38320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: format = NEON_8H;  VIXL_ASSERT(rd.IsW()); break;
38330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 4: format = NEON_4S;  VIXL_ASSERT(rd.IsW()); break;
38340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
38350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 8);
38360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(rd.IsX());
38370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      format = NEON_2D;
38380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      q = NEON_Q;
38390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
38400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= vn_index) &&
38430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          (vn_index < LaneCountFromFormat(static_cast<VectorFormat>(format))));
38440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | NEON_UMOV | ImmNEON5(format, vn_index) | Rn(vn) | Rd(rd));
38450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::mov(const Register& rd,
38490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
38500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int vn_index) {
38510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.SizeInBytes() >= 4);
38520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  umov(rd, vn, vn_index);
38530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::smov(const Register& rd,
38570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
38580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int vn_index) {
38590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We support vd arguments of the form vd.VxT() or vd.T(), where x is the
38600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // number of lanes, and T is b, h, s.
38610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int lane_size = vn.LaneSizeInBytes();
38620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONFormatField format;
38630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q = 0;
38640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(lane_size != 8);
38650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (lane_size) {
38660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 1: format = NEON_16B; break;
38670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case 2: format = NEON_8H;  break;
38680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
38690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(lane_size == 4);
38700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(rd.IsX());
38710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      format = NEON_4S;
38720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
38730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
38740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  q = rd.IsW() ? 0 : NEON_Q;
38750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((0 <= vn_index) &&
38760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          (vn_index < LaneCountFromFormat(static_cast<VectorFormat>(format))));
38770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | NEON_SMOV | ImmNEON5(format, vn_index) | Rn(vn) | Rd(rd));
38780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cls(const VRegister& vd,
38820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
38830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
38840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!vd.Is1D() && !vd.Is2D());
38850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_CLS | Rn(vn) | Rd(vd));
38860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38890cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::clz(const VRegister& vd,
38900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
38910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
38920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!vd.Is1D() && !vd.Is2D());
38930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_CLZ | Rn(vn) | Rd(vd));
38940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
38950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
38970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::cnt(const VRegister& vd,
38980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn) {
38990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B());
39010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_CNT | Rn(vn) | Rd(vd));
39020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev16(const VRegister& vd,
39060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
39070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B());
39090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_REV16 | Rn(vn) | Rd(vd));
39100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39130cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev32(const VRegister& vd,
39140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
39150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B() || vd.Is4H() || vd.Is8H());
39170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_REV32 | Rn(vn) | Rd(vd));
39180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39210cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rev64(const VRegister& vd,
39220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
39230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!vd.Is1D() && !vd.Is2D());
39250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_REV64 | Rn(vn) | Rd(vd));
39260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39290cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ursqrte(const VRegister& vd,
39300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn) {
39310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is2S() || vd.Is4S());
39330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_URSQRTE | Rn(vn) | Rd(vd));
39340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39370cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::urecpe(const VRegister& vd,
39380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
39390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
39400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is2S() || vd.Is4S());
39410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | NEON_URECPE | Rn(vn) | Rd(vd));
39420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONAddlp(const VRegister& vd,
39460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vn,
39470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          NEON2RegMiscOp op) {
39480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((op == NEON_SADDLP) ||
39490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (op == NEON_UADDLP) ||
39500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (op == NEON_SADALP) ||
39510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (op == NEON_UADALP));
39520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is8B() && vd.Is4H()) ||
39540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4H() && vd.Is2S()) ||
39550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is2S() && vd.Is1D()) ||
39560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is16B() && vd.Is8H())||
39570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8H() && vd.Is4S()) ||
39580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4S() && vd.Is2D()));
39590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | op | Rn(vn) | Rd(vd));
39600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::saddlp(const VRegister& vd,
39640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
39650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAddlp(vd, vn, NEON_SADDLP);
39660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39690cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uaddlp(const VRegister& vd,
39700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
39710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAddlp(vd, vn, NEON_UADDLP);
39720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39750cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sadalp(const VRegister& vd,
39760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
39770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAddlp(vd, vn, NEON_SADALP);
39780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39810cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uadalp(const VRegister& vd,
39820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
39830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAddlp(vd, vn, NEON_UADALP);
39840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONAcrossLanesL(const VRegister& vd,
39880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const VRegister& vn,
39890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 NEONAcrossLanesOp op) {
39900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is8B()  && vd.Is1H()) ||
39910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is16B() && vd.Is1H()) ||
39920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4H()  && vd.Is1S()) ||
39930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8H()  && vd.Is1S()) ||
39940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4S()  && vd.Is1D()));
39950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vn) | op | Rn(vn) | Rd(vd));
39960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
39970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
39990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::saddlv(const VRegister& vd,
40000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
40010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAcrossLanesL(vd, vn, NEON_SADDLV);
40020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40050cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uaddlv(const VRegister& vd,
40060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn) {
40070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAcrossLanesL(vd, vn, NEON_UADDLV);
40080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONAcrossLanes(const VRegister& vd,
40120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const VRegister& vn,
40130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                NEONAcrossLanesOp op) {
40140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is8B()  && vd.Is1B()) ||
40150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is16B() && vd.Is1B()) ||
40160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4H()  && vd.Is1H()) ||
40170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8H()  && vd.Is1H()) ||
40180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4S()  && vd.Is1S()));
40190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((op & NEONAcrossLanesFPFMask) == NEONAcrossLanesFPFixed) {
40200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(FPFormat(vn) | op | Rn(vn) | Rd(vd));
40210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
40220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(VFormat(vn) | op | Rn(vn) | Rd(vd));
40230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
40240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define NEON_ACROSSLANES_LIST(V) \
40280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmaxv,   NEON_FMAXV,   vd.Is1S()) \
40290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fminv,   NEON_FMINV,   vd.Is1S()) \
40300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fmaxnmv, NEON_FMAXNMV, vd.Is1S()) \
40310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(fminnmv, NEON_FMINNMV, vd.Is1S()) \
40320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(addv,    NEON_ADDV,    true)      \
40330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(smaxv,   NEON_SMAXV,   true)      \
40340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(sminv,   NEON_SMINV,   true)      \
40350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(umaxv,   NEON_UMAXV,   true)      \
40360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(uminv,   NEON_UMINV,   true)
40370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#define DEFINE_ASM_FUNC(FN, OP, AS)        \
40400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FN(const VRegister& vd,    \
40410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& vn) {  \
40420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AS);                         \
40430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONAcrossLanes(vd, vn, OP);             \
40440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlNEON_ACROSSLANES_LIST(DEFINE_ASM_FUNC)
40460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#undef DEFINE_ASM_FUNC
40470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40490cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONPerm(const VRegister& vd,
40500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vn,
40510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vm,
40520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         NEONPermOp op) {
40530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn, vm));
40540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(!vd.Is1D());
40550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(VFormat(vd) | op | Rm(vm) | Rn(vn) | Rd(vd));
40560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::trn1(const VRegister& vd,
40600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_TRN1);
40630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40660cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::trn2(const VRegister& vd,
40670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_TRN2);
40700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uzp1(const VRegister& vd,
40740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_UZP1);
40770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uzp2(const VRegister& vd,
40810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_UZP2);
40840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::zip1(const VRegister& vd,
40880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_ZIP1);
40910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
40940cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::zip2(const VRegister& vd,
40950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
40960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vm) {
40970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONPerm(vd, vn, vm, NEON_ZIP2);
40980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
40990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41010cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONShiftImmediate(const VRegister& vd,
41020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const VRegister& vn,
41030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   NEONShiftImmediateOp op,
41040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   int immh_immb) {
41050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameFormat(vd, vn));
41060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q, scalar;
41070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vn.IsScalar()) {
41080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = NEON_Q;
41090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = NEONScalar;
41100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = vd.IsD() ? 0 : NEON_Q;
41120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = 0;
41130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | op | scalar | immh_immb | Rn(vn) | Rd(vd));
41150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41180cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONShiftLeftImmediate(const VRegister& vd,
41190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       const VRegister& vn,
41200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       int shift,
41210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                       NEONShiftImmediateOp op) {
41220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits = vn.LaneSizeInBits();
41230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift >= 0) && (shift < laneSizeInBits));
41240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediate(vd, vn, op, (laneSizeInBits + shift) << 16);
41250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONShiftRightImmediate(const VRegister& vd,
41290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const VRegister& vn,
41300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        int shift,
41310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        NEONShiftImmediateOp op) {
41320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits = vn.LaneSizeInBits();
41330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift >= 1) && (shift <= laneSizeInBits));
41340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediate(vd, vn, op, ((2 * laneSizeInBits) - shift) << 16);
41350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41380cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONShiftImmediateL(const VRegister& vd,
41390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const VRegister& vn,
41400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    int shift,
41410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    NEONShiftImmediateOp op) {
41420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits = vn.LaneSizeInBits();
41430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift >= 0) && (shift < laneSizeInBits));
41440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int immh_immb = (laneSizeInBits + shift) << 16;
41450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((vn.Is8B() && vd.Is8H()) ||
41470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4H() && vd.Is4S()) ||
41480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is2S() && vd.Is2D()) ||
41490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is16B() && vd.Is8H())||
41500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is8H() && vd.Is4S()) ||
41510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (vn.Is4S() && vd.Is2D()));
41520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q;
41530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  q = vn.IsD() ? 0 : NEON_Q;
41540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | op | immh_immb | Rn(vn) | Rd(vd));
41550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONShiftImmediateN(const VRegister& vd,
41590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    const VRegister& vn,
41600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    int shift,
41610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                    NEONShiftImmediateOp op) {
41620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr q, scalar;
41630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int laneSizeInBits = vd.LaneSizeInBits();
41640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift >= 1) && (shift <= laneSizeInBits));
41650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int immh_immb = (2 * laneSizeInBits - shift) << 16;
41660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vn.IsScalar()) {
41680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((vd.Is1B() && vn.Is1H()) ||
41690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is1H() && vn.Is1S()) ||
41700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is1S() && vn.Is1D()));
41710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = NEON_Q;
41720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = NEONScalar;
41730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
41740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((vd.Is8B() && vn.Is8H()) ||
41750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is4H() && vn.Is4S()) ||
41760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is2S() && vn.Is2D()) ||
41770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is16B() && vn.Is8H())||
41780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is8H() && vn.Is4S()) ||
41790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (vd.Is4S() && vn.Is2D()));
41800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    scalar = 0;
41810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    q = vd.IsD() ? 0 : NEON_Q;
41820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
41830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | op | scalar | immh_immb | Rn(vn) | Rd(vd));
41840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::shl(const VRegister& vd,
41880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
41890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int shift) {
41900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
41910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftLeftImmediate(vd, vn, shift, NEON_SHL);
41920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
41930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
41950cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sli(const VRegister& vd,
41960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
41970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int shift) {
41980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
41990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftLeftImmediate(vd, vn, shift, NEON_SLI);
42000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42030cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshl(const VRegister& vd,
42040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
42050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
42060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftLeftImmediate(vd, vn, shift, NEON_SQSHL_imm);
42070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42100cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshlu(const VRegister& vd,
42110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
42120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
42130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftLeftImmediate(vd, vn, shift, NEON_SQSHLU);
42140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42170cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqshl(const VRegister& vd,
42180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
42190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
42200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftLeftImmediate(vd, vn, shift, NEON_UQSHL_imm);
42210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sshll(const VRegister& vd,
42250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
42260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
42270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsD());
42280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateL(vd, vn, shift, NEON_SSHLL);
42290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sshll2(const VRegister& vd,
42330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
42340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
42350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsQ());
42360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateL(vd, vn, shift, NEON_SSHLL);
42370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sxtl(const VRegister& vd,
42410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
42420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sshll(vd, vn, 0);
42430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sxtl2(const VRegister& vd,
42470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
42480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  sshll2(vd, vn, 0);
42490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ushll(const VRegister& vd,
42530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
42540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
42550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsD());
42560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateL(vd, vn, shift, NEON_USHLL);
42570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ushll2(const VRegister& vd,
42610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
42620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
42630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsQ());
42640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateL(vd, vn, shift, NEON_USHLL);
42650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uxtl(const VRegister& vd,
42690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn) {
42700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ushll(vd, vn, 0);
42710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42740cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uxtl2(const VRegister& vd,
42750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn) {
42760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  ushll2(vd, vn, 0);
42770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42800cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sri(const VRegister& vd,
42810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& vn,
42820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    int shift) {
42830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
42840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_SRI);
42850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sshr(const VRegister& vd,
42890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
42900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
42910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
42920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_SSHR);
42930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
42940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
42960cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ushr(const VRegister& vd,
42970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
42980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
42990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_USHR);
43010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43040cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::srshr(const VRegister& vd,
43050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_SRSHR);
43090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::urshr(const VRegister& vd,
43130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_URSHR);
43170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ssra(const VRegister& vd,
43210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
43220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
43230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_SSRA);
43250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::usra(const VRegister& vd,
43290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
43300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
43310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_USRA);
43330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43360cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::srsra(const VRegister& vd,
43370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_SRSRA);
43410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43440cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ursra(const VRegister& vd,
43450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsVector() || vd.Is1D());
43480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftRightImmediate(vd, vn, shift, NEON_URSRA);
43490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::shrn(const VRegister& vd,
43530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     const VRegister& vn,
43540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                     int shift) {
43550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsD());
43560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SHRN);
43570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43600cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::shrn2(const VRegister& vd,
43610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
43640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SHRN);
43650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rshrn(const VRegister& vd,
43690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      const VRegister& vn,
43700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                      int shift) {
43710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsD());
43720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_RSHRN);
43730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::rshrn2(const VRegister& vd,
43770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
43780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
43790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
43800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_RSHRN);
43810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43840cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshrn(const VRegister& vd,
43850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
43860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
43870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
43880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQSHRN);
43890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43920cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshrn2(const VRegister& vd,
43930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
43940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        int shift) {
43950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
43960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQSHRN);
43970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
43980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
43990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44000cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqrshrn(const VRegister& vd,
44010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
44020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        int shift) {
44030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
44040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQRSHRN);
44050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqrshrn2(const VRegister& vd,
44090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vn,
44100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         int shift) {
44110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
44120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQRSHRN);
44130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshrun(const VRegister& vd,
44170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
44180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        int shift) {
44190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
44200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQSHRUN);
44210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqshrun2(const VRegister& vd,
44250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vn,
44260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         int shift) {
44270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
44280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQSHRUN);
44290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44320cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqrshrun(const VRegister& vd,
44330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vn,
44340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         int shift) {
44350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
44360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQRSHRUN);
44370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::sqrshrun2(const VRegister& vd,
44410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const VRegister& vn,
44420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          int shift) {
44430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
44440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_SQRSHRUN);
44450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44480cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqshrn(const VRegister& vd,
44490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const VRegister& vn,
44500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       int shift) {
44510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
44520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_UQSHRN);
44530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44560cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqshrn2(const VRegister& vd,
44570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
44580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        int shift) {
44590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
44600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_UQSHRN);
44610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44640cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqrshrn(const VRegister& vd,
44650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const VRegister& vn,
44660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        int shift) {
44670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.IsD() || (vn.IsScalar() && vd.IsScalar()));
44680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_UQRSHRN);
44690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::uqrshrn2(const VRegister& vd,
44730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const VRegister& vn,
44740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         int shift) {
44750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vn.IsVector() && vd.IsQ());
44760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  NEONShiftImmediateN(vd, vn, shift, NEON_UQRSHRN);
44770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Note:
44810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Below, a difference in case for the same letter indicates a
44820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// negated bit.
44830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// If b is 1, then B is 0.
44840cc8b6ece4b3e757e11a906a81ece292437713abarmvixluint32_t Assembler::FP32ToImm8(float imm) {
44850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsImmFP32(imm));
44860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits: aBbb.bbbc.defg.h000.0000.0000.0000.0000
44870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bits = float_to_rawbits(imm);
44880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit7: a000.0000
44890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit7 = ((bits >> 31) & 0x1) << 7;
44900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit6: 0b00.0000
44910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit6 = ((bits >> 29) & 0x1) << 6;
44920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit5_to_0: 00cd.efgh
44930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit5_to_0 = (bits >> 19) & 0x3f;
44940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return bit7 | bit6 | bit5_to_0;
44960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
44970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
44990cc8b6ece4b3e757e11a906a81ece292437713abarmvixlInstr Assembler::ImmFP32(float imm) {
45000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FP32ToImm8(imm) << ImmFP_offset;
45010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45040cc8b6ece4b3e757e11a906a81ece292437713abarmvixluint32_t Assembler::FP64ToImm8(double imm) {
45050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(IsImmFP64(imm));
45060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
45070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //       0000.0000.0000.0000.0000.0000.0000.0000
45080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t bits = double_to_rawbits(imm);
45090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit7: a000.0000
45100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit7 = ((bits >> 63) & 0x1) << 7;
45110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit6: 0b00.0000
45120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit6 = ((bits >> 61) & 0x1) << 6;
45130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit5_to_0: 00cd.efgh
45140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bit5_to_0 = (bits >> 48) & 0x3f;
45150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return bit7 | bit6 | bit5_to_0;
45170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlInstr Assembler::ImmFP64(double imm) {
45210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return FP64ToImm8(imm) << ImmFP_offset;
45220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Code generation helpers.
45260cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::MoveWide(const Register& rd,
45270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         uint64_t imm,
45280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         int shift,
45290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         MoveWideImmediateOp mov_op) {
45300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Ignore the top 32 bits of an immediate if we're moving to a W register.
45310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rd.Is32Bits()) {
45320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Check that the top 32 bits are zero (a positive 32-bit number) or top
45330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // 33 bits are one (a negative 32-bit number, sign extended to 64 bits).
45340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(((imm >> kWRegSize) == 0) ||
45350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                ((imm >> (kWRegSize - 1)) == 0x1ffffffff));
45360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    imm &= kWRegMask;
45370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
45380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (shift >= 0) {
45400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Explicit shift specified.
45410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((shift == 0) || (shift == 16) ||
45420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                (shift == 32) || (shift == 48));
45430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rd.Is64Bits() || (shift == 0) || (shift == 16));
45440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift /= 16;
45450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
45460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Calculate a new immediate and shift combination to encode the immediate
45470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // argument.
45480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    shift = 0;
45490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((imm & 0xffffffffffff0000) == 0) {
45500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Nothing to do.
45510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if ((imm & 0xffffffff0000ffff) == 0) {
45520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      imm >>= 16;
45530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift = 1;
45540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if ((imm & 0xffff0000ffffffff) == 0) {
45550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(rd.Is64Bits());
45560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      imm >>= 32;
45570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift = 2;
45580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if ((imm & 0x0000ffffffffffff) == 0) {
45590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(rd.Is64Bits());
45600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      imm >>= 48;
45610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      shift = 3;
45620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
45630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
45640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(is_uint16(imm));
45660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | MoveWideImmediateFixed | mov_op |
45680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rd(rd) | ImmMoveWide(imm) | ShiftMoveWide(shift));
45690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
45700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45720cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::AddSub(const Register& rd,
45730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Register& rn,
45740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       const Operand& operand,
45750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       FlagsUpdate S,
45760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                       AddSubOp op) {
45770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
45780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (operand.IsImmediate()) {
45790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t immediate = operand.immediate();
45800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(IsImmAddSub(immediate));
45810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
45820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) |
45830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         ImmAddSub(immediate) | dest_reg | RnSP(rn));
45840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else if (operand.IsShiftedRegister()) {
45850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.reg().size() == rd.size());
45860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.shift() != ROR);
45870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
45880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // For instructions of the form:
45890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    //   add/sub   wsp, <Wn>, <Wm> [, LSL #0-3 ]
45900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    //   add/sub   <Wd>, wsp, <Wm> [, LSL #0-3 ]
45910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    //   add/sub   wsp, wsp, <Wm> [, LSL #0-3 ]
45920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    //   adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ]
45930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // or their 64-bit register equivalents, convert the operand from shifted to
45940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // extended register mode, and emit an add/sub extended instruction.
45950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (rn.IsSP() || rd.IsSP()) {
45960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(!(rd.IsSP() && (S == SetFlags)));
45970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      DataProcExtendedRegister(rd, rn, operand.ToExtendedRegister(), S,
45980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                               AddSubExtendedFixed | op);
45990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      DataProcShiftedRegister(rd, rn, operand, S, AddSubShiftedFixed | op);
46010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
46030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.IsExtendedRegister());
46040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    DataProcExtendedRegister(rd, rn, operand, S, AddSubExtendedFixed | op);
46050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
46060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46090cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::AddSubWithCarry(const Register& rd,
46100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const Register& rn,
46110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const Operand& operand,
46120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                FlagsUpdate S,
46130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                AddSubWithCarryOp op) {
46140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
46150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == operand.reg().size());
46160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
46170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | Rn(rn) | Rd(rd));
46180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46210cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::hlt(int code) {
46220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(is_uint16(code));
46230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(HLT | ImmException(code));
46240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46270cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::brk(int code) {
46280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(is_uint16(code));
46290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(BRK | ImmException(code));
46300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46330cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::svc(int code) {
46340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SVC | ImmException(code));
46350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// TODO(all): The third parameter should be passed by reference but gcc 4.8.2
46390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// reports a bogus uninitialised warning then.
46400cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::Logical(const Register& rd,
46410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Register& rn,
46420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const Operand operand,
46430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        LogicalOp op) {
46440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
46450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (operand.IsImmediate()) {
46460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t immediate = operand.immediate();
46470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    unsigned reg_size = rd.size();
46480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(immediate != 0);
46500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(immediate != -1);
46510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rd.Is64Bits() || is_uint32(immediate));
46520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If the operation is NOT, invert the operation and immediate.
46540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((op & NOT) == NOT) {
46550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      op = static_cast<LogicalOp>(op & ~NOT);
46560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask);
46570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    unsigned n, imm_s, imm_r;
46600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (IsImmLogical(immediate, reg_size, &n, &imm_s, &imm_r)) {
46610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Immediate can be encoded in the instruction.
46620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      LogicalImmediate(rd, rn, n, imm_s, imm_r, op);
46630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
46640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // This case is handled in the macro assembler.
46650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_UNREACHABLE();
46660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
46670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
46680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.IsShiftedRegister());
46690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.reg().size() == rd.size());
46700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed);
46710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op);
46720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
46730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46760cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LogicalImmediate(const Register& rd,
46770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 const Register& rn,
46780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 unsigned n,
46790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 unsigned imm_s,
46800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 unsigned imm_r,
46810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                 LogicalOp op) {
46820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned reg_size = rd.size();
46830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr dest_reg = (op == ANDS) ? Rd(rd) : RdSP(rd);
46840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | LogicalImmediateFixed | op | BitN(n, reg_size) |
46850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ImmSetBits(imm_s, reg_size) | ImmRotate(imm_r, reg_size) | dest_reg |
46860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rn(rn));
46870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
46880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
46900cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::ConditionalCompare(const Register& rn,
46910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   const Operand& operand,
46920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   StatusFlags nzcv,
46930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   Condition cond,
46940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                   ConditionalCompareOp op) {
46950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr ccmpop;
46960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (operand.IsImmediate()) {
46970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int64_t immediate = operand.immediate();
46980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(IsImmConditionalCompare(immediate));
46990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate);
47000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
47010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
47020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg());
47030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv));
47050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::DataProcessing1Source(const Register& rd,
47090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      const Register& rn,
47100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      DataProcessing1SourceOp op) {
47110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() == rn.size());
47120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rn) | op | Rn(rn) | Rd(rd));
47130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47160cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FPDataProcessing1Source(const VRegister& vd,
47170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const VRegister& vn,
47180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        FPDataProcessing1SourceOp op) {
47190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1H() || vd.Is1S() || vd.Is1D());
47200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vn) | op | Rn(vn) | Rd(vd));
47210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47240cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::FPDataProcessing3Source(const VRegister& vd,
47250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const VRegister& vn,
47260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const VRegister& vm,
47270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const VRegister& va,
47280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        FPDataProcessing3SourceOp op) {
47290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is1S() || vd.Is1D());
47300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(vd, vn, vm, va));
47310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(FPType(vd) | op | Rm(vm) | Rn(vn) | Rd(vd) | Ra(va));
47320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONModifiedImmShiftLsl(const VRegister& vd,
47360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const int imm8,
47370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const int left_shift,
47380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        NEONModifiedImmediateOp op) {
47390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is8B() || vd.Is16B() || vd.Is4H() || vd.Is8H() ||
47400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              vd.Is2S() || vd.Is4S());
47410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((left_shift == 0) || (left_shift == 8) ||
47420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (left_shift == 16) || (left_shift == 24));
47430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(is_uint8(imm8));
47440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int cmode_1, cmode_2, cmode_3;
47460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (vd.Is8B() || vd.Is16B()) {
47470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(op == NEONModifiedImmediate_MOVI);
47480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_1 = 1;
47490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_2 = 1;
47500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_3 = 1;
47510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
47520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_1 = (left_shift >> 3) & 1;
47530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_2 = left_shift >> 4;
47540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    cmode_3 = 0;
47550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (vd.Is4H() || vd.Is8H()) {
47560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT((left_shift == 0) || (left_shift == 8));
47570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      cmode_3 = 1;
47580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
47590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
47600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int cmode = (cmode_3 << 3) | (cmode_2 << 2) | (cmode_1 << 1);
47610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int q = vd.IsQ() ? NEON_Q : 0;
47630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | op | ImmNEONabcdefgh(imm8) | NEONCmode(cmode) | Rd(vd));
47650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47680cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::NEONModifiedImmShiftMsl(const VRegister& vd,
47690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const int imm8,
47700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const int shift_amount,
47710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        NEONModifiedImmediateOp op) {
47720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(vd.Is2S() || vd.Is4S());
47730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((shift_amount == 8) || (shift_amount == 16));
47740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(is_uint8(imm8));
47750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int cmode_0 = (shift_amount >> 4) & 1;
47770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int cmode = 0xc | cmode_0;
47780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int q = vd.IsQ() ? NEON_Q : 0;
47800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(q | op | ImmNEONabcdefgh(imm8) | NEONCmode(cmode) | Rd(vd));
47820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
47830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
47850cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::EmitShift(const Register& rd,
47860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const Register& rn,
47870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          Shift shift,
47880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          unsigned shift_amount) {
47890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  switch (shift) {
47900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case LSL:
47910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      lsl(rd, rn, shift_amount);
47920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
47930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case LSR:
47940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      lsr(rd, rn, shift_amount);
47950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
47960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case ASR:
47970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      asr(rd, rn, shift_amount);
47980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
47990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    case ROR:
48000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      ror(rd, rn, shift_amount);
48010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      break;
48020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    default:
48030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_UNREACHABLE();
48040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48080cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::EmitExtendShift(const Register& rd,
48090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                const Register& rn,
48100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                Extend extend,
48110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                unsigned left_shift) {
48120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rd.size() >= rn.size());
48130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned reg_size = rd.size();
48140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Use the correct size of register.
48150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Register rn_ = Register(rn.code(), rd.size());
48160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Bits extracted are high_bit:0.
48170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned high_bit = (8 << (extend & 0x3)) - 1;
48180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Number of bits left in the result that are not introduced by the shift.
48190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1);
48200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) {
48220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (extend) {
48230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case UXTB:
48240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case UXTH:
48250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break;
48260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case SXTB:
48270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case SXTH:
48280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case SXTW: sbfm(rd, rn_, non_shift_bits, high_bit); break;
48290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case UXTX:
48300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case SXTX: {
48310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rn.size() == kXRegSize);
48320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        // Nothing to extend. Just shift.
48330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        lsl(rd, rn_, left_shift);
48340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        break;
48350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      }
48360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default: VIXL_UNREACHABLE();
48370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
48390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // No need to extend as the extended bits would be shifted away.
48400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    lsl(rd, rn_, left_shift);
48410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48450cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::DataProcShiftedRegister(const Register& rd,
48460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const Register& rn,
48470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        const Operand& operand,
48480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        FlagsUpdate S,
48490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                        Instr op) {
48500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(operand.IsShiftedRegister());
48510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rn.Is64Bits() || (rn.Is32Bits() &&
48520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              is_uint5(operand.shift_amount())));
48530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | op | Flags(S) |
48540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) |
48550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       Rm(operand.reg()) | Rn(rn) | Rd(rd));
48560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48590cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::DataProcExtendedRegister(const Register& rd,
48600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         const Register& rn,
48610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         const Operand& operand,
48620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         FlagsUpdate S,
48630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         Instr op) {
48640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
48650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) |
48660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       ExtendMode(operand.extend()) | ImmExtendShift(operand.shift_amount()) |
48670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl       dest_reg | RnSP(rn));
48680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
48690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48710cc8b6ece4b3e757e11a906a81ece292437713abarmvixlInstr Assembler::LoadStoreMemOperand(const MemOperand& addr,
48720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                     unsigned access_size,
48730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                     LoadStoreScalingOption option) {
48740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr base = RnSP(addr.base());
48750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int64_t offset = addr.offset();
48760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsImmediateOffset()) {
48780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    bool prefer_unscaled = (option == PreferUnscaledOffset) ||
48790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                           (option == RequireUnscaledOffset);
48800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (prefer_unscaled && IsImmLSUnscaled(offset)) {
48810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Use the unscaled addressing mode.
48820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return base | LoadStoreUnscaledOffsetFixed | ImmLS(offset);
48830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((option != RequireUnscaledOffset) &&
48860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        IsImmLSScaled(offset, access_size)) {
48870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Use the scaled addressing mode.
48880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return base | LoadStoreUnsignedOffsetFixed |
48890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl          ImmLSUnsigned(offset >> access_size);
48900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if ((option != RequireScaledOffset) && IsImmLSUnscaled(offset)) {
48930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Use the unscaled addressing mode.
48940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return base | LoadStoreUnscaledOffsetFixed | ImmLS(offset);
48950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
48960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
48970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
48980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // All remaining addressing modes are register-offset, pre-indexed or
48990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // post-indexed modes.
49000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((option != RequireUnscaledOffset) &&
49010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl              (option != RequireScaledOffset));
49020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsRegisterOffset()) {
49040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Extend ext = addr.extend();
49050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    Shift shift = addr.shift();
49060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    unsigned shift_amount = addr.shift_amount();
49070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // LSL is encoded in the option field as UXTX.
49090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (shift == LSL) {
49100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      ext = UXTX;
49110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
49120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Shifts are encoded in one bit, indicating a left shift by the memory
49140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // access size.
49150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT((shift_amount == 0) || (shift_amount == access_size));
49160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return base | LoadStoreRegisterOffsetFixed | Rm(addr.regoffset()) |
49170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0);
49180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsPreIndex() && IsImmLSUnscaled(offset)) {
49210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return base | LoadStorePreIndexFixed | ImmLS(offset);
49220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (addr.IsPostIndex() && IsImmLSUnscaled(offset)) {
49250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return base | LoadStorePostIndexFixed | ImmLS(offset);
49260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // If this point is reached, the MemOperand (addr) cannot be encoded.
49290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_UNREACHABLE();
49300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return 0;
49310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49340cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::LoadStore(const CPURegister& rt,
49350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          const MemOperand& addr,
49360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          LoadStoreOp op,
49370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                          LoadStoreScalingOption option) {
49380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(op | Rt(rt) | LoadStoreMemOperand(addr, CalcLSDataSize(op), option));
49390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49420cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Assembler::Prefetch(PrefetchOperation op,
49430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         const MemOperand& addr,
49440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                         LoadStoreScalingOption option) {
49450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(addr.IsRegisterOffset() || addr.IsImmediateOffset());
49460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Instr prfop = ImmPrefetchOperation(op);
49480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  Emit(PRFM | prfop | LoadStoreMemOperand(addr, kXRegSizeInBytesLog2, option));
49490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49520cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmAddSub(int64_t immediate) {
49530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return is_uint12(immediate) ||
49540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0));
49550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49580cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmConditionalCompare(int64_t immediate) {
49590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return is_uint5(immediate);
49600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49630cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmFP32(float imm) {
49640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Valid values will have the form:
49650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // aBbb.bbbc.defg.h000.0000.0000.0000.0000
49660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t bits = float_to_rawbits(imm);
49670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits[19..0] are cleared.
49680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((bits & 0x7ffff) != 0) {
49690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
49700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits[29..25] are all set or all cleared.
49730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t b_pattern = (bits >> 16) & 0x3e00;
49740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (b_pattern != 0 && b_pattern != 0x3e00) {
49750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
49760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit[30] and bit[29] are opposite.
49790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (((bits ^ (bits << 1)) & 0x40000000) == 0) {
49800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
49810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return true;
49840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
49850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49870cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmFP64(double imm) {
49880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Valid values will have the form:
49890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
49900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 0000.0000.0000.0000.0000.0000.0000.0000
49910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t bits = double_to_rawbits(imm);
49920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits[47..0] are cleared.
49930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((bits & 0x0000ffffffffffff) != 0) {
49940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
49950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
49960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
49970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bits[61..54] are all set or all cleared.
49980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint32_t b_pattern = (bits >> 48) & 0x3fc0;
49990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((b_pattern != 0) && (b_pattern != 0x3fc0)) {
50000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
50010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
50020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bit[62] and bit[61] are opposite.
50040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (((bits ^ (bits << 1)) & (UINT64_C(1) << 62)) == 0) {
50050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
50060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
50070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return true;
50090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50120cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmLSPair(int64_t offset, unsigned access_size) {
50130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(access_size <= kQRegSizeInBytesLog2);
50140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool offset_is_size_multiple =
50150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (((offset >> access_size) << access_size) == offset);
50160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return offset_is_size_multiple && is_int7(offset >> access_size);
50170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50200cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmLSScaled(int64_t offset, unsigned access_size) {
50210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(access_size <= kQRegSizeInBytesLog2);
50220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool offset_is_size_multiple =
50230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      (((offset >> access_size) << access_size) == offset);
50240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return offset_is_size_multiple && is_uint12(offset >> access_size);
50250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50280cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmLSUnscaled(int64_t offset) {
50290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return is_int9(offset);
50300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// The movn instruction can generate immediates containing an arbitrary 16-bit
50340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// value, with remaining bits set, eg. 0xffff1234, 0xffff1234ffffffff.
50350cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmMovn(uint64_t imm, unsigned reg_size) {
50360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return IsImmMovz(~imm, reg_size);
50370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// The movz instruction can generate immediates containing an arbitrary 16-bit
50410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// value, with remaining bits clear, eg. 0x00001234, 0x0000123400000000.
50420cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmMovz(uint64_t imm, unsigned reg_size) {
50430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((reg_size == kXRegSize) || (reg_size == kWRegSize));
50440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return CountClearHalfWords(imm, reg_size) >= ((reg_size / 16) - 1);
50450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
50460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Test if a given value can be encoded in the immediate field of a logical
50490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// instruction.
50500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// If it can be encoded, the function returns true, and values pointed to by n,
50510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// imm_s and imm_r are updated with immediates encoded in the format required
50520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// by the corresponding fields in the logical instruction.
50530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// If it can not be encoded, the function returns false, and the values pointed
50540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// to by n, imm_s and imm_r are undefined.
50550cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool Assembler::IsImmLogical(uint64_t value,
50560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             unsigned width,
50570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             unsigned* n,
50580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             unsigned* imm_s,
50590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                             unsigned* imm_r) {
50600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((width == kWRegSize) || (width == kXRegSize));
50610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool negate = false;
50630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Logical immediates are encoded using parameters n, imm_s and imm_r using
50650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // the following table:
50660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
50670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    N   imms    immr    size        S             R
50680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    1  ssssss  rrrrrr    64    UInt(ssssss)  UInt(rrrrrr)
50690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0  0sssss  xrrrrr    32    UInt(sssss)   UInt(rrrrr)
50700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0  10ssss  xxrrrr    16    UInt(ssss)    UInt(rrrr)
50710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0  110sss  xxxrrr     8    UInt(sss)     UInt(rrr)
50720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0  1110ss  xxxxrr     4    UInt(ss)      UInt(rr)
50730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0  11110s  xxxxxr     2    UInt(s)       UInt(r)
50740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // (s bits must not be all set)
50750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
50760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // A pattern is constructed of size bits, where the least significant S+1 bits
50770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // are set. The pattern is rotated right by R, and repeated across a 32 or
50780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // 64-bit value, depending on destination register width.
50790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
50800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Put another way: the basic format of a logical immediate is a single
50810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // contiguous stretch of 1 bits, repeated across the whole word at intervals
50820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // given by a power of 2. To identify them quickly, we first locate the
50830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // lowest stretch of 1 bits, then the next 1 bit above that; that combination
50840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // is different for every logical immediate, so it gives us all the
50850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // information we need to identify the only logical immediate that our input
50860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // could be, and then we simply check if that's the value we actually have.
50870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
50880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // (The rotation parameter does give the possibility of the stretch of 1 bits
50890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // going 'round the end' of the word. To deal with that, we observe that in
50900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // any situation where that happens the bitwise NOT of the value is also a
50910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // valid logical immediate. So we simply invert the input whenever its low bit
50920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // is set, and then we know that the rotated case can't arise.)
50930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
50940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value & 1) {
50950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If the low bit is 1, negate the value, and set a flag to remember that we
50960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // did (so that we can adjust the return values appropriately).
50970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    negate = true;
50980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    value = ~value;
50990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
51000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (width == kWRegSize) {
51020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // To handle 32-bit logical immediates, the very easiest thing is to repeat
51030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // the input value twice to make a 64-bit word. The correct encoding of that
51040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // as a logical immediate will also be the correct encoding of the 32-bit
51050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // value.
51060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Avoid making the assumption that the most-significant 32 bits are zero by
51080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // shifting the value left and duplicating it.
51090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    value <<= kWRegSize;
51100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    value |= value >> kWRegSize;
51110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
51120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // The basic analysis idea: imagine our input word looks like this.
51140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
51150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0011111000111110001111100011111000111110001111100011111000111110
51160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //                                                          c  b    a
51170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //                                                          |<--d-->|
51180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
51190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We find the lowest set bit (as an actual power-of-2 value, not its index)
51200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // and call it a. Then we add a to our original number, which wipes out the
51210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // bottommost stretch of set bits and replaces it with a 1 carried into the
51220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // next zero bit. Then we look for the new lowest set bit, which is in
51230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // position b, and subtract it, so now our number is just like the original
51240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // but with the lowest stretch of set bits completely gone. Now we find the
51250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // lowest set bit again, which is position c in the diagram above. Then we'll
51260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // measure the distance d between bit positions a and c (using CLZ), and that
51270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // tells us that the only valid logical immediate that could possibly be equal
51280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // to this number is the one in which a stretch of bits running from a to just
51290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // below b is replicated every d bits.
51300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t a = LowestSetBit(value);
51310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value_plus_a = value + a;
51320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t b = LowestSetBit(value_plus_a);
51330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t value_plus_a_minus_b = value_plus_a - b;
51340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t c = LowestSetBit(value_plus_a_minus_b);
51350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int d, clz_a, out_n;
51370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t mask;
51380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (c != 0) {
51400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // The general case, in which there is more than one stretch of set bits.
51410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Compute the repeat distance d, and set up a bitmask covering the basic
51420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // unit of repetition (i.e. a word with the bottom d bits set). Also, in all
51430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // of these cases the N bit of the output will be zero.
51440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    clz_a = CountLeadingZeros(a, kXRegSize);
51450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    int clz_c = CountLeadingZeros(c, kXRegSize);
51460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    d = clz_a - clz_c;
51470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    mask = ((UINT64_C(1) << d) - 1);
51480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    out_n = 0;
51490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
51500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // Handle degenerate cases.
51510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    //
51520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If any of those 'find lowest set bit' operations didn't find a set bit at
51530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // all, then the word will have been zero thereafter, so in particular the
51540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // last lowest_set_bit operation will have returned zero. So we can test for
51550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // all the special case conditions in one go by seeing if c is zero.
51560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (a == 0) {
51570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // The input was zero (or all 1 bits, which will come to here too after we
51580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // inverted it at the start of the function), for which we just return
51590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // false.
51600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      return false;
51610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
51620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // Otherwise, if c was zero but a was not, then there's just one stretch
51630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // of set bits in our word, meaning that we have the trivial case of
51640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // d == 64 and only one 'repetition'. Set up all the same variables as in
51650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      // the general case above, and set the N bit in the output.
51660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      clz_a = CountLeadingZeros(a, kXRegSize);
51670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      d = 64;
51680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      mask = ~UINT64_C(0);
51690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      out_n = 1;
51700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
51710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
51720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // If the repeat period d is not a power of two, it can't be encoded.
51740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (!IsPowerOf2(d)) {
51750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
51760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
51770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (((b - a) & ~mask) != 0) {
51790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If the bit stretch (b - a) does not fit within the mask derived from the
51800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // repeat period, then fail.
51810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
51820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
51830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
51840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // The only possible option is b - a repeated every d bits. Now we're going to
51850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // actually construct the valid logical immediate derived from that
51860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // specification, and see if it equals our original input.
51870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
51880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // To repeat a value every d bits, we multiply it by a number of the form
51890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // (1 + 2^d + 2^(2d) + ...), i.e. 0x0001000100010001 or similar. These can
51900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // be derived using a table lookup on CLZ(d).
51910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  static const uint64_t multipliers[] = {
51920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x0000000000000001UL,
51930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x0000000100000001UL,
51940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x0001000100010001UL,
51950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x0101010101010101UL,
51960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x1111111111111111UL,
51970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    0x5555555555555555UL,
51980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  };
51990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t multiplier = multipliers[CountLeadingZeros(d, kXRegSize) - 57];
52000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  uint64_t candidate = (b - a) * multiplier;
52010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (value != candidate) {
52030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // The candidate pattern doesn't match our input value, so fail.
52040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return false;
52050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
52060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // We have a match! This is a valid logical immediate, so now we have to
52080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // construct the bits and pieces of the instruction encoding that generates
52090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // it.
52100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Count the set bits in our basic stretch. The special case of clz(0) == -1
52120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // makes the answer come out right for stretches that reach the very top of
52130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // the word (e.g. numbers like 0xffffc00000000000).
52140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int clz_b = (b == 0) ? -1 : CountLeadingZeros(b, kXRegSize);
52150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int s = clz_a - clz_b;
52160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Decide how many bits to rotate right by, to put the low bit of that basic
52180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // stretch in position a.
52190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int r;
52200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (negate) {
52210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // If we inverted the input right at the start of this function, here's
52220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // where we compensate: the number of set bits becomes the number of clear
52230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // bits, and the rotation count is based on position b rather than position
52240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    // a (since b is the location of the 'lowest' 1 bit after inversion).
52250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    s = d - s;
52260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    r = (clz_b + 1) & (d - 1);
52270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
52280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    r = (clz_a + 1) & (d - 1);
52290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
52300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // Now we're done, except for having to encode the S output in such a way that
52320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // it gives both the number of set bits and the length of the repeated
52330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // segment. The s field is encoded like this:
52340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
52350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //     imms    size        S
52360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    ssssss    64    UInt(ssssss)
52370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    0sssss    32    UInt(sssss)
52380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    10ssss    16    UInt(ssss)
52390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    110sss     8    UInt(sss)
52400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    1110ss     4    UInt(ss)
52410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //    11110s     2    UInt(s)
52420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  //
52430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  // So we 'or' (-d << 1) with our computed s to form imms.
52440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if ((n != NULL) || (imm_s != NULL) || (imm_r != NULL)) {
52450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    *n = out_n;
52460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    *imm_s = ((-d << 1) | (s - 1)) & 0x3f;
52470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    *imm_r = r;
52480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
52490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return true;
52510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
52520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52540cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStoreOp Assembler::LoadOpFor(const CPURegister& rt) {
52550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.IsValid());
52560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rt.IsRegister()) {
52570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return rt.Is64Bits() ? LDR_x : LDR_w;
52580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
52590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rt.IsVRegister());
52600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rt.SizeInBits()) {
52610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kBRegSize: return LDR_b;
52620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kHRegSize: return LDR_h;
52630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kSRegSize: return LDR_s;
52640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kDRegSize: return LDR_d;
52650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
52660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rt.IsQ());
52670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return LDR_q;
52680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
52690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
52700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
52710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52730cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStoreOp Assembler::StoreOpFor(const CPURegister& rt) {
52740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(rt.IsValid());
52750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rt.IsRegister()) {
52760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return rt.Is64Bits() ? STR_x : STR_w;
52770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
52780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rt.IsVRegister());
52790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rt.SizeInBits()) {
52800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kBRegSize: return STR_b;
52810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kHRegSize: return STR_h;
52820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kSRegSize: return STR_s;
52830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kDRegSize: return STR_d;
52840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
52850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rt.IsQ());
52860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return STR_q;
52870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
52880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
52890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
52900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
52920cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStorePairOp Assembler::StorePairOpFor(const CPURegister& rt,
52930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    const CPURegister& rt2) {
52940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
52950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(rt2);
52960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rt.IsRegister()) {
52970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return rt.Is64Bits() ? STP_x : STP_w;
52980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
52990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rt.IsVRegister());
53000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rt.SizeInBytes()) {
53010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kSRegSizeInBytes: return STP_s;
53020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kDRegSizeInBytes: return STP_d;
53030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
53040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rt.IsQ());
53050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return STP_q;
53060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
53070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
53080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53110cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStorePairOp Assembler::LoadPairOpFor(const CPURegister& rt,
53120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                         const CPURegister& rt2) {
53130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((STP_w | LoadStorePairLBit) == LDP_w);
53140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return static_cast<LoadStorePairOp>(StorePairOpFor(rt, rt2) |
53150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                                      LoadStorePairLBit);
53160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStorePairNonTemporalOp Assembler::StorePairNonTemporalOpFor(
53200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    const CPURegister& rt, const CPURegister& rt2) {
53210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
53220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  USE(rt2);
53230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rt.IsRegister()) {
53240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return rt.Is64Bits() ? STNP_x : STNP_w;
53250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
53260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rt.IsVRegister());
53270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rt.SizeInBytes()) {
53280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kSRegSizeInBytes: return STNP_s;
53290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kDRegSizeInBytes: return STNP_d;
53300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
53310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rt.IsQ());
53320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return STNP_q;
53330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
53340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
53350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53380cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadStorePairNonTemporalOp Assembler::LoadPairNonTemporalOpFor(
53390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    const CPURegister& rt, const CPURegister& rt2) {
53400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT((STNP_w | LoadStorePairNonTemporalLBit) == LDNP_w);
53410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return static_cast<LoadStorePairNonTemporalOp>(
53420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      StorePairNonTemporalOpFor(rt, rt2) | LoadStorePairNonTemporalLBit);
53430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53460cc8b6ece4b3e757e11a906a81ece292437713abarmvixlLoadLiteralOp Assembler::LoadLiteralOpFor(const CPURegister& rt) {
53470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  if (rt.IsRegister()) {
53480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    return rt.IsX() ? LDR_x_lit : LDR_w_lit;
53490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  } else {
53500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    VIXL_ASSERT(rt.IsVRegister());
53510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    switch (rt.SizeInBytes()) {
53520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kSRegSizeInBytes: return LDR_s_lit;
53530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      case kDRegSizeInBytes: return LDR_d_lit;
53540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      default:
53550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        VIXL_ASSERT(rt.IsQ());
53560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl        return LDR_q_lit;
53570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
53580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
53590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53620cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool AreAliased(const CPURegister& reg1, const CPURegister& reg2,
53630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                const CPURegister& reg3, const CPURegister& reg4,
53640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                const CPURegister& reg5, const CPURegister& reg6,
53650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                const CPURegister& reg7, const CPURegister& reg8) {
53660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int number_of_valid_regs = 0;
53670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int number_of_valid_fpregs = 0;
53680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  RegList unique_regs = 0;
53700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  RegList unique_fpregs = 0;
53710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  const CPURegister regs[] = {reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8};
53730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  for (unsigned i = 0; i < sizeof(regs) / sizeof(regs[0]); i++) {
53750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    if (regs[i].IsRegister()) {
53760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      number_of_valid_regs++;
53770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      unique_regs |= regs[i].Bit();
53780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else if (regs[i].IsVRegister()) {
53790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      number_of_valid_fpregs++;
53800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      unique_fpregs |= regs[i].Bit();
53810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    } else {
53820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl      VIXL_ASSERT(!regs[i].IsValid());
53830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl    }
53840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  }
53850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int number_of_unique_regs = CountSetBits(unique_regs);
53870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  int number_of_unique_fpregs = CountSetBits(unique_fpregs);
53880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(number_of_valid_regs >= number_of_unique_regs);
53900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(number_of_valid_fpregs >= number_of_unique_fpregs);
53910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return (number_of_valid_regs != number_of_unique_regs) ||
53930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl         (number_of_valid_fpregs != number_of_unique_fpregs);
53940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
53950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
53970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool AreSameSizeAndType(const CPURegister& reg1, const CPURegister& reg2,
53980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const CPURegister& reg3, const CPURegister& reg4,
53990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const CPURegister& reg5, const CPURegister& reg6,
54000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                        const CPURegister& reg7, const CPURegister& reg8) {
54010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg1.IsValid());
54020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool match = true;
54030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg2.IsValid() || reg2.IsSameSizeAndType(reg1);
54040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1);
54050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1);
54060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1);
54070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1);
54080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1);
54090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1);
54100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return match;
54110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
54120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
54130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
54140cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool AreSameFormat(const VRegister& reg1, const VRegister& reg2,
54150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                   const VRegister& reg3, const VRegister& reg4) {
54160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg1.IsValid());
54170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool match = true;
54180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg2.IsValid() || reg2.IsSameFormat(reg1);
54190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg3.IsValid() || reg3.IsSameFormat(reg1);
54200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg4.IsValid() || reg4.IsSameFormat(reg1);
54210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return match;
54220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
54230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
54240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl
54250cc8b6ece4b3e757e11a906a81ece292437713abarmvixlbool AreConsecutive(const VRegister& reg1, const VRegister& reg2,
54260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl                    const VRegister& reg3, const VRegister& reg4) {
54270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  VIXL_ASSERT(reg1.IsValid());
54280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  bool match = true;
54290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg2.IsValid() ||
54300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl           (reg2.code() == ((reg1.code() + 1) % kNumberOfVRegisters));
54310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg3.IsValid() ||
54320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl           (reg3.code() == ((reg1.code() + 2) % kNumberOfVRegisters));
54330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  match &= !reg4.IsValid() ||
54340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl           (reg4.code() == ((reg1.code() + 3) % kNumberOfVRegisters));
54350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  return match;
54360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}
54370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl}  // namespace vixl
5438