1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved.
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met:
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions of source code must retain the above copyright notice,
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer.
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer in the documentation
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     and/or other materials provided with the distribution.
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     used to endorse or promote products derived from this software without
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     specific prior written permission.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <cmath>
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/assembler-a64.h"
30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CPURegList utilities.
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegister CPURegList::PopLowestIndex() {
35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (IsEmpty()) {
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NoCPUReg;
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int index = CountTrailingZeros(list_, kRegListSizeInBits);
391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((1 << index) & list_);
40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Remove(index);
41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return CPURegister(index, size_, type_);
42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegister CPURegList::PopHighestIndex() {
461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsValid());
47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (IsEmpty()) {
48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return NoCPUReg;
49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int index = CountLeadingZeros(list_, kRegListSizeInBits);
51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  index = kRegListSizeInBits - 1 - index;
521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((1 << index) & list_);
53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Remove(index);
54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return CPURegister(index, size_, type_);
55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool CPURegList::IsValid() const {
59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((type_ == CPURegister::kRegister) ||
60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      (type_ == CPURegister::kFPRegister)) {
61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    bool is_valid = true;
62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Try to create a CPURegister for each element in the list.
63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    for (int i = 0; i < kRegListSizeInBits; i++) {
64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (((list_ >> i) & 1) != 0) {
65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        is_valid &= CPURegister(i, size_, type_).IsValid();
66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return is_valid;
69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (type_ == CPURegister::kNoRegister) {
70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // We can't use IsEmpty here because that asserts IsValid().
71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return list_ == 0;
72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid CPURegList::RemoveCalleeSaved() {
79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (type() == CPURegister::kRegister) {
80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Remove(GetCalleeSaved(RegisterSizeInBits()));
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (type() == CPURegister::kFPRegister) {
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Remove(GetCalleeSavedFP(RegisterSizeInBits()));
83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(type() == CPURegister::kNoRegister);
851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsEmpty());
86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // The list must already be empty, so do nothing.
87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegList CPURegList::GetCalleeSaved(unsigned size) {
92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return CPURegList(CPURegister::kRegister, size, 19, 29);
93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegList CPURegList::GetCalleeSavedFP(unsigned size) {
97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return CPURegList(CPURegister::kFPRegister, size, 8, 15);
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegList CPURegList::GetCallerSaved(unsigned size) {
102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Registers x0-x18 and lr (x30) are caller-saved.
103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18);
104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  list.Combine(lr);
105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return list;
106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPURegList CPURegList::GetCallerSavedFP(unsigned size) {
110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Registers d0-d7 and d16-d31 are caller-saved.
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7);
112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31));
113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return list;
114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst CPURegList kCalleeSaved = CPURegList::GetCalleeSaved();
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst CPURegList kCalleeSavedFP = CPURegList::GetCalleeSavedFP();
119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst CPURegList kCallerSaved = CPURegList::GetCallerSaved();
120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst CPURegList kCallerSavedFP = CPURegList::GetCallerSavedFP();
121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Registers.
124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define WREG(n) w##n,
125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register Register::wregisters[] = {
126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlREGISTER_CODE_LIST(WREG)
127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef WREG
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define XREG(n) x##n,
131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register Register::xregisters[] = {
132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlREGISTER_CODE_LIST(XREG)
133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef XREG
135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define SREG(n) s##n,
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister FPRegister::sregisters[] = {
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlREGISTER_CODE_LIST(SREG)
139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef SREG
141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define DREG(n) d##n,
143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister FPRegister::dregisters[] = {
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlREGISTER_CODE_LIST(DREG)
145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl};
146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef DREG
147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register& Register::WRegFromCode(unsigned code) {
150ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  if (code == kSPRegInternalCode) {
151ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return wsp;
152ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  } else {
153ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    VIXL_ASSERT(code < kNumberOfRegisters);
154ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return wregisters[code];
155ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  }
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register& Register::XRegFromCode(unsigned code) {
160ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  if (code == kSPRegInternalCode) {
161ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return sp;
162ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  } else {
163ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    VIXL_ASSERT(code < kNumberOfRegisters);
164ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return xregisters[code];
165ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  }
166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister& FPRegister::SRegFromCode(unsigned code) {
1701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(code < kNumberOfFPRegisters);
171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return sregisters[code];
172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister& FPRegister::DRegFromCode(unsigned code) {
1761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(code < kNumberOfFPRegisters);
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return dregisters[code];
178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register& CPURegister::W() const {
1821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsValidRegister());
183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return Register::WRegFromCode(code_);
184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst Register& CPURegister::X() const {
1881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsValidRegister());
189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return Register::XRegFromCode(code_);
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister& CPURegister::S() const {
1941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsValidFPRegister());
195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return FPRegister::SRegFromCode(code_);
196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst FPRegister& CPURegister::D() const {
2001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsValidFPRegister());
201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return FPRegister::DRegFromCode(code_);
202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Operand.
206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlOperand::Operand(int64_t immediate)
207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    : immediate_(immediate),
208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      reg_(NoReg),
209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_(NO_SHIFT),
210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      extend_(NO_EXTEND),
211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_amount_(0) {}
212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlOperand::Operand(Register reg, Shift shift, unsigned shift_amount)
215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    : reg_(reg),
216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_(shift),
217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      extend_(NO_EXTEND),
218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_amount_(shift_amount) {
2191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(reg.Is64Bits() || (shift_amount < kWRegSize));
2201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(reg.Is32Bits() || (shift_amount < kXRegSize));
2211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(!reg.IsSP());
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlOperand::Operand(Register reg, Extend extend, unsigned shift_amount)
226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    : reg_(reg),
227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_(NO_SHIFT),
228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      extend_(extend),
229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift_amount_(shift_amount) {
2301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(reg.IsValid());
2311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(shift_amount <= 4);
2321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(!reg.IsSP());
233f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
234f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // Extend modes SXTX and UXTX require a 64-bit register.
2351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(reg.Is64Bits() || ((extend != SXTX) && (extend != UXTX)));
236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Operand::IsImmediate() const {
240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return reg_.Is(NoReg);
241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Operand::IsShiftedRegister() const {
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return reg_.IsValid() && (shift_ != NO_SHIFT);
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Operand::IsExtendedRegister() const {
250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return reg_.IsValid() && (extend_ != NO_EXTEND);
251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
254f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlbool Operand::IsZero() const {
255f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  if (IsImmediate()) {
256f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return immediate() == 0;
257f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  } else {
258f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl    return reg().IsZero();
259f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  }
260f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
261f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
262f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlOperand Operand::ToExtendedRegister() const {
2641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsShiftedRegister());
2651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((shift_ == LSL) && (shift_amount_ <= 4));
266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return Operand(reg_, reg_.Is64Bits() ? UXTX : UXTW, shift_amount_);
267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// MemOperand
271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlMemOperand::MemOperand(Register base, ptrdiff_t offset, AddrMode addrmode)
272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  : base_(base), regoffset_(NoReg), offset_(offset), addrmode_(addrmode) {
2731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlMemOperand::MemOperand(Register base,
278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       Register regoffset,
279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       Extend extend,
280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       unsigned shift_amount)
281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset),
282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_(NO_SHIFT), extend_(extend), shift_amount_(shift_amount) {
2831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
2841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(!regoffset.IsSP());
2851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((extend == UXTW) || (extend == SXTW) || (extend == SXTX));
286f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
287f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  // SXTX extend mode requires a 64-bit offset register.
2881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(regoffset.Is64Bits() || (extend != SXTX));
289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlMemOperand::MemOperand(Register base,
293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       Register regoffset,
294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       Shift shift,
295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       unsigned shift_amount)
296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset),
297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_(shift), extend_(NO_EXTEND), shift_amount_(shift_amount) {
2981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
2991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(regoffset.Is64Bits() && !regoffset.IsSP());
3001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(shift == LSL);
301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlMemOperand::MemOperand(Register base, const Operand& offset, AddrMode addrmode)
305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  : base_(base), regoffset_(NoReg), addrmode_(addrmode) {
3061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(base.Is64Bits() && !base.IsZero());
307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (offset.IsImmediate()) {
309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset_ = offset.immediate();
310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (offset.IsShiftedRegister()) {
3111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(addrmode == Offset);
312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    regoffset_ = offset.reg();
314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_= offset.shift();
315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_amount_ = offset.shift_amount();
316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    extend_ = NO_EXTEND;
318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset_ = 0;
319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // These assertions match those in the shifted-register constructor.
3211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(regoffset_.Is64Bits() && !regoffset_.IsSP());
3221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(shift_ == LSL);
323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
3241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(offset.IsExtendedRegister());
3251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(addrmode == Offset);
326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    regoffset_ = offset.reg();
328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    extend_ = offset.extend();
329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_amount_ = offset.shift_amount();
330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift_= NO_SHIFT;
332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset_ = 0;
333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // These assertions match those in the extended-register constructor.
3351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(!regoffset_.IsSP());
3361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((extend_ == UXTW) || (extend_ == SXTW) || (extend_ == SXTX));
3371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((regoffset_.Is64Bits() || (extend_ != SXTX)));
338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool MemOperand::IsImmediateOffset() const {
343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return (addrmode_ == Offset) && regoffset_.Is(NoReg);
344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool MemOperand::IsRegisterOffset() const {
348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return (addrmode_ == Offset) && !regoffset_.Is(NoReg);
349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool MemOperand::IsPreIndex() const {
353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return addrmode_ == PreIndex;
354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool MemOperand::IsPostIndex() const {
358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return addrmode_ == PostIndex;
359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Assembler
363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlAssembler::Assembler(byte* buffer, unsigned buffer_size)
364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    : buffer_size_(buffer_size), literal_pool_monitor_(0) {
365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  buffer_ = reinterpret_cast<Instruction*>(buffer);
367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  pc_ = buffer_;
368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Reset();
369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlAssembler::~Assembler() {
3731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(finalized_ || (pc_ == buffer_));
3741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(literals_.empty());
375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::Reset() {
379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
3801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((pc_ >= buffer_) && (pc_ < buffer_ + buffer_size_));
3811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(literal_pool_monitor_ == 0);
382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  memset(buffer_, 0, pc_ - buffer_);
383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  finalized_ = false;
384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  pc_ = buffer_;
386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  literals_.clear();
387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  next_literal_pool_check_ = pc_ + kLiteralPoolCheckInterval;
388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::FinalizeCode() {
392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  EmitLiteralPool();
393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#ifdef DEBUG
394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  finalized_ = true;
395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#endif
396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::bind(Label* label) {
400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  label->is_bound_ = true;
401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  label->target_ = pc_;
402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  while (label->IsLinked()) {
403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Get the address of the following instruction in the chain.
404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Instruction* next_link = label->link_->ImmPCOffsetTarget();
405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Update the instruction target.
406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    label->link_->SetImmPCOffsetTarget(label->target_);
407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Update the label's link.
408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // If the offset of the branch we just updated was 0 (kEndOfChain) we are
409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // done.
410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    label->link_ = (label->link_ != next_link) ? next_link : NULL;
411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Assembler::UpdateAndGetByteOffsetTo(Label* label) {
416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int offset;
4171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_STATIC_ASSERT(sizeof(*pc_) == 1);
418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (label->IsBound()) {
419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset = label->target() - pc_;
420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (label->IsLinked()) {
421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset = label->link() - pc_;
422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    offset = Label::kEndOfChain;
424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  label->set_link(pc_);
426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return offset;
427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Code generation.
431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::br(const Register& xn) {
4321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(xn.Is64Bits());
433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(BR | Rn(xn));
434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::blr(const Register& xn) {
4381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(xn.Is64Bits());
439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(BLR | Rn(xn));
440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ret(const Register& xn) {
4441123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(xn.Is64Bits());
445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(RET | Rn(xn));
446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
449578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Assembler::b(int imm26) {
450578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  Emit(B | ImmUncondBranch(imm26));
451578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
452578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
453578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
454578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Assembler::b(int imm19, Condition cond) {
455578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  Emit(B_cond | ImmCondBranch(imm19) | cond);
456578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
457578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
458578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
459578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Assembler::b(Label* label) {
460578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  b(UpdateAndGetInstructionOffsetTo(label));
461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::b(Label* label, Condition cond) {
465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  b(UpdateAndGetInstructionOffsetTo(label), cond);
466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::bl(int imm26) {
470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(BL | ImmUncondBranch(imm26));
471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::bl(Label* label) {
475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bl(UpdateAndGetInstructionOffsetTo(label));
476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cbz(const Register& rt,
480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    int imm19) {
481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rt) | CBZ | ImmCmpBranch(imm19) | Rt(rt));
482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cbz(const Register& rt,
486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    Label* label) {
487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  cbz(rt, UpdateAndGetInstructionOffsetTo(label));
488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cbnz(const Register& rt,
492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     int imm19) {
493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rt) | CBNZ | ImmCmpBranch(imm19) | Rt(rt));
494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cbnz(const Register& rt,
498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     Label* label) {
499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  cbnz(rt, UpdateAndGetInstructionOffsetTo(label));
500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::tbz(const Register& rt,
504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    unsigned bit_pos,
505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    int imm14) {
5061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSize)));
507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(TBZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt));
508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::tbz(const Register& rt,
512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    unsigned bit_pos,
513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    Label* label) {
514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  tbz(rt, bit_pos, UpdateAndGetInstructionOffsetTo(label));
515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::tbnz(const Register& rt,
519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned bit_pos,
520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     int imm14) {
5211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSize)));
522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(TBNZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt));
523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::tbnz(const Register& rt,
527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned bit_pos,
528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     Label* label) {
529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  tbnz(rt, bit_pos, UpdateAndGetInstructionOffsetTo(label));
530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::adr(const Register& rd, int imm21) {
5341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits());
535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(ADR | ImmPCRelAddress(imm21) | Rd(rd));
536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::adr(const Register& rd, Label* label) {
540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  adr(rd, UpdateAndGetByteOffsetTo(label));
541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::add(const Register& rd,
545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
546f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                    const Operand& operand) {
547f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSub(rd, rn, operand, LeaveFlags, ADD);
548f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
549f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
550f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
551f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::adds(const Register& rd,
552f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
553f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
554f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSub(rd, rn, operand, SetFlags, ADD);
555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cmn(const Register& rn,
559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rn);
561f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  adds(zr, rn, operand);
562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::sub(const Register& rd,
566ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
567f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                    const Operand& operand) {
568f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSub(rd, rn, operand, LeaveFlags, SUB);
569f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
570f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
571f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
572f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::subs(const Register& rd,
573f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
574f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
575f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSub(rd, rn, operand, SetFlags, SUB);
576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cmp(const Register& rn, const Operand& operand) {
580ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rn);
581f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  subs(zr, rn, operand);
582f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
583f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
584f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
585f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::neg(const Register& rd, const Operand& operand) {
586f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Register zr = AppropriateZeroRegFor(rd);
587f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  sub(rd, zr, operand);
588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
591f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::negs(const Register& rd, const Operand& operand) {
592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rd);
593f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  subs(rd, zr, operand);
594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::adc(const Register& rd,
598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
599f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                    const Operand& operand) {
600f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSubWithCarry(rd, rn, operand, LeaveFlags, ADC);
601f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
602f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
603f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
604f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::adcs(const Register& rd,
605f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
606f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
607f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSubWithCarry(rd, rn, operand, SetFlags, ADC);
608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::sbc(const Register& rd,
612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
613f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                    const Operand& operand) {
614f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSubWithCarry(rd, rn, operand, LeaveFlags, SBC);
615f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
616f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
617f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
618f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::sbcs(const Register& rd,
619f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
620f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
621f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  AddSubWithCarry(rd, rn, operand, SetFlags, SBC);
622f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
623f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
624f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
625f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::ngc(const Register& rd, const Operand& operand) {
626f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Register zr = AppropriateZeroRegFor(rd);
627f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  sbc(rd, zr, operand);
628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
631f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::ngcs(const Register& rd, const Operand& operand) {
632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rd);
633f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  sbcs(rd, zr, operand);
634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Logical instructions.
638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::and_(const Register& rd,
639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
640f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
641f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Logical(rd, rn, operand, AND);
642f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
643f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
644f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
645f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::ands(const Register& rd,
646f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
647f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
648f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Logical(rd, rn, operand, ANDS);
649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::tst(const Register& rn,
653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
654f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  ands(AppropriateZeroRegFor(rn), rn, operand);
655ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::bic(const Register& rd,
659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
660f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                    const Operand& operand) {
661f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Logical(rd, rn, operand, BIC);
662f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
663f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
664f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
665f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::bics(const Register& rd,
666f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Register& rn,
667f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                     const Operand& operand) {
668f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Logical(rd, rn, operand, BICS);
669ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::orr(const Register& rd,
673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Logical(rd, rn, operand, ORR);
676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::orn(const Register& rd,
680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Logical(rd, rn, operand, ORN);
683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::eor(const Register& rd,
687ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
688ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
689ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Logical(rd, rn, operand, EOR);
690ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
692ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
693ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::eon(const Register& rd,
694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
695ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Operand& operand) {
696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Logical(rd, rn, operand, EON);
697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
700ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::lslv(const Register& rd,
701ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
702ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
7031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
7041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | LSLV | Rm(rm) | Rn(rn) | Rd(rd));
706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::lsrv(const Register& rd,
710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
7121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
7131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | LSRV | Rm(rm) | Rn(rn) | Rd(rd));
715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::asrv(const Register& rd,
719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
7211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
7221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | ASRV | Rm(rm) | Rn(rn) | Rd(rd));
724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::rorv(const Register& rd,
728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
7301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
7311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | RORV | Rm(rm) | Rn(rn) | Rd(rd));
733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
734ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Bitfield operations.
737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::bfm(const Register& rd,
738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned immr,
740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned imms) {
7411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | BFM | N |
744f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::sbfm(const Register& rd,
749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
750ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned immr,
751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned imms) {
7521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits() || rn.Is32Bits());
753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | SBFM | N |
755f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ubfm(const Register& rd,
760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned immr,
762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned imms) {
7631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
765ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | UBFM | N |
766f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl       ImmR(immr, rd.size()) | ImmS(imms, rn.size()) | Rn(rn) | Rd(rd));
767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::extr(const Register& rd,
771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm,
773ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     unsigned lsb) {
7741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
7751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset);
777f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Emit(SF(rd) | EXTR | N | Rm(rm) | ImmS(lsb, rn.size()) | Rn(rn) | Rd(rd));
778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::csel(const Register& rd,
782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm,
784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     Condition cond) {
785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalSelect(rd, rn, rm, cond, CSEL);
786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::csinc(const Register& rd,
790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rm,
792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Condition cond) {
793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalSelect(rd, rn, rm, cond, CSINC);
794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::csinv(const Register& rd,
798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rm,
800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Condition cond) {
801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalSelect(rd, rn, rm, cond, CSINV);
802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::csneg(const Register& rd,
806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rm,
808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Condition cond) {
809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalSelect(rd, rn, rm, cond, CSNEG);
810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
813ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cset(const Register &rd, Condition cond) {
8141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((cond != al) && (cond != nv));
815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rd);
816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  csinc(rd, zr, zr, InvertCondition(cond));
817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::csetm(const Register &rd, Condition cond) {
8211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((cond != al) && (cond != nv));
822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register zr = AppropriateZeroRegFor(rd);
823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  csinv(rd, zr, zr, InvertCondition(cond));
824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cinc(const Register &rd, const Register &rn, Condition cond) {
8281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((cond != al) && (cond != nv));
829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  csinc(rd, rn, rn, InvertCondition(cond));
830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cinv(const Register &rd, const Register &rn, Condition cond) {
8341123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((cond != al) && (cond != nv));
835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  csinv(rd, rn, rn, InvertCondition(cond));
836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cneg(const Register &rd, const Register &rn, Condition cond) {
8401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((cond != al) && (cond != nv));
841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  csneg(rd, rn, rn, InvertCondition(cond));
842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ConditionalSelect(const Register& rd,
846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                  const Register& rn,
847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                  const Register& rm,
848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                  Condition cond,
849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                  ConditionalSelectOp op) {
8501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
8511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | op | Rm(rm) | Cond(cond) | Rn(rn) | Rd(rd));
853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ccmn(const Register& rn,
857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Operand& operand,
858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     StatusFlags nzcv,
859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     Condition cond) {
860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalCompare(rn, operand, nzcv, cond, CCMN);
861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ccmp(const Register& rn,
865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Operand& operand,
866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     StatusFlags nzcv,
867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     Condition cond) {
868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ConditionalCompare(rn, operand, nzcv, cond, CCMP);
869ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
870ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::DataProcessing3Source(const Register& rd,
873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm,
875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& ra,
876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     DataProcessing3SourceOp op) {
877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | op | Rm(rm) | Ra(ra) | Rn(rn) | Rd(rd));
878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::mul(const Register& rd,
882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn,
883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rm) {
8841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rd, rn, rm));
885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, AppropriateZeroRegFor(rd), MADD);
886ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
888ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::madd(const Register& rd,
890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm,
892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& ra) {
893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, MADD);
894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::mneg(const Register& rd,
898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
9001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rd, rn, rm));
901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, AppropriateZeroRegFor(rd), MSUB);
902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
905ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::msub(const Register& rd,
906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm,
908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& ra) {
909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, MSUB);
910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::umaddl(const Register& rd,
914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rn,
915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rm,
916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& ra) {
9171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
9181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, UMADDL_x);
920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
923ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::smaddl(const Register& rd,
924ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rn,
925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rm,
926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& ra) {
9271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
9281123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, SMADDL_x);
930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::umsubl(const Register& rd,
934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rn,
935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rm,
936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& ra) {
9371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
9381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, UMSUBL_x);
940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::smsubl(const Register& rd,
944ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rn,
945ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rm,
946ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& ra) {
9471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits() && ra.Is64Bits());
9481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, ra, SMSUBL_x);
950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::smull(const Register& rd,
954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rm) {
9561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits());
9571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is32Bits() && rm.Is32Bits());
958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(rd, rn, rm, xzr, SMADDL_x);
959ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
960ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::sdiv(const Register& rd,
963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
9651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
9661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | SDIV | Rm(rm) | Rn(rn) | Rd(rd));
968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::smulh(const Register& xd,
972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& xn,
973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& xm) {
9741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(xd.Is64Bits() && xn.Is64Bits() && xm.Is64Bits());
975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing3Source(xd, xn, xm, xzr, SMULH_x);
976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
978ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::udiv(const Register& rd,
979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn,
980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rm) {
9811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
9821123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rm.size());
983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | UDIV | Rm(rm) | Rn(rn) | Rd(rd));
984ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::rbit(const Register& rd,
988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const Register& rn) {
989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, RBIT);
990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
991ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::rev16(const Register& rd,
994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn) {
995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, REV16);
996ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::rev32(const Register& rd,
1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn) {
10011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.Is64Bits());
1002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, REV);
1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::rev(const Register& rd,
1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn) {
1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, rd.Is64Bits() ? REV_x : REV_w);
1009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::clz(const Register& rd,
1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn) {
1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, CLZ);
1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::cls(const Register& rd,
1019ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const Register& rn) {
1020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  DataProcessing1Source(rd, rn, CLS);
1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldp(const CPURegister& rt,
1025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const CPURegister& rt2,
1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const MemOperand& src) {
1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStorePair(rt, rt2, src, LoadPairOpFor(rt, rt2));
1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1031ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::stp(const CPURegister& rt,
1032ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const CPURegister& rt2,
1033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                    const MemOperand& dst) {
1034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2));
1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1036ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldpsw(const Register& rt,
1039ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rt2,
1040ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const MemOperand& src) {
10411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits());
1042ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStorePair(rt, rt2, src, LDPSW_x);
1043ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::LoadStorePair(const CPURegister& rt,
1047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                              const CPURegister& rt2,
1048ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                              const MemOperand& addr,
1049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                              LoadStorePairOp op) {
1050ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 'rt' and 'rt2' can only be aliased for stores.
10511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2));
10521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
1053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1054ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) |
1055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                ImmLSPair(addr.offset(), CalcLSPairDataSize(op));
1056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr addrmodeop;
1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (addr.IsImmediateOffset()) {
1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    addrmodeop = LoadStorePairOffsetFixed;
1060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
10611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(addr.offset() != 0);
1062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (addr.IsPreIndex()) {
1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      addrmodeop = LoadStorePairPreIndexFixed;
1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
10651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(addr.IsPostIndex());
1066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      addrmodeop = LoadStorePairPostIndexFixed;
1067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1068ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1069ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(addrmodeop | memop);
1070ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1072ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldnp(const CPURegister& rt,
1074ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const CPURegister& rt2,
1075ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const MemOperand& src) {
1076ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStorePairNonTemporal(rt, rt2, src,
1077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                           LoadPairNonTemporalOpFor(rt, rt2));
1078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1080ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1081ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::stnp(const CPURegister& rt,
1082ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const CPURegister& rt2,
1083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const MemOperand& dst) {
1084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStorePairNonTemporal(rt, rt2, dst,
1085ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                           StorePairNonTemporalOpFor(rt, rt2));
1086ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1087ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1088ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1089ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::LoadStorePairNonTemporal(const CPURegister& rt,
1090ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         const CPURegister& rt2,
1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         const MemOperand& addr,
1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         LoadStorePairNonTemporalOp op) {
10931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(!rt.Is(rt2));
10941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
10951123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(addr.IsImmediateOffset());
1096ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LSDataSize size = CalcLSPairDataSize(
1098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    static_cast<LoadStorePairOp>(op & LoadStorePairMask));
1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) |
1100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       ImmLSPair(addr.offset(), size));
1101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Memory instructions.
1105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldrb(const Register& rt, const MemOperand& src) {
1106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, LDRB_w);
1107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::strb(const Register& rt, const MemOperand& dst) {
1111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, dst, STRB_w);
1112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldrsb(const Register& rt, const MemOperand& src) {
1116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w);
1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldrh(const Register& rt, const MemOperand& src) {
1121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, LDRH_w);
1122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::strh(const Register& rt, const MemOperand& dst) {
1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, dst, STRH_w);
1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldrsh(const Register& rt, const MemOperand& src) {
1131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w);
1132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldr(const CPURegister& rt, const MemOperand& src) {
1136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, LoadOpFor(rt));
1137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::str(const CPURegister& rt, const MemOperand& src) {
1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, StoreOpFor(rt));
1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldrsw(const Register& rt, const MemOperand& src) {
11461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits());
1147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadStore(rt, src, LDRSW_x);
1148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldr(const Register& rt, uint64_t imm) {
1152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  LoadLiteral(rt, imm, rt.Is64Bits() ? LDR_x_lit : LDR_w_lit);
1153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ldr(const FPRegister& ft, double imm) {
11571123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(ft.Is64Bits());
11581123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  LoadLiteral(ft, double_to_rawbits(imm), LDR_d_lit);
11591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl}
1160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
11621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixlvoid Assembler::ldr(const FPRegister& ft, float imm) {
11631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(ft.Is32Bits());
11641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  LoadLiteral(ft, float_to_rawbits(imm), LDR_s_lit);
1165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::mov(const Register& rd, const Register& rm) {
1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Moves involving the stack pointer are encoded as add immediate with
1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // second operand of zero. Otherwise, orr with first operand zr is
1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // used.
1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rd.IsSP() || rm.IsSP()) {
1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    add(rd, rm, 0);
1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    orr(rd, AppropriateZeroRegFor(rd), rm);
1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::mvn(const Register& rd, const Operand& operand) {
1181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  orn(rd, AppropriateZeroRegFor(rd), operand);
1182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::mrs(const Register& rt, SystemRegister sysreg) {
11861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits());
1187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(MRS | ImmSystemRegister(sysreg) | Rt(rt));
1188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::msr(SystemRegister sysreg, const Register& rt) {
11921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.Is64Bits());
1193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(MSR | Rt(rt) | ImmSystemRegister(sysreg));
1194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::hint(SystemHint code) {
1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(HINT | ImmHint(code) | Rt(xzr));
1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1202f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::dmb(BarrierDomain domain, BarrierType type) {
1203f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Emit(DMB | ImmBarrierDomain(domain) | ImmBarrierType(type));
1204f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1205f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
12061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1207f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::dsb(BarrierDomain domain, BarrierType type) {
1208f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Emit(DSB | ImmBarrierDomain(domain) | ImmBarrierType(type));
1209f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1210f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
12111123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1212f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::isb() {
1213f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  Emit(ISB | ImmBarrierDomain(FullSystem) | ImmBarrierType(BarrierAll));
1214f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
12161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1217ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::fmov(const FPRegister& fd, double imm) {
12181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.Is64Bits());
12191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsImmFP64(imm));
12201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  Emit(FMOV_d_imm | Rd(fd) | ImmFP64(imm));
12211123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl}
12221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
12231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl
1224ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::fmov(const FPRegister& fd, float imm) {
12251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.Is32Bits());
12261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsImmFP32(imm));
12271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  Emit(FMOV_s_imm | Rd(fd) | ImmFP32(imm));
1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1231ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::fmov(const Register& rd, const FPRegister& fn) {
12321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == fn.size());
1233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPIntegerConvertOp op = rd.Is32Bits() ? FMOV_ws : FMOV_xd;
1234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(op | Rd(rd) | Rn(fn));
1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1238ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::fmov(const FPRegister& fd, const Register& rn) {
12391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == rn.size());
1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPIntegerConvertOp op = fd.Is32Bits() ? FMOV_sw : FMOV_dx;
1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(op | Rd(fd) | Rn(rn));
1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1245ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::fmov(const FPRegister& fd, const FPRegister& fn) {
12461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == fn.size());
1247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fd) | FMOV | Rd(fd) | Rn(fn));
1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fadd(const FPRegister& fd,
1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FADD);
1255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fsub(const FPRegister& fd,
1259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FSUB);
1262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fmul(const FPRegister& fd,
1266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FMUL);
1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1272f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fmadd(const FPRegister& fd,
1273f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                      const FPRegister& fn,
1274f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                      const FPRegister& fm,
1275f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                      const FPRegister& fa) {
1276f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMADD_s : FMADD_d);
1277f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1278f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1279f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fmsub(const FPRegister& fd,
1281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fn,
1282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fm,
1283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fa) {
1284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMSUB_s : FMSUB_d);
1285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1288f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fnmadd(const FPRegister& fd,
1289f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fn,
1290f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fm,
1291f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fa) {
1292f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMADD_s : FNMADD_d);
1293f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1294f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1295f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1296f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fnmsub(const FPRegister& fd,
1297f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fn,
1298f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fm,
1299f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fa) {
1300f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMSUB_s : FNMSUB_d);
1301f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1302f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1303f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fdiv(const FPRegister& fd,
1305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FDIV);
1308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fmax(const FPRegister& fd,
1312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FMAX);
1315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1318f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fmaxnm(const FPRegister& fd,
1319f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fn,
1320f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fm) {
1321f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing2Source(fd, fn, fm, FMAXNM);
1322f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1323f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1324f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fmin(const FPRegister& fd,
1326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn,
1327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
1328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing2Source(fd, fn, fm, FMIN);
1329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1332f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fminnm(const FPRegister& fd,
1333f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fn,
1334f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fm) {
1335f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing2Source(fd, fn, fm, FMINNM);
1336f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1337f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1338f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fabs(const FPRegister& fd,
1340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn) {
13411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing1Source(fd, fn, FABS);
1343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fneg(const FPRegister& fd,
1347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fn) {
13481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing1Source(fd, fn, FNEG);
1350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fsqrt(const FPRegister& fd,
1354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fn) {
13551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing1Source(fd, fn, FSQRT);
1357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1360f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::frinta(const FPRegister& fd,
1361f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl                       const FPRegister& fn) {
13621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1363f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPDataProcessing1Source(fd, fn, FRINTA);
1364f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1365f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1366f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1367ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid Assembler::frintm(const FPRegister& fd,
1368ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                       const FPRegister& fn) {
1369ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1370ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  FPDataProcessing1Source(fd, fn, FRINTM);
1371ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}
1372ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
1373ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
1374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::frintn(const FPRegister& fd,
1375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const FPRegister& fn) {
13761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing1Source(fd, fn, FRINTN);
1378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::frintz(const FPRegister& fd,
1382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const FPRegister& fn) {
13831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.SizeInBits() == fn.SizeInBits());
1384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPDataProcessing1Source(fd, fn, FRINTZ);
1385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fcmp(const FPRegister& fn,
1389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     const FPRegister& fm) {
13901123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fn.size() == fm.size());
1391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fn) | FCMP | Rm(fm) | Rn(fn));
1392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fcmp(const FPRegister& fn,
1396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                     double value) {
1397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(value);
1398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Although the fcmp instruction can strictly only take an immediate value of
1399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // +0.0, we don't need to check for -0.0 because the sign of 0.0 doesn't
1400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // affect the result of the comparison.
14011123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(value == 0.0);
1402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fn) | FCMP_zero | Rn(fn));
1403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fccmp(const FPRegister& fn,
1407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fm,
1408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      StatusFlags nzcv,
1409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Condition cond) {
14101123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fn.size() == fm.size());
1411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fn) | FCCMP | Rm(fm) | Cond(cond) | Rn(fn) | Nzcv(nzcv));
1412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fcsel(const FPRegister& fd,
1416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fn,
1417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const FPRegister& fm,
1418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      Condition cond) {
14191123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == fn.size());
14201123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == fm.size());
1421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fd) | FCSEL | Rm(fm) | Cond(cond) | Rn(fn) | Rd(fd));
1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::FPConvertToInt(const Register& rd,
1426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               const FPRegister& fn,
1427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               FPIntegerConvertOp op) {
1428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | FPType(fn) | op | Rn(fn) | Rd(rd));
1429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1432578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Assembler::fcvt(const FPRegister& fd,
1433578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                     const FPRegister& fn) {
1434578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (fd.Is64Bits()) {
1435578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    // Convert float to double.
14361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(fn.Is32Bits());
1437578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    FPDataProcessing1Source(fd, fn, FCVT_ds);
1438578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  } else {
1439578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    // Convert double to float.
14401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(fn.Is64Bits());
1441578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    FPDataProcessing1Source(fd, fn, FCVT_sd);
1442578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
1443578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
1444578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
1445578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
1446f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtau(const Register& rd, const FPRegister& fn) {
1447f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPConvertToInt(rd, fn, FCVTAU);
1448f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1449f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1450f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1451f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtas(const Register& rd, const FPRegister& fn) {
1452f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl  FPConvertToInt(rd, fn, FCVTAS);
1453f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl}
1454f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1455f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl
1456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fcvtmu(const Register& rd, const FPRegister& fn) {
1457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTMU);
1458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::fcvtms(const Register& rd, const FPRegister& fn) {
1462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTMS);
1463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1466f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtnu(const Register& rd, const FPRegister& fn) {
1467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTNU);
1468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1471f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtns(const Register& rd, const FPRegister& fn) {
1472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTNS);
1473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1476f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtzu(const Register& rd, const FPRegister& fn) {
1477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTZU);
1478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1481f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Assembler::fcvtzs(const Register& rd, const FPRegister& fn) {
1482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  FPConvertToInt(rd, fn, FCVTZS);
1483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::scvtf(const FPRegister& fd,
1487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
1488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      unsigned fbits) {
1489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (fbits == 0) {
1490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(SF(rn) | FPType(fd) | SCVTF | Rn(rn) | Rd(fd));
1491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(SF(rn) | FPType(fd) | SCVTF_fixed | FPScale(64 - fbits) | Rn(rn) |
1493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         Rd(fd));
1494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ucvtf(const FPRegister& fd,
1499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      const Register& rn,
1500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      unsigned fbits) {
1501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (fbits == 0) {
1502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(SF(rn) | FPType(fd) | UCVTF | Rn(rn) | Rd(fd));
1503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(SF(rn) | FPType(fd) | UCVTF_fixed | FPScale(64 - fbits) | Rn(rn) |
1505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         Rd(fd));
1506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Note:
1511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Below, a difference in case for the same letter indicates a
1512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// negated bit.
1513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// If b is 1, then B is 0.
1514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlInstr Assembler::ImmFP32(float imm) {
15151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsImmFP32(imm));
1516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits: aBbb.bbbc.defg.h000.0000.0000.0000.0000
1517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bits = float_to_rawbits(imm);
1518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit7: a000.0000
1519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit7 = ((bits >> 31) & 0x1) << 7;
1520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit6: 0b00.0000
1521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit6 = ((bits >> 29) & 0x1) << 6;
1522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit5_to_0: 00cd.efgh
1523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit5_to_0 = (bits >> 19) & 0x3f;
1524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return (bit7 | bit6 | bit5_to_0) << ImmFP_offset;
1526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlInstr Assembler::ImmFP64(double imm) {
15301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(IsImmFP64(imm));
1531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
1532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //       0000.0000.0000.0000.0000.0000.0000.0000
1533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t bits = double_to_rawbits(imm);
1534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit7: a000.0000
1535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit7 = ((bits >> 63) & 0x1) << 7;
1536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit6: 0b00.0000
1537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit6 = ((bits >> 61) & 0x1) << 6;
1538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit5_to_0: 00cd.efgh
1539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bit5_to_0 = (bits >> 48) & 0x3f;
1540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return (bit7 | bit6 | bit5_to_0) << ImmFP_offset;
1542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Code generation helpers.
1546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::MoveWide(const Register& rd,
1547ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                         uint64_t imm,
1548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                         int shift,
1549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                         MoveWideImmediateOp mov_op) {
1550ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (shift >= 0) {
1551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Explicit shift specified.
15521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((shift == 0) || (shift == 16) ||
15531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl                (shift == 32) || (shift == 48));
15541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rd.Is64Bits() || (shift == 0) || (shift == 16));
1555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift /= 16;
1556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Calculate a new immediate and shift combination to encode the immediate
1558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // argument.
1559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    shift = 0;
1560e6feb7aa71ed0d2318558000aaeb46220890ad9aIan Rogers    if ((imm & UINT64_C(0xffffffffffff0000)) == 0) {
1561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // Nothing to do.
1562e6feb7aa71ed0d2318558000aaeb46220890ad9aIan Rogers    } else if ((imm & UINT64_C(0xffffffff0000ffff)) == 0) {
1563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      imm >>= 16;
1564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift = 1;
1565e6feb7aa71ed0d2318558000aaeb46220890ad9aIan Rogers    } else if ((imm & UINT64_C(0xffff0000ffffffff)) == 0) {
15661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(rd.Is64Bits());
1567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      imm >>= 32;
1568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift = 2;
1569e6feb7aa71ed0d2318558000aaeb46220890ad9aIan Rogers    } else if ((imm & UINT64_C(0x0000ffffffffffff)) == 0) {
15701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(rd.Is64Bits());
1571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      imm >>= 48;
1572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      shift = 3;
1573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
15761123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(is_uint16(imm));
1577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | MoveWideImmediateFixed | mov_op |
1579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       Rd(rd) | ImmMoveWide(imm) | ShiftMoveWide(shift));
1580ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::AddSub(const Register& rd,
1584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Register& rn,
1585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       const Operand& operand,
1586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       FlagsUpdate S,
1587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                       AddSubOp op) {
15881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
1589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (operand.IsImmediate()) {
1590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    int64_t immediate = operand.immediate();
15911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsImmAddSub(immediate));
1592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
1593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) |
1594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         ImmAddSub(immediate) | dest_reg | RnSP(rn));
1595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (operand.IsShiftedRegister()) {
15961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.reg().size() == rd.size());
15971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.shift() != ROR);
1598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // For instructions of the form:
1600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //   add/sub   wsp, <Wn>, <Wm> [, LSL #0-3 ]
1601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //   add/sub   <Wd>, wsp, <Wm> [, LSL #0-3 ]
1602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //   add/sub   wsp, wsp, <Wm> [, LSL #0-3 ]
1603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //   adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ]
1604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // or their 64-bit register equivalents, convert the operand from shifted to
1605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // extended register mode, and emit an add/sub extended instruction.
1606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (rn.IsSP() || rd.IsSP()) {
16071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(!(rd.IsSP() && (S == SetFlags)));
1608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      DataProcExtendedRegister(rd, rn, operand.ToExtendedRegister(), S,
1609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                               AddSubExtendedFixed | op);
1610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      DataProcShiftedRegister(rd, rn, operand, S, AddSubShiftedFixed | op);
1612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
16141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.IsExtendedRegister());
1615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    DataProcExtendedRegister(rd, rn, operand, S, AddSubExtendedFixed | op);
1616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::AddSubWithCarry(const Register& rd,
1621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                const Register& rn,
1622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                const Operand& operand,
1623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                FlagsUpdate S,
1624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                AddSubWithCarryOp op) {
16251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
16261123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == operand.reg().size());
16271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
1628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | Rn(rn) | Rd(rd));
1629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::hlt(int code) {
16331123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(is_uint16(code));
1634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(HLT | ImmException(code));
1635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::brk(int code) {
16391123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(is_uint16(code));
1640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(BRK | ImmException(code));
1641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::Logical(const Register& rd,
1645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const Register& rn,
1646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const Operand& operand,
1647ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        LogicalOp op) {
16481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
1649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (operand.IsImmediate()) {
1650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    int64_t immediate = operand.immediate();
1651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    unsigned reg_size = rd.size();
1652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
16531123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(immediate != 0);
16541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(immediate != -1);
16551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rd.Is64Bits() || is_uint32(immediate));
1656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // If the operation is NOT, invert the operation and immediate.
1658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if ((op & NOT) == NOT) {
1659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      op = static_cast<LogicalOp>(op & ~NOT);
1660ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask);
1661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1663ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    unsigned n, imm_s, imm_r;
1664ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (IsImmLogical(immediate, reg_size, &n, &imm_s, &imm_r)) {
1665ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // Immediate can be encoded in the instruction.
1666ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      LogicalImmediate(rd, rn, n, imm_s, imm_r, op);
1667ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1668ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // This case is handled in the macro assembler.
16691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_UNREACHABLE();
1670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
16721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.IsShiftedRegister());
16731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.reg().size() == rd.size());
1674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed);
1675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op);
1676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::LogicalImmediate(const Register& rd,
1681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 const Register& rn,
1682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 unsigned n,
1683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 unsigned imm_s,
1684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 unsigned imm_r,
1685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 LogicalOp op) {
1686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned reg_size = rd.size();
1687ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr dest_reg = (op == ANDS) ? Rd(rd) : RdSP(rd);
1688ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | LogicalImmediateFixed | op | BitN(n, reg_size) |
1689ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       ImmSetBits(imm_s, reg_size) | ImmRotate(imm_r, reg_size) | dest_reg |
1690ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       Rn(rn));
1691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1692ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1693ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::ConditionalCompare(const Register& rn,
1695ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   const Operand& operand,
1696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   StatusFlags nzcv,
1697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   Condition cond,
1698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   ConditionalCompareOp op) {
1699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr ccmpop;
1700ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (operand.IsImmediate()) {
1701ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    int64_t immediate = operand.immediate();
17021123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(IsImmConditionalCompare(immediate));
1703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate);
1704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
17051123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
1706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg());
1707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv));
1709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::DataProcessing1Source(const Register& rd,
1713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                      const Register& rn,
1714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                      DataProcessing1SourceOp op) {
17151123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() == rn.size());
1716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rn) | op | Rn(rn) | Rd(rd));
1717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::FPDataProcessing1Source(const FPRegister& fd,
1721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fn,
1722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        FPDataProcessing1SourceOp op) {
1723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fn) | op | Rn(fn) | Rd(fd));
1724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::FPDataProcessing2Source(const FPRegister& fd,
1728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fn,
1729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fm,
1730ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        FPDataProcessing2SourceOp op) {
17311123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == fn.size());
17321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(fd.size() == fm.size());
1733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd));
1734ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::FPDataProcessing3Source(const FPRegister& fd,
1738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fn,
1739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fm,
1740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const FPRegister& fa,
1741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        FPDataProcessing3SourceOp op) {
17421123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(fd, fn, fm, fa));
1743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd) | Ra(fa));
1744ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::EmitShift(const Register& rd,
1748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                          const Register& rn,
1749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                          Shift shift,
1750ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                          unsigned shift_amount) {
1751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  switch (shift) {
1752ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case LSL:
1753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      lsl(rd, rn, shift_amount);
1754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1755ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case LSR:
1756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      lsr(rd, rn, shift_amount);
1757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case ASR:
1759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      asr(rd, rn, shift_amount);
1760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    case ROR:
1762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      ror(rd, rn, shift_amount);
1763ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      break;
1764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    default:
17651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_UNREACHABLE();
1766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::EmitExtendShift(const Register& rd,
1771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                const Register& rn,
1772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                Extend extend,
1773ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                unsigned left_shift) {
17741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rd.size() >= rn.size());
1775ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned reg_size = rd.size();
1776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Use the correct size of register.
1777ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Register rn_ = Register(rn.code(), rd.size());
1778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Bits extracted are high_bit:0.
1779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned high_bit = (8 << (extend & 0x3)) - 1;
1780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Number of bits left in the result that are not introduced by the shift.
1781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1);
1782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) {
1784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    switch (extend) {
1785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case UXTB:
1786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case UXTH:
1787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break;
1788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case SXTB:
1789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case SXTH:
1790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case SXTW: sbfm(rd, rn_, non_shift_bits, high_bit); break;
1791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case UXTX:
1792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      case SXTX: {
17931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        VIXL_ASSERT(rn.size() == kXRegSize);
1794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        // Nothing to extend. Just shift.
1795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        lsl(rd, rn_, left_shift);
1796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        break;
1797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
17981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      default: VIXL_UNREACHABLE();
1799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // No need to extend as the extended bits would be shifted away.
1802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lsl(rd, rn_, left_shift);
1803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::DataProcShiftedRegister(const Register& rd,
1808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const Register& rn,
1809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        const Operand& operand,
1810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        FlagsUpdate S,
1811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                        Instr op) {
18121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(operand.IsShiftedRegister());
18131123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rn.Is64Bits() || (rn.Is32Bits() &&
18141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl              is_uint5(operand.shift_amount())));
1815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | op | Flags(S) |
1816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) |
1817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       Rm(operand.reg()) | Rn(rn) | Rd(rd));
1818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1821ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::DataProcExtendedRegister(const Register& rd,
1822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         const Register& rn,
1823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         const Operand& operand,
1824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         FlagsUpdate S,
1825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         Instr op) {
1826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
1827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) |
1828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       ExtendMode(operand.extend()) | ImmExtendShift(operand.shift_amount()) |
1829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       dest_reg | RnSP(rn));
1830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmAddSub(int64_t immediate) {
1834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return is_uint12(immediate) ||
1835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0));
1836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::LoadStore(const CPURegister& rt,
1839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                          const MemOperand& addr,
1840ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                          LoadStoreOp op) {
1841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr memop = op | Rt(rt) | RnSP(addr.base());
1842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ptrdiff_t offset = addr.offset();
1843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (addr.IsImmediateOffset()) {
1845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    LSDataSize size = CalcLSDataSize(op);
1846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (IsImmLSScaled(offset, size)) {
1847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // Use the scaled addressing mode.
1848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Emit(LoadStoreUnsignedOffsetFixed | memop |
1849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           ImmLSUnsigned(offset >> size));
1850ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else if (IsImmLSUnscaled(offset)) {
1851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // Use the unscaled addressing mode.
1852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      Emit(LoadStoreUnscaledOffsetFixed | memop | ImmLS(offset));
1853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // This case is handled in the macro assembler.
18551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_UNREACHABLE();
1856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else if (addr.IsRegisterOffset()) {
1858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Extend ext = addr.extend();
1859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Shift shift = addr.shift();
1860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    unsigned shift_amount = addr.shift_amount();
1861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // LSL is encoded in the option field as UXTX.
1863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (shift == LSL) {
1864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      ext = UXTX;
1865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Shifts are encoded in one bit, indicating a left shift by the memory
1868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // access size.
18691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((shift_amount == 0) ||
1870ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl           (shift_amount == static_cast<unsigned>(CalcLSDataSize(op))));
1871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Emit(LoadStoreRegisterOffsetFixed | memop | Rm(addr.regoffset()) |
1872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0));
1873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
1874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (IsImmLSUnscaled(offset)) {
1875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (addr.IsPreIndex()) {
1876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        Emit(LoadStorePreIndexFixed | memop | ImmLS(offset));
1877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
18781123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl        VIXL_ASSERT(addr.IsPostIndex());
1879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        Emit(LoadStorePostIndexFixed | memop | ImmLS(offset));
1880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
1881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      // This case is handled in the macro assembler.
18831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_UNREACHABLE();
1884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1886ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1888ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmLSUnscaled(ptrdiff_t offset) {
1890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return is_int9(offset);
1891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmLSScaled(ptrdiff_t offset, LSDataSize size) {
1895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool offset_is_size_multiple = (((offset >> size) << size) == offset);
1896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return offset_is_size_multiple && is_uint12(offset >> size);
1897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::LoadLiteral(const CPURegister& rt,
1901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            uint64_t imm,
1902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                            LoadLiteralOp op) {
19031123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(is_int32(imm) || is_uint32(imm) || (rt.Is64Bits()));
1904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1905ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  BlockLiteralPoolScope scope(this);
1906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  RecordLiteral(imm, rt.SizeInBytes());
1907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Emit(op | ImmLLiteral(0) | Rt(rt));
1908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
1909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Test if a given value can be encoded in the immediate field of a logical
1912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// instruction.
1913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// If it can be encoded, the function returns true, and values pointed to by n,
1914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// imm_s and imm_r are updated with immediates encoded in the format required
1915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// by the corresponding fields in the logical instruction.
1916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// If it can not be encoded, the function returns false, and the values pointed
1917ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// to by n, imm_s and imm_r are undefined.
1918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmLogical(uint64_t value,
1919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             unsigned width,
1920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             unsigned* n,
1921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             unsigned* imm_s,
1922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                             unsigned* imm_r) {
19231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((n != NULL) && (imm_s != NULL) && (imm_r != NULL));
19241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((width == kWRegSize) || (width == kXRegSize));
1925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Logical immediates are encoded using parameters n, imm_s and imm_r using
1927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // the following table:
1928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  N   imms    immr    size        S             R
1930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  1  ssssss  rrrrrr    64    UInt(ssssss)  UInt(rrrrrr)
1931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  0  0sssss  xrrrrr    32    UInt(sssss)   UInt(rrrrr)
1932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  0  10ssss  xxrrrr    16    UInt(ssss)    UInt(rrrr)
1933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  0  110sss  xxxrrr     8    UInt(sss)     UInt(rrr)
1934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  0  1110ss  xxxxrr     4    UInt(ss)      UInt(rr)
1935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //  0  11110s  xxxxxr     2    UInt(s)       UInt(r)
1936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // (s bits must not be all set)
1937ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // A pattern is constructed of size bits, where the least significant S+1
1939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits are set. The pattern is rotated right by R, and repeated across a
1940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 32 or 64-bit value, depending on destination register width.
1941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // To test if an arbitrary immediate can be encoded using this scheme, an
1943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // iterative algorithm is used.
1944ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  //
1945ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // TODO: This code does not consider using X/W register overlap to support
1946ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 64-bit immediates where the top 32-bits are zero, and the bottom 32-bits
1947ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // are an encodable logical immediate.
1948ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 1. If the value has all set or all clear bits, it can't be encoded.
19501123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  if ((value == 0) || (value == kXRegMask) ||
19511123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      ((width == kWRegSize) && (value == kWRegMask))) {
1952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
1953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
1954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned lead_zero = CountLeadingZeros(value, width);
1956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned lead_one = CountLeadingZeros(~value, width);
1957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned trail_zero = CountTrailingZeros(value, width);
1958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned trail_one = CountTrailingZeros(~value, width);
1959ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  unsigned set_bits = CountSetBits(value, width);
1960ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The fixed bits in the immediate s field.
1962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If width == 64 (X reg), start at 0xFFFFFF80.
1963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // If width == 32 (W reg), start at 0xFFFFFFC0, as the iteration for 64-bit
1964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // widths won't be executed.
1965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int imm_s_fixed = (width == kXRegSize) ? -128 : -64;
1966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int imm_s_mask = 0x3F;
1967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (;;) {
1969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // 2. If the value is two bits wide, it can be encoded.
1970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (width == 2) {
1971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      *n = 0;
1972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      *imm_s = 0x3C;
1973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      *imm_r = (value & 3) - 1;
1974ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return true;
1975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    *n = (width == 64) ? 1 : 0;
1978ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    *imm_s = ((imm_s_fixed | (set_bits - 1)) & imm_s_mask);
1979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if ((lead_zero + set_bits) == width) {
1980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      *imm_r = 0;
1981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
1982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      *imm_r = (lead_zero > 0) ? (width - trail_zero) : lead_one;
1983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1984ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // 3. If the sum of leading zeros, trailing zeros and set bits is equal to
1986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //    the bit width of the value, it can be encoded.
1987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (lead_zero + trail_zero + set_bits == width) {
1988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return true;
1989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1991ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // 4. If the sum of leading ones, trailing ones and unset bits in the
1992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //    value is equal to the bit width of the value, it can be encoded.
1993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (lead_one + trail_one + (width - set_bits) == width) {
1994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return true;
1995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
1996ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // 5. If the most-significant half of the bitwise value is equal to the
1998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //    least-significant half, return to step 2 using the least-significant
1999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    //    half of the value.
20001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    uint64_t mask = (UINT64_C(1) << (width >> 1)) - 1;
2001ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if ((value & mask) == ((value >> (width >> 1)) & mask)) {
2002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      width >>= 1;
2003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      set_bits >>= 1;
2004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      imm_s_fixed >>= 1;
2005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      continue;
2006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
2007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // 6. Otherwise, the value can't be encoded.
2009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmConditionalCompare(int64_t immediate) {
2014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return is_uint5(immediate);
2015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmFP32(float imm) {
2019ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Valid values will have the form:
2020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // aBbb.bbbc.defg.h000.0000.0000.0000.0000
2021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t bits = float_to_rawbits(imm);
2022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits[19..0] are cleared.
2023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((bits & 0x7ffff) != 0) {
2024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits[29..25] are all set or all cleared.
2028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t b_pattern = (bits >> 16) & 0x3e00;
2029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (b_pattern != 0 && b_pattern != 0x3e00) {
2030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2031ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2032ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit[30] and bit[29] are opposite.
2034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (((bits ^ (bits << 1)) & 0x40000000) == 0) {
2035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2036ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return true;
2039ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2040ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2041ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2042ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Assembler::IsImmFP64(double imm) {
2043ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Valid values will have the form:
2044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
2045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // 0000.0000.0000.0000.0000.0000.0000.0000
2046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t bits = double_to_rawbits(imm);
2047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits[47..0] are cleared.
2048e6feb7aa71ed0d2318558000aaeb46220890ad9aIan Rogers  if ((bits & UINT64_C(0x0000ffffffffffff)) != 0) {
2049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2050ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2051ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2052ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bits[61..54] are all set or all cleared.
2053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint32_t b_pattern = (bits >> 48) & 0x3fc0;
20541123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  if ((b_pattern != 0) && (b_pattern != 0x3fc0)) {
2055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // bit[62] and bit[61] are opposite.
20591123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  if (((bits ^ (bits << 1)) & (UINT64_C(1) << 62)) == 0) {
2060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return false;
2061ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return true;
2064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2065ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStoreOp Assembler::LoadOpFor(const CPURegister& rt) {
20681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.IsValid());
2069ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2070ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDR_x : LDR_w;
2071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
20721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDR_d : LDR_s;
2074ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2075ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2076ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStorePairOp Assembler::LoadPairOpFor(const CPURegister& rt,
2079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    const CPURegister& rt2) {
20801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
2081ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(rt2);
2082ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDP_x : LDP_w;
2084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
20851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2086ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDP_d : LDP_s;
2087ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2088ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2089ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2090ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStoreOp Assembler::StoreOpFor(const CPURegister& rt) {
20921123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(rt.IsValid());
2093ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2094ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STR_x : STR_w;
2095ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
20961123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STR_d : STR_s;
2098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStorePairOp Assembler::StorePairOpFor(const CPURegister& rt,
2103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    const CPURegister& rt2) {
21041123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
2105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(rt2);
2106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STP_x : STP_w;
2108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
21091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STP_d : STP_s;
2111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStorePairNonTemporalOp Assembler::LoadPairNonTemporalOpFor(
2116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    const CPURegister& rt, const CPURegister& rt2) {
21171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
2118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(rt2);
2119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDNP_x : LDNP_w;
2121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
21221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? LDNP_d : LDNP_s;
2124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlLoadStorePairNonTemporalOp Assembler::StorePairNonTemporalOpFor(
2129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    const CPURegister& rt, const CPURegister& rt2) {
21301123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(AreSameSizeAndType(rt, rt2));
2131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  USE(rt2);
2132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (rt.IsRegister()) {
2133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STNP_x : STNP_w;
2134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
21351123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT(rt.IsFPRegister());
2136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return rt.Is64Bits() ? STNP_d : STNP_s;
2137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::RecordLiteral(int64_t imm, unsigned size) {
2142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  literals_.push_front(new Literal(pc_, imm, size));
2143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Check if a literal pool should be emitted. Currently a literal is emitted
2147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// when:
2148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//  * the distance to the first literal load handled by this pool is greater
2149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//    than the recommended distance and the literal pool can be emitted without
2150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//    generating a jump over it.
2151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//  * the distance to the first literal load handled by this pool is greater
2152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//    than twice the recommended distance.
2153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// TODO: refine this heuristic using real world data.
2154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::CheckLiteralPool(LiteralPoolEmitOption option) {
2155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (IsLiteralPoolBlocked()) {
2156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Literal pool emission is forbidden, no point in doing further checks.
2157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return;
2158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (literals_.empty()) {
2161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // No literal pool to emit.
2162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    next_literal_pool_check_ += kLiteralPoolCheckInterval;
2163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return;
2164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  intptr_t distance = pc_ - literals_.back()->pc_;
2167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if ((distance < kRecommendedLiteralPoolRange) ||
2168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      ((option == JumpRequired) &&
2169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl       (distance < (2 * kRecommendedLiteralPoolRange)))) {
2170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // We prefer not to have to jump over the literal pool.
2171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    next_literal_pool_check_ += kLiteralPoolCheckInterval;
2172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return;
2173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  EmitLiteralPool(option);
2176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Assembler::EmitLiteralPool(LiteralPoolEmitOption option) {
2180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Prevent recursive calls while emitting the literal pool.
2181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  BlockLiteralPoolScope scope(this);
2182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Label marker;
2184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Label start_of_pool;
2185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Label end_of_pool;
2186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (option == JumpRequired) {
2188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    b(&end_of_pool);
2189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Leave space for a literal pool marker. This is populated later, once the
2192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // size of the pool is known.
2193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bind(&marker);
2194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  nop();
2195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Now populate the literal pool.
2197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bind(&start_of_pool);
2198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::list<Literal*>::iterator it;
2199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (it = literals_.begin(); it != literals_.end(); it++) {
2200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Update the load-literal instruction to point to this pool entry.
2201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Instruction* load_literal = (*it)->pc_;
2202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    load_literal->SetImmLLiteral(pc_);
2203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // Copy the data into the pool.
2204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    uint64_t value= (*it)->value_;
2205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    unsigned size = (*it)->size_;
22061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((size == kXRegSizeInBytes) || (size == kWRegSizeInBytes));
22071123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl    VIXL_ASSERT((pc_ + size) <= (buffer_ + buffer_size_));
2208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    memcpy(pc_, &value, size);
2209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    pc_ += size;
2210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    delete *it;
2211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  literals_.clear();
2213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bind(&end_of_pool);
2214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // The pool size should always be a multiple of four bytes because that is the
2216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // scaling applied by the LDR(literal) instruction, even for X-register loads.
22171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT((SizeOfCodeGeneratedSince(&start_of_pool) % 4) == 0);
2218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  uint64_t pool_size = SizeOfCodeGeneratedSince(&start_of_pool) / 4;
2219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // Literal pool marker indicating the size in words of the literal pool.
2221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // We use a literal load to the zero register, the offset indicating the
2222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // size in words. This instruction can encode a large enough offset to span
2223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // the entire pool at its maximum size.
2224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  Instr marker_instruction = LDR_x_lit | ImmLLiteral(pool_size) | Rt(xzr);
2225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  memcpy(marker.target(), &marker_instruction, kInstructionSize);
2226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  next_literal_pool_check_ = pc_ + kLiteralPoolCheckInterval;
2228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Return the size in bytes, required by the literal pool entries. This does
2232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// not include any marker or branch over the literal pool itself.
2233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlsize_t Assembler::LiteralPoolSize() {
2234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  size_t size = 0;
2235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::list<Literal*>::iterator it;
2237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (it = literals_.begin(); it != literals_.end(); it++) {
2238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    size += (*it)->size_;
2239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return size;
2242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool AreAliased(const CPURegister& reg1, const CPURegister& reg2,
2246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                const CPURegister& reg3, const CPURegister& reg4,
2247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                const CPURegister& reg5, const CPURegister& reg6,
2248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                const CPURegister& reg7, const CPURegister& reg8) {
2249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int number_of_valid_regs = 0;
2250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int number_of_valid_fpregs = 0;
2251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  RegList unique_regs = 0;
2253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  RegList unique_fpregs = 0;
2254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  const CPURegister regs[] = {reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8};
2256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (unsigned i = 0; i < sizeof(regs) / sizeof(regs[0]); i++) {
2258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (regs[i].IsRegister()) {
2259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      number_of_valid_regs++;
2260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      unique_regs |= regs[i].Bit();
2261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else if (regs[i].IsFPRegister()) {
2262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      number_of_valid_fpregs++;
2263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      unique_fpregs |= regs[i].Bit();
2264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
22651123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl      VIXL_ASSERT(!regs[i].IsValid());
2266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
2267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
2268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int number_of_unique_regs =
2270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    CountSetBits(unique_regs, sizeof(unique_regs) * 8);
2271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  int number_of_unique_fpregs =
2272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    CountSetBits(unique_fpregs, sizeof(unique_fpregs) * 8);
2273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
22741123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(number_of_valid_regs >= number_of_unique_regs);
22751123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(number_of_valid_fpregs >= number_of_unique_fpregs);
2276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return (number_of_valid_regs != number_of_unique_regs) ||
2278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (number_of_valid_fpregs != number_of_unique_fpregs);
2279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool AreSameSizeAndType(const CPURegister& reg1, const CPURegister& reg2,
2283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& reg3, const CPURegister& reg4,
2284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& reg5, const CPURegister& reg6,
2285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                        const CPURegister& reg7, const CPURegister& reg8) {
22861123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl  VIXL_ASSERT(reg1.IsValid());
2287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  bool match = true;
2288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg2.IsValid() || reg2.IsSameSizeAndType(reg1);
2289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1);
2290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1);
2291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1);
2292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1);
2293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1);
2294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1);
2295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return match;
2296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
2297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
2300