Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/arm64/assembler-arm64.h

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Restore AreConsecutive change Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_
6 #define V8_ARM64_ASSEMBLER_ARM64_H_ 6 #define V8_ARM64_ASSEMBLER_ARM64_H_
7 7
8 #include <deque> 8 #include <deque>
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 V(s24) V(s25) V(s26) V(s27) V(s28) V(s29) V(s30) V(s31) 47 V(s24) V(s25) V(s26) V(s27) V(s28) V(s29) V(s30) V(s31)
48 48
49 #define DOUBLE_REGISTERS(R) \ 49 #define DOUBLE_REGISTERS(R) \
50 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ 50 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \
51 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \ 51 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \
52 R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \ 52 R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \
53 R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31) 53 R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31)
54 54
55 #define SIMD128_REGISTERS(V) \ 55 #define SIMD128_REGISTERS(V) \
56 V(q0) V(q1) V(q2) V(q3) V(q4) V(q5) V(q6) V(q7) \ 56 V(q0) V(q1) V(q2) V(q3) V(q4) V(q5) V(q6) V(q7) \
57 V(q8) V(q9) V(q10) V(q11) V(q12) V(q13) V(q14) V(q15) 57 V(q8) V(q9) V(q10) V(q11) V(q12) V(q13) V(q14) V(q15) \
58 V(q16) V(q17) V(q18) V(q19) V(q20) V(q21) V(q22) V(q23) \
59 V(q24) V(q25) V(q26) V(q27) V(q28) V(q29) V(q30) V(q31)
58 60
59 #define ALLOCATABLE_DOUBLE_REGISTERS(R) \ 61 #define ALLOCATABLE_DOUBLE_REGISTERS(R) \
60 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ 62 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \
61 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \ 63 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \
62 R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \ 64 R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \
63 R(d25) R(d26) R(d27) R(d28) 65 R(d25) R(d26) R(d27) R(d28)
64 // clang-format on 66 // clang-format on
65 67
66 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte; 68 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte;
67 69
68 70 // Some CPURegister methods can return Register and VRegister types, so we
69 // Some CPURegister methods can return Register and FPRegister types, so we
70 // need to declare them in advance. 71 // need to declare them in advance.
71 struct Register; 72 struct Register;
72 struct FPRegister; 73 struct VRegister;
73
74 74
75 struct CPURegister { 75 struct CPURegister {
76 enum Code { 76 enum Code {
77 #define REGISTER_CODE(R) kCode_##R, 77 #define REGISTER_CODE(R) kCode_##R,
78 GENERAL_REGISTERS(REGISTER_CODE) 78 GENERAL_REGISTERS(REGISTER_CODE)
79 #undef REGISTER_CODE 79 #undef REGISTER_CODE
80 kAfterLast, 80 kAfterLast,
81 kCode_no_reg = -1 81 kCode_no_reg = -1
82 }; 82 };
83 83
84 enum RegisterType { 84 enum RegisterType {
85 // The kInvalid value is used to detect uninitialized static instances, 85 // The kInvalid value is used to detect uninitialized static instances,
86 // which are always zero-initialized before any constructors are called. 86 // which are always zero-initialized before any constructors are called.
87 kInvalid = 0, 87 kInvalid = 0,
88 kRegister, 88 kRegister,
89 kFPRegister, 89 kVRegister,
90 kNoRegister 90 kNoRegister
91 }; 91 };
92 92
93 static CPURegister Create(int code, int size, RegisterType type) { 93 static CPURegister Create(int reg_code, int reg_size, RegisterType reg_type,
94 CPURegister r = {code, size, type}; 94 int lane_count = 1) {
95 CPURegister r = {reg_code, reg_size, reg_type, lane_count};
95 return r; 96 return r;
96 } 97 }
97 98
98 int code() const; 99 int code() const;
99 RegisterType type() const; 100 RegisterType type() const;
100 RegList Bit() const; 101 RegList Bit() const;
101 int SizeInBits() const; 102 int SizeInBits() const;
102 int SizeInBytes() const; 103 int SizeInBytes() const;
104 bool Is8Bits() const;
105 bool Is16Bits() const;
103 bool Is32Bits() const; 106 bool Is32Bits() const;
104 bool Is64Bits() const; 107 bool Is64Bits() const;
108 bool Is128Bits() const;
105 bool IsValid() const; 109 bool IsValid() const;
106 bool IsValidOrNone() const; 110 bool IsValidOrNone() const;
107 bool IsValidRegister() const; 111 bool IsValidRegister() const;
108 bool IsValidFPRegister() const; 112 bool IsValidVRegister() const;
109 bool IsNone() const; 113 bool IsNone() const;
110 bool Is(const CPURegister& other) const; 114 bool Is(const CPURegister& other) const;
111 bool Aliases(const CPURegister& other) const; 115 bool Aliases(const CPURegister& other) const;
112 116
113 bool IsZero() const; 117 bool IsZero() const;
114 bool IsSP() const; 118 bool IsSP() const;
115 119
116 bool IsRegister() const; 120 bool IsRegister() const;
117 bool IsFPRegister() const; 121 bool IsVRegister() const;
122
123 bool IsFPRegister() const { return IsS() || IsD(); }
124
125 bool IsW() const { return IsValidRegister() && Is32Bits(); }
126 bool IsX() const { return IsValidRegister() && Is64Bits(); }
127
128 // These assertions ensure that the size and type of the register are as
129 // described. They do not consider the number of lanes that make up a vector.
130 // So, for example, Is8B() implies IsD(), and Is1D() implies IsD, but IsD()
131 // does not imply Is1D() or Is8B().
132 // Check the number of lanes, ie. the format of the vector, using methods such
133 // as Is8B(), Is1D(), etc. in the VRegister class.
134 bool IsV() const { return IsVRegister(); }
135 bool IsB() const { return IsV() && Is8Bits(); }
136 bool IsH() const { return IsV() && Is16Bits(); }
137 bool IsS() const { return IsV() && Is32Bits(); }
138 bool IsD() const { return IsV() && Is64Bits(); }
139 bool IsQ() const { return IsV() && Is128Bits(); }
118 140
119 Register X() const; 141 Register X() const;
120 Register W() const; 142 Register W() const;
121 FPRegister D() const; 143 VRegister V() const;
122 FPRegister S() const; 144 VRegister B() const;
145 VRegister H() const;
146 VRegister D() const;
147 VRegister S() const;
148 VRegister Q() const;
123 149
124 bool IsSameSizeAndType(const CPURegister& other) const; 150 bool IsSameSizeAndType(const CPURegister& other) const;
125 151
126 // V8 compatibility. 152 // V8 compatibility.
127 bool is(const CPURegister& other) const { return Is(other); } 153 bool is(const CPURegister& other) const { return Is(other); }
128 bool is_valid() const { return IsValid(); } 154 bool is_valid() const { return IsValid(); }
129 155
130 int reg_code; 156 int reg_code;
131 int reg_size; 157 int reg_size;
132 RegisterType reg_type; 158 RegisterType reg_type;
159 int lane_count;
133 }; 160 };
134 161
135 162
136 struct Register : public CPURegister { 163 struct Register : public CPURegister {
137 static Register Create(int code, int size) { 164 static Register Create(int code, int size) {
138 return Register(CPURegister::Create(code, size, CPURegister::kRegister)); 165 return Register(CPURegister::Create(code, size, CPURegister::kRegister));
139 } 166 }
140 167
141 Register() { 168 Register() {
142 reg_code = 0; 169 reg_code = 0;
143 reg_size = 0; 170 reg_size = 0;
144 reg_type = CPURegister::kNoRegister; 171 reg_type = CPURegister::kNoRegister;
145 } 172 }
146 173
147 explicit Register(const CPURegister& r) { 174 explicit Register(const CPURegister& r) {
148 reg_code = r.reg_code; 175 reg_code = r.reg_code;
149 reg_size = r.reg_size; 176 reg_size = r.reg_size;
150 reg_type = r.reg_type; 177 reg_type = r.reg_type;
178 lane_count = r.lane_count;
151 DCHECK(IsValidOrNone()); 179 DCHECK(IsValidOrNone());
180 DCHECK_EQ(r.lane_count, 1);
152 } 181 }
153 182
154 Register(const Register& r) { // NOLINT(runtime/explicit) 183 Register(const Register& r) { // NOLINT(runtime/explicit)
155 reg_code = r.reg_code; 184 reg_code = r.reg_code;
156 reg_size = r.reg_size; 185 reg_size = r.reg_size;
157 reg_type = r.reg_type; 186 reg_type = r.reg_type;
187 lane_count = r.lane_count;
158 DCHECK(IsValidOrNone()); 188 DCHECK(IsValidOrNone());
159 } 189 }
160 190
161 bool IsValid() const { 191 bool IsValid() const {
162 DCHECK(IsRegister() || IsNone()); 192 DCHECK(IsRegister() || IsNone());
163 return IsValidRegister(); 193 return IsValidRegister();
164 } 194 }
165 195
166 static Register XRegFromCode(unsigned code); 196 static Register XRegFromCode(unsigned code);
167 static Register WRegFromCode(unsigned code); 197 static Register WRegFromCode(unsigned code);
(...skipping 24 matching lines...) Expand all
192 static Register from_code(int code) { 222 static Register from_code(int code) {
193 // Always return an X register. 223 // Always return an X register.
194 return Register::Create(code, kXRegSizeInBits); 224 return Register::Create(code, kXRegSizeInBits);
195 } 225 }
196 226
197 // End of V8 compatibility section ----------------------- 227 // End of V8 compatibility section -----------------------
198 }; 228 };
199 229
200 static const bool kSimpleFPAliasing = true; 230 static const bool kSimpleFPAliasing = true;
201 231
202 struct FPRegister : public CPURegister { 232 struct VRegister : public CPURegister {
203 enum Code { 233 enum Code {
204 #define REGISTER_CODE(R) kCode_##R, 234 #define REGISTER_CODE(R) kCode_##R,
205 DOUBLE_REGISTERS(REGISTER_CODE) 235 DOUBLE_REGISTERS(REGISTER_CODE)
206 #undef REGISTER_CODE 236 #undef REGISTER_CODE
207 kAfterLast, 237 kAfterLast,
208 kCode_no_reg = -1 238 kCode_no_reg = -1
209 }; 239 };
210 240
211 static FPRegister Create(int code, int size) { 241 static VRegister Create(int reg_code, int reg_size, int lane_count = 1) {
212 return FPRegister( 242 DCHECK(base::bits::IsPowerOfTwo32(lane_count) && (lane_count <= 16));
213 CPURegister::Create(code, size, CPURegister::kFPRegister)); 243 VRegister v(CPURegister::Create(reg_code, reg_size, CPURegister::kVRegister,
244 lane_count));
245 DCHECK(v.IsValidVRegister());
246 return v;
214 } 247 }
215 248
216 FPRegister() { 249 static VRegister Create(int reg_code, VectorFormat format) {
250 int reg_size = RegisterSizeInBitsFromFormat(format);
251 int reg_count = IsVectorFormat(format) ? LaneCountFromFormat(format) : 1;
252 return VRegister::Create(reg_code, reg_size, reg_count);
253 }
254
255 VRegister() {
217 reg_code = 0; 256 reg_code = 0;
218 reg_size = 0; 257 reg_size = 0;
219 reg_type = CPURegister::kNoRegister; 258 reg_type = CPURegister::kNoRegister;
259 lane_count = 1;
220 } 260 }
221 261
222 explicit FPRegister(const CPURegister& r) { 262 explicit VRegister(const CPURegister& r) {
223 reg_code = r.reg_code; 263 reg_code = r.reg_code;
224 reg_size = r.reg_size; 264 reg_size = r.reg_size;
225 reg_type = r.reg_type; 265 reg_type = r.reg_type;
266 lane_count = r.lane_count;
226 DCHECK(IsValidOrNone()); 267 DCHECK(IsValidOrNone());
227 } 268 }
228 269
229 FPRegister(const FPRegister& r) { // NOLINT(runtime/explicit) 270 VRegister(const VRegister& r) { // NOLINT(runtime/explicit)
230 reg_code = r.reg_code; 271 reg_code = r.reg_code;
231 reg_size = r.reg_size; 272 reg_size = r.reg_size;
232 reg_type = r.reg_type; 273 reg_type = r.reg_type;
274 lane_count = r.lane_count;
233 DCHECK(IsValidOrNone()); 275 DCHECK(IsValidOrNone());
234 } 276 }
235 277
236 bool IsValid() const { 278 bool IsValid() const {
237 DCHECK(IsFPRegister() || IsNone()); 279 DCHECK(IsVRegister() || IsNone());
238 return IsValidFPRegister(); 280 return IsValidVRegister();
239 } 281 }
240 282
241 static FPRegister SRegFromCode(unsigned code); 283 static VRegister BRegFromCode(unsigned code);
242 static FPRegister DRegFromCode(unsigned code); 284 static VRegister HRegFromCode(unsigned code);
285 static VRegister SRegFromCode(unsigned code);
286 static VRegister DRegFromCode(unsigned code);
287 static VRegister QRegFromCode(unsigned code);
288 static VRegister VRegFromCode(unsigned code);
289
290 VRegister V8B() const {
291 return VRegister::Create(code(), kDRegSizeInBits, 8);
292 }
293 VRegister V16B() const {
294 return VRegister::Create(code(), kQRegSizeInBits, 16);
295 }
296 VRegister V4H() const {
297 return VRegister::Create(code(), kDRegSizeInBits, 4);
298 }
299 VRegister V8H() const {
300 return VRegister::Create(code(), kQRegSizeInBits, 8);
301 }
302 VRegister V2S() const {
303 return VRegister::Create(code(), kDRegSizeInBits, 2);
304 }
305 VRegister V4S() const {
306 return VRegister::Create(code(), kQRegSizeInBits, 4);
307 }
308 VRegister V2D() const {
309 return VRegister::Create(code(), kQRegSizeInBits, 2);
310 }
311 VRegister V1D() const {
312 return VRegister::Create(code(), kDRegSizeInBits, 1);
313 }
314
315 bool Is8B() const { return (Is64Bits() && (lane_count == 8)); }
316 bool Is16B() const { return (Is128Bits() && (lane_count == 16)); }
317 bool Is4H() const { return (Is64Bits() && (lane_count == 4)); }
318 bool Is8H() const { return (Is128Bits() && (lane_count == 8)); }
319 bool Is2S() const { return (Is64Bits() && (lane_count == 2)); }
320 bool Is4S() const { return (Is128Bits() && (lane_count == 4)); }
321 bool Is1D() const { return (Is64Bits() && (lane_count == 1)); }
322 bool Is2D() const { return (Is128Bits() && (lane_count == 2)); }
323
324 // For consistency, we assert the number of lanes of these scalar registers,
325 // even though there are no vectors of equivalent total size with which they
326 // could alias.
327 bool Is1B() const {
328 DCHECK(!(Is8Bits() && IsVector()));
329 return Is8Bits();
330 }
331 bool Is1H() const {
332 DCHECK(!(Is16Bits() && IsVector()));
333 return Is16Bits();
334 }
335 bool Is1S() const {
336 DCHECK(!(Is32Bits() && IsVector()));
337 return Is32Bits();
338 }
339
340 bool IsLaneSizeB() const { return LaneSizeInBits() == kBRegSizeInBits; }
341 bool IsLaneSizeH() const { return LaneSizeInBits() == kHRegSizeInBits; }
342 bool IsLaneSizeS() const { return LaneSizeInBits() == kSRegSizeInBits; }
343 bool IsLaneSizeD() const { return LaneSizeInBits() == kDRegSizeInBits; }
344
345 bool IsScalar() const { return lane_count == 1; }
346 bool IsVector() const { return lane_count > 1; }
347
348 bool IsSameFormat(const VRegister& other) const {
349 return (reg_size == other.reg_size) && (lane_count == other.lane_count);
350 }
351
352 int LaneCount() const { return lane_count; }
353
354 unsigned LaneSizeInBytes() const { return SizeInBytes() / lane_count; }
355
356 unsigned LaneSizeInBits() const { return LaneSizeInBytes() * 8; }
243 357
244 // Start of V8 compatibility section --------------------- 358 // Start of V8 compatibility section ---------------------
245 static const int kMaxNumRegisters = kNumberOfFPRegisters; 359 static const int kMaxNumRegisters = kNumberOfVRegisters;
246 STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast); 360 STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast);
247 361
248 // Crankshaft can use all the FP registers except: 362 // Crankshaft can use all the V registers except:
249 // - d15 which is used to keep the 0 double value 363 // - d15 which is used to keep the 0 double value
250 // - d30 which is used in crankshaft as a double scratch register 364 // - d30 which is used in crankshaft as a double scratch register
251 // - d31 which is used in the MacroAssembler as a double scratch register 365 // - d31 which is used in the MacroAssembler as a double scratch register
252 static FPRegister from_code(int code) { 366 static VRegister from_code(int code) {
253 // Always return a D register. 367 // Always return a D register.
254 return FPRegister::Create(code, kDRegSizeInBits); 368 return VRegister::Create(code, kDRegSizeInBits);
255 } 369 }
256 // End of V8 compatibility section ----------------------- 370 // End of V8 compatibility section -----------------------
257 }; 371 };
258 372
259 373 static_assert(sizeof(CPURegister) == sizeof(Register),
260 STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); 374 "CPURegister must be same size as Register");
261 STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); 375 static_assert(sizeof(CPURegister) == sizeof(VRegister),
262 376 "CPURegister must be same size as VRegister");
263 377
264 #if defined(ARM64_DEFINE_REG_STATICS) 378 #if defined(ARM64_DEFINE_REG_STATICS)
265 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 379 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \
266 const CPURegister init_##register_class##_##name = {code, size, type}; \ 380 const CPURegister init_##register_class##_##name = {code, size, type, 1}; \
267 const register_class& name = *reinterpret_cast<const register_class*>( \ 381 const register_class& name = *reinterpret_cast<const register_class*>( \
268 &init_##register_class##_##name) 382 &init_##register_class##_##name)
269 #define ALIAS_REGISTER(register_class, alias, name) \ 383 #define ALIAS_REGISTER(register_class, alias, name) \
270 const register_class& alias = *reinterpret_cast<const register_class*>( \ 384 const register_class& alias = *reinterpret_cast<const register_class*>( \
271 &init_##register_class##_##name) 385 &init_##register_class##_##name)
272 #else 386 #else
273 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 387 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \
274 extern const register_class& name 388 extern const register_class& name
275 #define ALIAS_REGISTER(register_class, alias, name) \ 389 #define ALIAS_REGISTER(register_class, alias, name) \
276 extern const register_class& alias 390 extern const register_class& alias
277 #endif // defined(ARM64_DEFINE_REG_STATICS) 391 #endif // defined(ARM64_DEFINE_REG_STATICS)
278 392
279 // No*Reg is used to indicate an unused argument, or an error case. Note that 393 // No*Reg is used to indicate an unused argument, or an error case. Note that
280 // these all compare equal (using the Is() method). The Register and FPRegister 394 // these all compare equal (using the Is() method). The Register and VRegister
281 // variants are provided for convenience. 395 // variants are provided for convenience.
282 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister); 396 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister);
283 INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister); 397 INITIALIZE_REGISTER(VRegister, NoVReg, 0, 0, CPURegister::kNoRegister);
284 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister); 398 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister);
285 399
286 // v8 compatibility. 400 // v8 compatibility.
287 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); 401 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
288 402
289 #define DEFINE_REGISTERS(N) \ 403 #define DEFINE_REGISTERS(N) \
290 INITIALIZE_REGISTER(Register, w##N, N, \ 404 INITIALIZE_REGISTER(Register, w##N, N, \
291 kWRegSizeInBits, CPURegister::kRegister); \ 405 kWRegSizeInBits, CPURegister::kRegister); \
292 INITIALIZE_REGISTER(Register, x##N, N, \ 406 INITIALIZE_REGISTER(Register, x##N, N, \
293 kXRegSizeInBits, CPURegister::kRegister); 407 kXRegSizeInBits, CPURegister::kRegister);
294 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) 408 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
295 #undef DEFINE_REGISTERS 409 #undef DEFINE_REGISTERS
296 410
297 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits, 411 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
298 CPURegister::kRegister); 412 CPURegister::kRegister);
299 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits, 413 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
300 CPURegister::kRegister); 414 CPURegister::kRegister);
301 415
302 #define DEFINE_FPREGISTERS(N) \ 416 #define DEFINE_VREGISTERS(N) \
303 INITIALIZE_REGISTER(FPRegister, s##N, N, \ 417 INITIALIZE_REGISTER(VRegister, b##N, N, kBRegSizeInBits, \
304 kSRegSizeInBits, CPURegister::kFPRegister); \ 418 CPURegister::kVRegister); \
305 INITIALIZE_REGISTER(FPRegister, d##N, N, \ 419 INITIALIZE_REGISTER(VRegister, h##N, N, kHRegSizeInBits, \
306 kDRegSizeInBits, CPURegister::kFPRegister); 420 CPURegister::kVRegister); \
307 GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS) 421 INITIALIZE_REGISTER(VRegister, s##N, N, kSRegSizeInBits, \
308 #undef DEFINE_FPREGISTERS 422 CPURegister::kVRegister); \
423 INITIALIZE_REGISTER(VRegister, d##N, N, kDRegSizeInBits, \
424 CPURegister::kVRegister); \
425 INITIALIZE_REGISTER(VRegister, q##N, N, kQRegSizeInBits, \
426 CPURegister::kVRegister); \
427 INITIALIZE_REGISTER(VRegister, v##N, N, kQRegSizeInBits, \
428 CPURegister::kVRegister);
429 GENERAL_REGISTER_CODE_LIST(DEFINE_VREGISTERS)
430 #undef DEFINE_VREGISTERS
309 431
310 #undef INITIALIZE_REGISTER 432 #undef INITIALIZE_REGISTER
311 433
312 // Registers aliases. 434 // Registers aliases.
435 ALIAS_REGISTER(VRegister, v8_, v8); // Avoid conflicts with namespace v8.
313 ALIAS_REGISTER(Register, ip0, x16); 436 ALIAS_REGISTER(Register, ip0, x16);
314 ALIAS_REGISTER(Register, ip1, x17); 437 ALIAS_REGISTER(Register, ip1, x17);
315 ALIAS_REGISTER(Register, wip0, w16); 438 ALIAS_REGISTER(Register, wip0, w16);
316 ALIAS_REGISTER(Register, wip1, w17); 439 ALIAS_REGISTER(Register, wip1, w17);
317 // Root register. 440 // Root register.
318 ALIAS_REGISTER(Register, root, x26); 441 ALIAS_REGISTER(Register, root, x26);
319 ALIAS_REGISTER(Register, rr, x26); 442 ALIAS_REGISTER(Register, rr, x26);
320 // Context pointer register. 443 // Context pointer register.
321 ALIAS_REGISTER(Register, cp, x27); 444 ALIAS_REGISTER(Register, cp, x27);
322 // We use a register as a JS stack pointer to overcome the restriction on the 445 // We use a register as a JS stack pointer to overcome the restriction on the
323 // architectural SP alignment. 446 // architectural SP alignment.
324 // We chose x28 because it is contiguous with the other specific purpose 447 // We chose x28 because it is contiguous with the other specific purpose
325 // registers. 448 // registers.
326 STATIC_ASSERT(kJSSPCode == 28); 449 STATIC_ASSERT(kJSSPCode == 28);
327 ALIAS_REGISTER(Register, jssp, x28); 450 ALIAS_REGISTER(Register, jssp, x28);
328 ALIAS_REGISTER(Register, wjssp, w28); 451 ALIAS_REGISTER(Register, wjssp, w28);
329 ALIAS_REGISTER(Register, fp, x29); 452 ALIAS_REGISTER(Register, fp, x29);
330 ALIAS_REGISTER(Register, lr, x30); 453 ALIAS_REGISTER(Register, lr, x30);
331 ALIAS_REGISTER(Register, xzr, x31); 454 ALIAS_REGISTER(Register, xzr, x31);
332 ALIAS_REGISTER(Register, wzr, w31); 455 ALIAS_REGISTER(Register, wzr, w31);
333 456
334 // Keeps the 0 double value. 457 // Keeps the 0 double value.
335 ALIAS_REGISTER(FPRegister, fp_zero, d15); 458 ALIAS_REGISTER(VRegister, fp_zero, d15);
336 // Crankshaft double scratch register. 459 // Crankshaft double scratch register.
337 ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29); 460 ALIAS_REGISTER(VRegister, crankshaft_fp_scratch, d29);
338 // MacroAssembler double scratch registers. 461 // MacroAssembler double scratch registers.
339 ALIAS_REGISTER(FPRegister, fp_scratch, d30); 462 ALIAS_REGISTER(VRegister, fp_scratch, d30);
340 ALIAS_REGISTER(FPRegister, fp_scratch1, d30); 463 ALIAS_REGISTER(VRegister, fp_scratch1, d30);
341 ALIAS_REGISTER(FPRegister, fp_scratch2, d31); 464 ALIAS_REGISTER(VRegister, fp_scratch2, d31);
342 465
343 #undef ALIAS_REGISTER 466 #undef ALIAS_REGISTER
344 467
345 468
346 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, 469 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1,
347 Register reg2 = NoReg, 470 Register reg2 = NoReg,
348 Register reg3 = NoReg, 471 Register reg3 = NoReg,
349 Register reg4 = NoReg); 472 Register reg4 = NoReg);
350 473
351 474
(...skipping 14 matching lines...) Expand all
366 // arguments. At least one argument (reg1) must be valid (not NoCPUReg). 489 // arguments. At least one argument (reg1) must be valid (not NoCPUReg).
367 bool AreSameSizeAndType(const CPURegister& reg1, 490 bool AreSameSizeAndType(const CPURegister& reg1,
368 const CPURegister& reg2, 491 const CPURegister& reg2,
369 const CPURegister& reg3 = NoCPUReg, 492 const CPURegister& reg3 = NoCPUReg,
370 const CPURegister& reg4 = NoCPUReg, 493 const CPURegister& reg4 = NoCPUReg,
371 const CPURegister& reg5 = NoCPUReg, 494 const CPURegister& reg5 = NoCPUReg,
372 const CPURegister& reg6 = NoCPUReg, 495 const CPURegister& reg6 = NoCPUReg,
373 const CPURegister& reg7 = NoCPUReg, 496 const CPURegister& reg7 = NoCPUReg,
374 const CPURegister& reg8 = NoCPUReg); 497 const CPURegister& reg8 = NoCPUReg);
375 498
376 typedef FPRegister FloatRegister; 499 // AreSameFormat returns true if all of the specified VRegisters have the same
377 typedef FPRegister DoubleRegister; 500 // vector format. Arguments set to NoVReg are ignored, as are any subsequent
501 // arguments. At least one argument (reg1) must be valid (not NoVReg).
502 bool AreSameFormat(const VRegister& reg1, const VRegister& reg2,
503 const VRegister& reg3 = NoVReg,
504 const VRegister& reg4 = NoVReg);
378 505
379 // TODO(arm64) Define SIMD registers. 506 // AreConsecutive returns true if all of the specified VRegisters are
380 typedef FPRegister Simd128Register; 507 // consecutive in the register file. Arguments may be set to NoVReg, and if so,
508 // subsequent arguments must also be NoVReg. At least one argument (reg1) must
509 // be valid (not NoVReg).
510 bool AreConsecutive(const VRegister& reg1, const VRegister& reg2,
511 const VRegister& reg3 = NoVReg,
512 const VRegister& reg4 = NoVReg);
513
514 typedef VRegister FloatRegister;
515 typedef VRegister DoubleRegister;
516 typedef VRegister Simd128Register;
381 517
382 // ----------------------------------------------------------------------------- 518 // -----------------------------------------------------------------------------
383 // Lists of registers. 519 // Lists of registers.
384 class CPURegList { 520 class CPURegList {
385 public: 521 public:
386 explicit CPURegList(CPURegister reg1, 522 explicit CPURegList(CPURegister reg1,
387 CPURegister reg2 = NoCPUReg, 523 CPURegister reg2 = NoCPUReg,
388 CPURegister reg3 = NoCPUReg, 524 CPURegister reg3 = NoCPUReg,
389 CPURegister reg4 = NoCPUReg) 525 CPURegister reg4 = NoCPUReg)
390 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()), 526 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()),
391 size_(reg1.SizeInBits()), type_(reg1.type()) { 527 size_(reg1.SizeInBits()), type_(reg1.type()) {
392 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4)); 528 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4));
393 DCHECK(IsValid()); 529 DCHECK(IsValid());
394 } 530 }
395 531
396 CPURegList(CPURegister::RegisterType type, int size, RegList list) 532 CPURegList(CPURegister::RegisterType type, int size, RegList list)
397 : list_(list), size_(size), type_(type) { 533 : list_(list), size_(size), type_(type) {
398 DCHECK(IsValid()); 534 DCHECK(IsValid());
399 } 535 }
400 536
401 CPURegList(CPURegister::RegisterType type, int size, int first_reg, 537 CPURegList(CPURegister::RegisterType type, int size, int first_reg,
402 int last_reg) 538 int last_reg)
403 : size_(size), type_(type) { 539 : size_(size), type_(type) {
404 DCHECK(((type == CPURegister::kRegister) && 540 DCHECK(
405 (last_reg < kNumberOfRegisters)) || 541 ((type == CPURegister::kRegister) && (last_reg < kNumberOfRegisters)) ||
406 ((type == CPURegister::kFPRegister) && 542 ((type == CPURegister::kVRegister) &&
407 (last_reg < kNumberOfFPRegisters))); 543 (last_reg < kNumberOfVRegisters)));
408 DCHECK(last_reg >= first_reg); 544 DCHECK(last_reg >= first_reg);
409 list_ = (1UL << (last_reg + 1)) - 1; 545 list_ = (1UL << (last_reg + 1)) - 1;
410 list_ &= ~((1UL << first_reg) - 1); 546 list_ &= ~((1UL << first_reg) - 1);
411 DCHECK(IsValid()); 547 DCHECK(IsValid());
412 } 548 }
413 549
414 CPURegister::RegisterType type() const { 550 CPURegister::RegisterType type() const {
415 DCHECK(IsValid()); 551 DCHECK(IsValid());
416 return type_; 552 return type_;
417 } 553 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 586
451 // Remove all callee-saved registers from the list. This can be useful when 587 // Remove all callee-saved registers from the list. This can be useful when
452 // preparing registers for an AAPCS64 function call, for example. 588 // preparing registers for an AAPCS64 function call, for example.
453 void RemoveCalleeSaved(); 589 void RemoveCalleeSaved();
454 590
455 CPURegister PopLowestIndex(); 591 CPURegister PopLowestIndex();
456 CPURegister PopHighestIndex(); 592 CPURegister PopHighestIndex();
457 593
458 // AAPCS64 callee-saved registers. 594 // AAPCS64 callee-saved registers.
459 static CPURegList GetCalleeSaved(int size = kXRegSizeInBits); 595 static CPURegList GetCalleeSaved(int size = kXRegSizeInBits);
460 static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits); 596 static CPURegList GetCalleeSavedV(int size = kDRegSizeInBits);
461 597
462 // AAPCS64 caller-saved registers. Note that this includes lr. 598 // AAPCS64 caller-saved registers. Note that this includes lr.
599 // TODO(all): Determine how we handle d8-d15 being callee-saved, but the top
600 // 64-bits being caller-saved.
463 static CPURegList GetCallerSaved(int size = kXRegSizeInBits); 601 static CPURegList GetCallerSaved(int size = kXRegSizeInBits);
464 static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits); 602 static CPURegList GetCallerSavedV(int size = kDRegSizeInBits);
465 603
466 // Registers saved as safepoints. 604 // Registers saved as safepoints.
467 static CPURegList GetSafepointSavedRegisters(); 605 static CPURegList GetSafepointSavedRegisters();
468 606
469 bool IsEmpty() const { 607 bool IsEmpty() const {
470 DCHECK(IsValid()); 608 DCHECK(IsValid());
471 return list_ == 0; 609 return list_ == 0;
472 } 610 }
473 611
474 bool IncludesAliasOf(const CPURegister& other1, 612 bool IncludesAliasOf(const CPURegister& other1,
(...skipping 30 matching lines...) Expand all
505 return RegisterSizeInBytes() * Count(); 643 return RegisterSizeInBytes() * Count();
506 } 644 }
507 645
508 private: 646 private:
509 RegList list_; 647 RegList list_;
510 int size_; 648 int size_;
511 CPURegister::RegisterType type_; 649 CPURegister::RegisterType type_;
512 650
513 bool IsValid() const { 651 bool IsValid() const {
514 const RegList kValidRegisters = 0x8000000ffffffff; 652 const RegList kValidRegisters = 0x8000000ffffffff;
515 const RegList kValidFPRegisters = 0x0000000ffffffff; 653 const RegList kValidVRegisters = 0x0000000ffffffff;
516 switch (type_) { 654 switch (type_) {
517 case CPURegister::kRegister: 655 case CPURegister::kRegister:
518 return (list_ & kValidRegisters) == list_; 656 return (list_ & kValidRegisters) == list_;
519 case CPURegister::kFPRegister: 657 case CPURegister::kVRegister:
520 return (list_ & kValidFPRegisters) == list_; 658 return (list_ & kValidVRegisters) == list_;
521 case CPURegister::kNoRegister: 659 case CPURegister::kNoRegister:
522 return list_ == 0; 660 return list_ == 0;
523 default: 661 default:
524 UNREACHABLE(); 662 UNREACHABLE();
525 return false; 663 return false;
526 } 664 }
527 } 665 }
528 }; 666 };
529 667
530 668
531 // AAPCS64 callee-saved registers. 669 // AAPCS64 callee-saved registers.
532 #define kCalleeSaved CPURegList::GetCalleeSaved() 670 #define kCalleeSaved CPURegList::GetCalleeSaved()
533 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() 671 #define kCalleeSavedV CPURegList::GetCalleeSavedV()
534
535 672
536 // AAPCS64 caller-saved registers. Note that this includes lr. 673 // AAPCS64 caller-saved registers. Note that this includes lr.
537 #define kCallerSaved CPURegList::GetCallerSaved() 674 #define kCallerSaved CPURegList::GetCallerSaved()
538 #define kCallerSavedFP CPURegList::GetCallerSavedFP() 675 #define kCallerSavedV CPURegList::GetCallerSavedV()
539 676
540 // ----------------------------------------------------------------------------- 677 // -----------------------------------------------------------------------------
541 // Immediates. 678 // Immediates.
542 class Immediate { 679 class Immediate {
543 public: 680 public:
544 template<typename T> 681 template<typename T>
545 inline explicit Immediate(Handle<T> handle); 682 inline explicit Immediate(Handle<T> handle);
546 683
547 // This is allowed to be an implicit constructor because Immediate is 684 // This is allowed to be an implicit constructor because Immediate is
548 // a wrapper class that doesn't normally perform any type conversion. 685 // a wrapper class that doesn't normally perform any type conversion.
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 // Bit clear (A & ~B). 1229 // Bit clear (A & ~B).
1093 void bic(const Register& rd, 1230 void bic(const Register& rd,
1094 const Register& rn, 1231 const Register& rn,
1095 const Operand& operand); 1232 const Operand& operand);
1096 1233
1097 // Bit clear (A & ~B) and update status flags. 1234 // Bit clear (A & ~B) and update status flags.
1098 void bics(const Register& rd, 1235 void bics(const Register& rd,
1099 const Register& rn, 1236 const Register& rn,
1100 const Operand& operand); 1237 const Operand& operand);
1101 1238
1239 // Bitwise and.
1240 void and_(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1241
1242 // Bit clear immediate.
1243 void bic(const VRegister& vd, const int imm8, const int left_shift = 0);
1244
1245 // Bit clear.
1246 void bic(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1247
1248 // Bitwise insert if false.
1249 void bif(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1250
1251 // Bitwise insert if true.
1252 void bit(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1253
1254 // Bitwise select.
1255 void bsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1256
1257 // Polynomial multiply.
1258 void pmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1259
1260 // Vector move immediate.
1261 void movi(const VRegister& vd, const uint64_t imm, Shift shift = LSL,
1262 const int shift_amount = 0);
1263
1264 // Bitwise not.
1265 void mvn(const VRegister& vd, const VRegister& vn);
1266
1267 // Vector move inverted immediate.
1268 void mvni(const VRegister& vd, const int imm8, Shift shift = LSL,
1269 const int shift_amount = 0);
1270
1271 // Signed saturating accumulate of unsigned value.
1272 void suqadd(const VRegister& vd, const VRegister& vn);
1273
1274 // Unsigned saturating accumulate of signed value.
1275 void usqadd(const VRegister& vd, const VRegister& vn);
1276
1277 // Absolute value.
1278 void abs(const VRegister& vd, const VRegister& vn);
1279
1280 // Signed saturating absolute value.
1281 void sqabs(const VRegister& vd, const VRegister& vn);
1282
1283 // Negate.
1284 void neg(const VRegister& vd, const VRegister& vn);
1285
1286 // Signed saturating negate.
1287 void sqneg(const VRegister& vd, const VRegister& vn);
1288
1289 // Bitwise not.
1290 void not_(const VRegister& vd, const VRegister& vn);
1291
1292 // Extract narrow.
1293 void xtn(const VRegister& vd, const VRegister& vn);
1294
1295 // Extract narrow (second part).
1296 void xtn2(const VRegister& vd, const VRegister& vn);
1297
1298 // Signed saturating extract narrow.
1299 void sqxtn(const VRegister& vd, const VRegister& vn);
1300
1301 // Signed saturating extract narrow (second part).
1302 void sqxtn2(const VRegister& vd, const VRegister& vn);
1303
1304 // Unsigned saturating extract narrow.
1305 void uqxtn(const VRegister& vd, const VRegister& vn);
1306
1307 // Unsigned saturating extract narrow (second part).
1308 void uqxtn2(const VRegister& vd, const VRegister& vn);
1309
1310 // Signed saturating extract unsigned narrow.
1311 void sqxtun(const VRegister& vd, const VRegister& vn);
1312
1313 // Signed saturating extract unsigned narrow (second part).
1314 void sqxtun2(const VRegister& vd, const VRegister& vn);
1315
1316 // Move register to register.
1317 void mov(const VRegister& vd, const VRegister& vn);
1318
1319 // Bitwise orn.
bbudge 2017/02/22 01:50:59 nit: comments should contain more information, e.g
martyn.capewell 2017/02/23 13:10:41 Done.
1320 void orn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1321
1322 // Bitwise eor.
bbudge 2017/02/22 01:50:59 nit exclusive or.
martyn.capewell 2017/02/23 13:10:41 Done.
1323 void eor(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1324
1102 // Bitwise or (A | B). 1325 // Bitwise or (A | B).
1103 void orr(const Register& rd, const Register& rn, const Operand& operand); 1326 void orr(const Register& rd, const Register& rn, const Operand& operand);
1104 1327
1328 // Bitwise or.
1329 void orr(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1330
1331 // Bitwise or immediate.
1332 void orr(const VRegister& vd, const int imm8, const int left_shift = 0);
1333
1105 // Bitwise nor (A | ~B). 1334 // Bitwise nor (A | ~B).
1106 void orn(const Register& rd, const Register& rn, const Operand& operand); 1335 void orn(const Register& rd, const Register& rn, const Operand& operand);
1107 1336
1108 // Bitwise eor/xor (A ^ B). 1337 // Bitwise eor/xor (A ^ B).
1109 void eor(const Register& rd, const Register& rn, const Operand& operand); 1338 void eor(const Register& rd, const Register& rn, const Operand& operand);
1110 1339
1111 // Bitwise enor/xnor (A ^ ~B). 1340 // Bitwise enor/xnor (A ^ ~B).
1112 void eon(const Register& rd, const Register& rn, const Operand& operand); 1341 void eon(const Register& rd, const Register& rn, const Operand& operand);
1113 1342
1114 // Logical shift left variable. 1343 // Logical shift left variable.
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 ADR_FAR_NOP, 1730 ADR_FAR_NOP,
1502 FIRST_NOP_MARKER = DEBUG_BREAK_NOP, 1731 FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
1503 LAST_NOP_MARKER = ADR_FAR_NOP 1732 LAST_NOP_MARKER = ADR_FAR_NOP
1504 }; 1733 };
1505 1734
1506 void nop(NopMarkerTypes n) { 1735 void nop(NopMarkerTypes n) {
1507 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER)); 1736 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER));
1508 mov(Register::XRegFromCode(n), Register::XRegFromCode(n)); 1737 mov(Register::XRegFromCode(n), Register::XRegFromCode(n));
1509 } 1738 }
1510 1739
1740 // Add.
1741 void add(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1742
1743 // Unsigned halving add.
1744 void uhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1745
1746 // Subtract.
1747 void sub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1748
1749 // Signed halving add.
1750 void shadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1751
1752 // Multiply by scalar element.
1753 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1754 int vm_index);
1755
1756 // Multiply-add by scalar element.
1757 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1758 int vm_index);
1759
1760 // Multiply-subtract by scalar element.
1761 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1762 int vm_index);
1763
1764 // Signed long multiply-add by scalar element.
1765 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1766 int vm_index);
1767
1768 // Signed long multiply-add by scalar element (second part).
1769 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1770 int vm_index);
1771
1772 // Unsigned long multiply-add by scalar element.
1773 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1774 int vm_index);
1775
1776 // Unsigned long multiply-add by scalar element (second part).
1777 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1778 int vm_index);
1779
1780 // Signed long multiply-sub by scalar element.
1781 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1782 int vm_index);
1783
1784 // Signed long multiply-sub by scalar element (second part).
1785 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1786 int vm_index);
1787
1788 // Unsigned long multiply-sub by scalar element.
1789 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1790 int vm_index);
1791
1792 // Unsigned long multiply-sub by scalar element (second part).
1793 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1794 int vm_index);
1795
1796 // Signed long multiply by scalar element.
1797 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1798 int vm_index);
1799
1800 // Signed long multiply by scalar element (second part).
1801 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1802 int vm_index);
1803
1804 // Unsigned long multiply by scalar element.
1805 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1806 int vm_index);
1807
1808 // Unsigned long multiply by scalar element (second part).
1809 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1810 int vm_index);
1811
1812 // Add narrow returning high half.
1813 void addhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1814
1815 // Add narrow returning high half (second part).
1816 void addhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1817
1818 // Signed saturating double long multiply by element.
1819 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1820 int vm_index);
1821
1822 // Signed saturating double long multiply by element (second part).
1823 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1824 int vm_index);
1825
1826 // Signed saturating doubling long multiply-add by element.
1827 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1828 int vm_index);
1829
1830 // Signed saturating doubling long multiply-add by element (second part).
1831 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1832 int vm_index);
1833
1834 // Signed saturating doubling long multiply-sub by element.
1835 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1836 int vm_index);
1837
1838 // Signed saturating doubling long multiply-sub by element (second part).
1839 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1840 int vm_index);
1841
1842 // Compare bitwise to zero.
1843 void cmeq(const VRegister& vd, const VRegister& vn, int value);
1844
1845 // Compare signed greater than or equal to zero.
1846 void cmge(const VRegister& vd, const VRegister& vn, int value);
1847
1848 // Compare signed greater than zero.
1849 void cmgt(const VRegister& vd, const VRegister& vn, int value);
1850
1851 // Compare signed less than or equal to zero.
1852 void cmle(const VRegister& vd, const VRegister& vn, int value);
1853
1854 // Compare signed less than zero.
1855 void cmlt(const VRegister& vd, const VRegister& vn, int value);
1856
1857 // Unsigned rounding halving add.
1858 void urhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1859
1860 // Compare equal.
1861 void cmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1862
1863 // Compare signed greater than or equal.
1864 void cmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1865
1866 // Compare signed greater than.
1867 void cmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1868
1869 // Compare unsigned higher.
1870 void cmhi(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1871
1872 // Compare unsigned higher or same.
1873 void cmhs(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1874
1875 // Compare bitwise test bits nonzero.
1876 void cmtst(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1877
1878 // Signed shift left by register.
1879 void sshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1880
1881 // Unsigned shift left by register.
1882 void ushl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1883
1884 // Signed saturating doubling long multiply-subtract.
1885 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1886
1887 // Signed saturating doubling long multiply-subtract (second part).
1888 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1889
1890 // Signed saturating doubling long multiply.
1891 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1892
1893 // Signed saturating doubling long multiply (second part).
1894 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1895
1896 // Signed saturating doubling multiply returning high half.
1897 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1898
1899 // Signed saturating rounding doubling multiply returning high half.
1900 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1901
1902 // Signed saturating doubling multiply element returning high half.
1903 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1904 int vm_index);
1905
1906 // Signed saturating rounding doubling multiply element returning high half.
1907 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1908 int vm_index);
1909
1910 // Unsigned long multiply long.
1911 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1912
1913 // Unsigned long multiply (second part).
1914 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1915
1916 // Rounding add narrow returning high half.
1917 void raddhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1918
1919 // Subtract narrow returning high half.
1920 void subhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1921
1922 // Subtract narrow returning high half (second part).
1923 void subhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1924
1925 // Rounding add narrow returning high half (second part).
1926 void raddhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1927
1928 // Rounding subtract narrow returning high half.
1929 void rsubhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1930
1931 // Rounding subtract narrow returning high half (second part).
1932 void rsubhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1933
1934 // Signed saturating shift left by register.
1935 void sqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1936
1937 // Unsigned saturating shift left by register.
1938 void uqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1939
1940 // Signed rounding shift left by register.
1941 void srshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1942
1943 // Unsigned rounding shift left by register.
1944 void urshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1945
1946 // Signed saturating rounding shift left by register.
1947 void sqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1948
1949 // Unsigned saturating rounding shift left by register.
1950 void uqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1951
1952 // Signed absolute difference.
1953 void sabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1954
1955 // Unsigned absolute difference and accumulate.
1956 void uaba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1957
1958 // Shift left by immediate and insert.
1959 void sli(const VRegister& vd, const VRegister& vn, int shift);
1960
1961 // Shift right by immediate and insert.
1962 void sri(const VRegister& vd, const VRegister& vn, int shift);
1963
1964 // Signed maximum.
1965 void smax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1966
1967 // Signed pairwise maximum.
1968 void smaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1969
1970 // Add across vector.
1971 void addv(const VRegister& vd, const VRegister& vn);
1972
1973 // Signed add long across vector.
1974 void saddlv(const VRegister& vd, const VRegister& vn);
1975
1976 // Unsigned add long across vector.
1977 void uaddlv(const VRegister& vd, const VRegister& vn);
1978
1979 // FP maximum number across vector.
1980 void fmaxnmv(const VRegister& vd, const VRegister& vn);
1981
1982 // FP maximum across vector.
1983 void fmaxv(const VRegister& vd, const VRegister& vn);
1984
1985 // FP minimum number across vector.
1986 void fminnmv(const VRegister& vd, const VRegister& vn);
1987
1988 // FP minimum across vector.
1989 void fminv(const VRegister& vd, const VRegister& vn);
1990
1991 // Signed maximum across vector.
1992 void smaxv(const VRegister& vd, const VRegister& vn);
1993
1994 // Signed minimum.
1995 void smin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1996
1997 // Signed minimum pairwise.
1998 void sminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1999
2000 // Signed minimum across vector.
2001 void sminv(const VRegister& vd, const VRegister& vn);
2002
2003 // One-element structure store from one register.
2004 void st1(const VRegister& vt, const MemOperand& src);
2005
2006 // One-element structure store from two registers.
2007 void st1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2008
2009 // One-element structure store from three registers.
2010 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2011 const MemOperand& src);
2012
2013 // One-element structure store from four registers.
2014 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2015 const VRegister& vt4, const MemOperand& src);
2016
2017 // One-element single structure store from one lane.
2018 void st1(const VRegister& vt, int lane, const MemOperand& src);
2019
2020 // Two-element structure store from two registers.
2021 void st2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2022
2023 // Two-element single structure store from two lanes.
2024 void st2(const VRegister& vt, const VRegister& vt2, int lane,
2025 const MemOperand& src);
2026
2027 // Three-element structure store from three registers.
2028 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2029 const MemOperand& src);
2030
2031 // Three-element single structure store from three lanes.
2032 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2033 int lane, const MemOperand& src);
2034
2035 // Four-element structure store from four registers.
2036 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2037 const VRegister& vt4, const MemOperand& src);
2038
2039 // Four-element single structure store from four lanes.
2040 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2041 const VRegister& vt4, int lane, const MemOperand& src);
2042
2043 // Unsigned add long.
2044 void uaddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2045
2046 // Unsigned add long (second part).
2047 void uaddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2048
2049 // Unsigned add wide.
2050 void uaddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2051
2052 // Unsigned add wide (second part).
2053 void uaddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2054
2055 // Signed add long.
2056 void saddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2057
2058 // Signed add long (second part).
2059 void saddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2060
2061 // Signed add wide.
2062 void saddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2063
2064 // Signed add wide (second part).
2065 void saddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2066
2067 // Unsigned subtract long.
2068 void usubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2069
2070 // Unsigned subtract long (second part).
2071 void usubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2072
2073 // Unsigned subtract wide.
2074 void usubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2075
2076 // Signed subtract long.
2077 void ssubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2078
2079 // Signed subtract long (second part).
2080 void ssubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2081
2082 // Signed integer subtract wide.
2083 void ssubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2084
2085 // Signed integer subtract wide (second part).
2086 void ssubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2087
2088 // Unsigned subtract wide (second part).
2089 void usubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2090
2091 // Unsigned maximum.
2092 void umax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2093
2094 // Unsigned pairwise maximum.
2095 void umaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2096
2097 // Unsigned maximum across vector.
2098 void umaxv(const VRegister& vd, const VRegister& vn);
2099
2100 // Unsigned minimum.
2101 void umin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2102
2103 // Unsigned pairwise minimum.
2104 void uminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2105
2106 // Unsigned minimum across vector.
2107 void uminv(const VRegister& vd, const VRegister& vn);
2108
2109 // Transpose vectors (primary).
2110 void trn1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2111
2112 // Transpose vectors (secondary).
2113 void trn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2114
2115 // Unzip vectors (primary).
2116 void uzp1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2117
2118 // Unzip vectors (secondary).
2119 void uzp2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2120
2121 // Zip vectors (primary).
2122 void zip1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2123
2124 // Zip vectors (secondary).
2125 void zip2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2126
2127 // Signed shift right by immediate.
2128 void sshr(const VRegister& vd, const VRegister& vn, int shift);
2129
2130 // Unsigned shift right by immediate.
2131 void ushr(const VRegister& vd, const VRegister& vn, int shift);
2132
2133 // Signed rounding shift right by immediate.
2134 void srshr(const VRegister& vd, const VRegister& vn, int shift);
2135
2136 // Unsigned rounding shift right by immediate.
2137 void urshr(const VRegister& vd, const VRegister& vn, int shift);
2138
2139 // Signed shift right by immediate and accumulate.
2140 void ssra(const VRegister& vd, const VRegister& vn, int shift);
2141
2142 // Unsigned shift right by immediate and accumulate.
2143 void usra(const VRegister& vd, const VRegister& vn, int shift);
2144
2145 // Signed rounding shift right by immediate and accumulate.
2146 void srsra(const VRegister& vd, const VRegister& vn, int shift);
2147
2148 // Unsigned rounding shift right by immediate and accumulate.
2149 void ursra(const VRegister& vd, const VRegister& vn, int shift);
2150
2151 // Shift right narrow by immediate.
2152 void shrn(const VRegister& vd, const VRegister& vn, int shift);
2153
2154 // Shift right narrow by immediate (second part).
2155 void shrn2(const VRegister& vd, const VRegister& vn, int shift);
2156
2157 // Rounding shift right narrow by immediate.
2158 void rshrn(const VRegister& vd, const VRegister& vn, int shift);
2159
2160 // Rounding shift right narrow by immediate (second part).
2161 void rshrn2(const VRegister& vd, const VRegister& vn, int shift);
2162
2163 // Unsigned saturating shift right narrow by immediate.
2164 void uqshrn(const VRegister& vd, const VRegister& vn, int shift);
2165
2166 // Unsigned saturating shift right narrow by immediate (second part).
2167 void uqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2168
2169 // Unsigned saturating rounding shift right narrow by immediate.
2170 void uqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2171
2172 // Unsigned saturating rounding shift right narrow by immediate (second part).
2173 void uqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2174
2175 // Signed saturating shift right narrow by immediate.
2176 void sqshrn(const VRegister& vd, const VRegister& vn, int shift);
2177
2178 // Signed saturating shift right narrow by immediate (second part).
2179 void sqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2180
2181 // Signed saturating rounded shift right narrow by immediate.
2182 void sqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2183
2184 // Signed saturating rounded shift right narrow by immediate (second part).
2185 void sqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2186
2187 // Signed saturating shift right unsigned narrow by immediate.
2188 void sqshrun(const VRegister& vd, const VRegister& vn, int shift);
2189
2190 // Signed saturating shift right unsigned narrow by immediate (second part).
2191 void sqshrun2(const VRegister& vd, const VRegister& vn, int shift);
2192
2193 // Signed sat rounded shift right unsigned narrow by immediate.
2194 void sqrshrun(const VRegister& vd, const VRegister& vn, int shift);
2195
2196 // Signed sat rounded shift right unsigned narrow by immediate (second part).
2197 void sqrshrun2(const VRegister& vd, const VRegister& vn, int shift);
2198
2199 // FP reciprocal step.
2200 void frecps(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2201
2202 // FP reciprocal estimate.
2203 void frecpe(const VRegister& vd, const VRegister& vn);
2204
2205 // FP reciprocal square root estimate.
2206 void frsqrte(const VRegister& vd, const VRegister& vn);
2207
2208 // FP reciprocal square root step.
2209 void frsqrts(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2210
2211 // Signed absolute difference and accumulate long.
2212 void sabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2213
2214 // Signed absolute difference and accumulate long (second part).
2215 void sabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2216
2217 // Unsigned absolute difference and accumulate long.
2218 void uabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2219
2220 // Unsigned absolute difference and accumulate long (second part).
2221 void uabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2222
2223 // Signed absolute difference long.
2224 void sabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2225
2226 // Signed absolute difference long (second part).
2227 void sabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2228
2229 // Unsigned absolute difference long.
2230 void uabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2231
2232 // Unsigned absolute difference long (second part).
2233 void uabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2234
2235 // Polynomial multiply long.
2236 void pmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2237
2238 // Polynomial multiply long (second part).
2239 void pmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2240
2241 // Signed long multiply-add.
2242 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2243
2244 // Signed long multiply-add (second part).
2245 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2246
2247 // Unsigned long multiply-add.
2248 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2249
2250 // Unsigned long multiply-add (second part).
2251 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2252
2253 // Signed long multiply-sub.
2254 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2255
2256 // Signed long multiply-sub (second part).
2257 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2258
2259 // Unsigned long multiply-sub.
2260 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2261
2262 // Unsigned long multiply-sub (second part).
2263 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2264
2265 // Signed long multiply.
2266 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2267
2268 // Signed long multiply (second part).
2269 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2270
2271 // Signed saturating doubling long multiply-add.
2272 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2273
2274 // Signed saturating doubling long multiply-add (second part).
2275 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2276
2277 // Unsigned absolute difference.
2278 void uabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2279
2280 // Signed absolute difference and accumulate.
2281 void saba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2282
1511 // FP instructions. 2283 // FP instructions.
1512 // Move immediate to FP register. 2284 // Move immediate to FP register.
1513 void fmov(FPRegister fd, double imm); 2285 void fmov(const VRegister& fd, double imm);
1514 void fmov(FPRegister fd, float imm); 2286 void fmov(const VRegister& fd, float imm);
1515 2287
1516 // Move FP register to register. 2288 // Move FP register to register.
1517 void fmov(Register rd, FPRegister fn); 2289 void fmov(const Register& rd, const VRegister& fn);
1518 2290
1519 // Move register to FP register. 2291 // Move register to FP register.
1520 void fmov(FPRegister fd, Register rn); 2292 void fmov(const VRegister& fd, const Register& rn);
1521 2293
1522 // Move FP register to FP register. 2294 // Move FP register to FP register.
1523 void fmov(FPRegister fd, FPRegister fn); 2295 void fmov(const VRegister& fd, const VRegister& fn);
2296
2297 // Move 64-bit register to top half of 128-bit FP register.
2298 void fmov(const VRegister& vd, int index, const Register& rn);
2299
2300 // Move top half of 128-bit FP register to 64-bit register.
2301 void fmov(const Register& rd, const VRegister& vn, int index);
1524 2302
1525 // FP add. 2303 // FP add.
1526 void fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2304 void fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1527 2305
1528 // FP subtract. 2306 // FP subtract.
1529 void fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2307 void fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1530 2308
1531 // FP multiply. 2309 // FP multiply.
1532 void fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2310 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1533 2311
1534 // FP fused multiply and add. 2312 // FP compare equal to zero.
1535 void fmadd(const FPRegister& fd, 2313 void fcmeq(const VRegister& vd, const VRegister& vn, double imm);
1536 const FPRegister& fn, 2314
1537 const FPRegister& fm, 2315 // FP greater than zero.
1538 const FPRegister& fa); 2316 void fcmgt(const VRegister& vd, const VRegister& vn, double imm);
1539 2317
1540 // FP fused multiply and subtract. 2318 // FP greater than or equal to zero.
1541 void fmsub(const FPRegister& fd, 2319 void fcmge(const VRegister& vd, const VRegister& vn, double imm);
1542 const FPRegister& fn, 2320
1543 const FPRegister& fm, 2321 // FP less than or equal to zero.
1544 const FPRegister& fa); 2322 void fcmle(const VRegister& vd, const VRegister& vn, double imm);
1545 2323
1546 // FP fused multiply, add and negate. 2324 // FP less than to zero.
1547 void fnmadd(const FPRegister& fd, 2325 void fcmlt(const VRegister& vd, const VRegister& vn, double imm);
1548 const FPRegister& fn, 2326
1549 const FPRegister& fm, 2327 // FP absolute difference.
1550 const FPRegister& fa); 2328 void fabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1551 2329
1552 // FP fused multiply, subtract and negate. 2330 // FP pairwise add vector.
1553 void fnmsub(const FPRegister& fd, 2331 void faddp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1554 const FPRegister& fn, 2332
1555 const FPRegister& fm, 2333 // FP pairwise add scalar.
1556 const FPRegister& fa); 2334 void faddp(const VRegister& vd, const VRegister& vn);
2335
2336 // FP pairwise maximum scalar.
2337 void fmaxp(const VRegister& vd, const VRegister& vn);
2338
2339 // FP pairwise maximum number scalar.
2340 void fmaxnmp(const VRegister& vd, const VRegister& vn);
2341
2342 // FP pairwise minimum number scalar.
2343 void fminnmp(const VRegister& vd, const VRegister& vn);
2344
2345 // FP vector multiply accumulate.
2346 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2347
2348 // FP vector multiply subtract.
2349 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2350
2351 // FP vector multiply extended.
2352 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2353
2354 // FP absolute greater than or equal.
2355 void facge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2356
2357 // FP absolute greater than.
2358 void facgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2359
2360 // FP multiply by element.
2361 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2362 int vm_index);
2363
2364 // FP fused multiply-add to accumulator by element.
2365 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2366 int vm_index);
2367
2368 // FP fused multiply-sub from accumulator by element.
2369 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2370 int vm_index);
2371
2372 // FP multiply extended by element.
2373 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2374 int vm_index);
2375
2376 // FP compare equal.
2377 void fcmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2378
2379 // FP greater than.
2380 void fcmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2381
2382 // FP greater than or equal.
2383 void fcmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2384
2385 // FP pairwise maximum vector.
2386 void fmaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2387
2388 // FP pairwise minimum vector.
2389 void fminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2390
2391 // FP pairwise minimum scalar.
2392 void fminp(const VRegister& vd, const VRegister& vn);
2393
2394 // FP pairwise maximum number vector.
2395 void fmaxnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2396
2397 // FP pairwise minimum number vector.
2398 void fminnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2399
2400 // FP fused multiply-add.
2401 void fmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2402 const VRegister& va);
2403
2404 // FP fused multiply-subtract.
2405 void fmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2406 const VRegister& va);
2407
2408 // FP fused multiply-add and negate.
2409 void fnmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2410 const VRegister& va);
2411
2412 // FP fused multiply-subtract and negate.
2413 void fnmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2414 const VRegister& va);
2415
2416 // FP multiply-negate scalar.
2417 void fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2418
2419 // FP reciprocal exponent scalar.
2420 void frecpx(const VRegister& vd, const VRegister& vn);
1557 2421
1558 // FP divide. 2422 // FP divide.
1559 void fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2423 void fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1560 2424
1561 // FP maximum. 2425 // FP maximum.
1562 void fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2426 void fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1563 2427
1564 // FP minimum. 2428 // FP minimum.
1565 void fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2429 void fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1566 2430
1567 // FP maximum. 2431 // FP maximum.
1568 void fmaxnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2432 void fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1569 2433
1570 // FP minimum. 2434 // FP minimum.
1571 void fminnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2435 void fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1572 2436
1573 // FP absolute. 2437 // FP absolute.
1574 void fabs(const FPRegister& fd, const FPRegister& fn); 2438 void fabs(const VRegister& vd, const VRegister& vn);
1575 2439
1576 // FP negate. 2440 // FP negate.
1577 void fneg(const FPRegister& fd, const FPRegister& fn); 2441 void fneg(const VRegister& vd, const VRegister& vn);
1578 2442
1579 // FP square root. 2443 // FP square root.
1580 void fsqrt(const FPRegister& fd, const FPRegister& fn); 2444 void fsqrt(const VRegister& vd, const VRegister& vn);
1581 2445
1582 // FP round to integer (nearest with ties to away). 2446 // FP round to integer nearest with ties to away.
1583 void frinta(const FPRegister& fd, const FPRegister& fn); 2447 void frinta(const VRegister& vd, const VRegister& vn);
1584 2448
1585 // FP round to integer (toward minus infinity). 2449 // FP round to integer, implicit rounding.
1586 void frintm(const FPRegister& fd, const FPRegister& fn); 2450 void frinti(const VRegister& vd, const VRegister& vn);
1587 2451
1588 // FP round to integer (nearest with ties to even). 2452 // FP round to integer toward minus infinity.
1589 void frintn(const FPRegister& fd, const FPRegister& fn); 2453 void frintm(const VRegister& vd, const VRegister& vn);
1590 2454
1591 // FP round to integer (towards plus infinity). 2455 // FP round to integer nearest with ties to even.
1592 void frintp(const FPRegister& fd, const FPRegister& fn); 2456 void frintn(const VRegister& vd, const VRegister& vn);
1593 2457
1594 // FP round to integer (towards zero.) 2458 // FP round to integer towards plus infinity.
1595 void frintz(const FPRegister& fd, const FPRegister& fn); 2459 void frintp(const VRegister& vd, const VRegister& vn);
2460
2461 // FP round to integer, exact, implicit rounding.
2462 void frintx(const VRegister& vd, const VRegister& vn);
2463
2464 // FP round to integer towards zero.
2465 void frintz(const VRegister& vd, const VRegister& vn);
1596 2466
1597 // FP compare registers. 2467 // FP compare registers.
1598 void fcmp(const FPRegister& fn, const FPRegister& fm); 2468 void fcmp(const VRegister& vn, const VRegister& vm);
1599 2469
1600 // FP compare immediate. 2470 // FP compare immediate.
1601 void fcmp(const FPRegister& fn, double value); 2471 void fcmp(const VRegister& vn, double value);
1602 2472
1603 // FP conditional compare. 2473 // FP conditional compare.
1604 void fccmp(const FPRegister& fn, 2474 void fccmp(const VRegister& vn, const VRegister& vm, StatusFlags nzcv,
1605 const FPRegister& fm,
1606 StatusFlags nzcv,
1607 Condition cond); 2475 Condition cond);
1608 2476
1609 // FP conditional select. 2477 // FP conditional select.
1610 void fcsel(const FPRegister& fd, 2478 void fcsel(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1611 const FPRegister& fn,
1612 const FPRegister& fm,
1613 Condition cond); 2479 Condition cond);
1614 2480
1615 // Common FP Convert function 2481 // Common FP Convert functions.
1616 void FPConvertToInt(const Register& rd, 2482 void NEONFPConvertToInt(const Register& rd, const VRegister& vn, Instr op);
1617 const FPRegister& fn, 2483 void NEONFPConvertToInt(const VRegister& vd, const VRegister& vn, Instr op);
1618 FPIntegerConvertOp op); 2484
1619 2485 // FP convert between precisions.
1620 // FP convert between single and double precision. 2486 void fcvt(const VRegister& vd, const VRegister& vn);
1621 void fcvt(const FPRegister& fd, const FPRegister& fn); 2487
1622 2488 // FP convert to higher precision.
1623 // Convert FP to unsigned integer (nearest with ties to away). 2489 void fcvtl(const VRegister& vd, const VRegister& vn);
1624 void fcvtau(const Register& rd, const FPRegister& fn); 2490
1625 2491 // FP convert to higher precision (second part).
1626 // Convert FP to signed integer (nearest with ties to away). 2492 void fcvtl2(const VRegister& vd, const VRegister& vn);
1627 void fcvtas(const Register& rd, const FPRegister& fn); 2493
1628 2494 // FP convert to lower precision.
1629 // Convert FP to unsigned integer (round towards -infinity). 2495 void fcvtn(const VRegister& vd, const VRegister& vn);
1630 void fcvtmu(const Register& rd, const FPRegister& fn); 2496
1631 2497 // FP convert to lower prevision (second part).
1632 // Convert FP to signed integer (round towards -infinity). 2498 void fcvtn2(const VRegister& vd, const VRegister& vn);
1633 void fcvtms(const Register& rd, const FPRegister& fn); 2499
1634 2500 // FP convert to lower precision, rounding to odd.
1635 // Convert FP to unsigned integer (nearest with ties to even). 2501 void fcvtxn(const VRegister& vd, const VRegister& vn);
1636 void fcvtnu(const Register& rd, const FPRegister& fn); 2502
1637 2503 // FP convert to lower precision, rounding to odd (second part).
1638 // Convert FP to signed integer (nearest with ties to even). 2504 void fcvtxn2(const VRegister& vd, const VRegister& vn);
1639 void fcvtns(const Register& rd, const FPRegister& fn); 2505
1640 2506 // FP convert to signed integer, nearest with ties to away.
1641 // Convert FP to unsigned integer (round towards zero). 2507 void fcvtas(const Register& rd, const VRegister& vn);
1642 void fcvtzu(const Register& rd, const FPRegister& fn); 2508
1643 2509 // FP convert to unsigned integer, nearest with ties to away.
1644 // Convert FP to signed integer (rounf towards zero). 2510 void fcvtau(const Register& rd, const VRegister& vn);
1645 void fcvtzs(const Register& rd, const FPRegister& fn); 2511
2512 // FP convert to signed integer, nearest with ties to away.
2513 void fcvtas(const VRegister& vd, const VRegister& vn);
2514
2515 // FP convert to unsigned integer, nearest with ties to away.
2516 void fcvtau(const VRegister& vd, const VRegister& vn);
2517
2518 // FP convert to signed integer, round towards -infinity.
2519 void fcvtms(const Register& rd, const VRegister& vn);
2520
2521 // FP convert to unsigned integer, round towards -infinity.
2522 void fcvtmu(const Register& rd, const VRegister& vn);
2523
2524 // FP convert to signed integer, round towards -infinity.
2525 void fcvtms(const VRegister& vd, const VRegister& vn);
2526
2527 // FP convert to unsigned integer, round towards -infinity.
2528 void fcvtmu(const VRegister& vd, const VRegister& vn);
2529
2530 // FP convert to signed integer, nearest with ties to even.
2531 void fcvtns(const Register& rd, const VRegister& vn);
2532
2533 // FP convert to unsigned integer, nearest with ties to even.
2534 void fcvtnu(const Register& rd, const VRegister& vn);
2535
2536 // FP convert to signed integer, nearest with ties to even.
2537 void fcvtns(const VRegister& rd, const VRegister& vn);
2538
2539 // FP convert to unsigned integer, nearest with ties to even.
2540 void fcvtnu(const VRegister& rd, const VRegister& vn);
2541
2542 // FP convert to signed integer or fixed-point, round towards zero.
2543 void fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0);
2544
2545 // FP convert to unsigned integer or fixed-point, round towards zero.
2546 void fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0);
2547
2548 // FP convert to signed integer or fixed-point, round towards zero.
2549 void fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0);
2550
2551 // FP convert to unsigned integer or fixed-point, round towards zero.
2552 void fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0);
2553
2554 // FP convert to signed integer, round towards +infinity.
2555 void fcvtps(const Register& rd, const VRegister& vn);
2556
2557 // FP convert to unsigned integer, round towards +infinity.
2558 void fcvtpu(const Register& rd, const VRegister& vn);
2559
2560 // FP convert to signed integer, round towards +infinity.
2561 void fcvtps(const VRegister& vd, const VRegister& vn);
2562
2563 // FP convert to unsigned integer, round towards +infinity.
2564 void fcvtpu(const VRegister& vd, const VRegister& vn);
1646 2565
1647 // Convert signed integer or fixed point to FP. 2566 // Convert signed integer or fixed point to FP.
1648 void scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 2567 void scvtf(const VRegister& fd, const Register& rn, int fbits = 0);
1649 2568
1650 // Convert unsigned integer or fixed point to FP. 2569 // Convert unsigned integer or fixed point to FP.
1651 void ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 2570 void ucvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2571
2572 // Convert signed integer or fixed-point to FP.
2573 void scvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2574
2575 // Convert unsigned integer or fixed-point to FP.
2576 void ucvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2577
2578 // Extract vector from pair of vectors.
2579 void ext(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2580 int index);
2581
2582 // Duplicate vector element to vector or scalar.
2583 void dup(const VRegister& vd, const VRegister& vn, int vn_index);
2584
2585 // Duplicate general-purpose register to vector.
2586 void dup(const VRegister& vd, const Register& rn);
2587
2588 // Insert vector element from general-purpose register.
2589 void ins(const VRegister& vd, int vd_index, const Register& rn);
2590
2591 // Move general-purpose register to a vector element.
2592 void mov(const VRegister& vd, int vd_index, const Register& rn);
2593
2594 // Unsigned move vector element to general-purpose register.
2595 void umov(const Register& rd, const VRegister& vn, int vn_index);
2596
2597 // Move vector element to general-purpose register.
2598 void mov(const Register& rd, const VRegister& vn, int vn_index);
2599
2600 // Move vector element to scalar.
2601 void mov(const VRegister& vd, const VRegister& vn, int vn_index);
2602
2603 // Insert vector element from another vector element.
2604 void ins(const VRegister& vd, int vd_index, const VRegister& vn,
2605 int vn_index);
2606
2607 // Move vector element to another vector element.
2608 void mov(const VRegister& vd, int vd_index, const VRegister& vn,
2609 int vn_index);
2610
2611 // Signed move vector element to general-purpose register.
2612 void smov(const Register& rd, const VRegister& vn, int vn_index);
2613
2614 // One-element structure load to one register.
2615 void ld1(const VRegister& vt, const MemOperand& src);
2616
2617 // One-element structure load to two registers.
2618 void ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2619
2620 // One-element structure load to three registers.
2621 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2622 const MemOperand& src);
2623
2624 // One-element structure load to four registers.
2625 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2626 const VRegister& vt4, const MemOperand& src);
2627
2628 // One-element single structure load to one lane.
2629 void ld1(const VRegister& vt, int lane, const MemOperand& src);
2630
2631 // One-element single structure load to all lanes.
2632 void ld1r(const VRegister& vt, const MemOperand& src);
2633
2634 // Two-element structure load.
2635 void ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2636
2637 // Two-element single structure load to one lane.
2638 void ld2(const VRegister& vt, const VRegister& vt2, int lane,
2639 const MemOperand& src);
2640
2641 // Two-element single structure load to all lanes.
2642 void ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2643
2644 // Three-element structure load.
2645 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2646 const MemOperand& src);
2647
2648 // Three-element single structure load to one lane.
2649 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2650 int lane, const MemOperand& src);
2651
2652 // Three-element single structure load to all lanes.
2653 void ld3r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2654 const MemOperand& src);
2655
2656 // Four-element structure load.
2657 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2658 const VRegister& vt4, const MemOperand& src);
2659
2660 // Four-element single structure load to one lane.
2661 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2662 const VRegister& vt4, int lane, const MemOperand& src);
2663
2664 // Four-element single structure load to all lanes.
2665 void ld4r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2666 const VRegister& vt4, const MemOperand& src);
2667
2668 // Count leading sign bits.
2669 void cls(const VRegister& vd, const VRegister& vn);
2670
2671 // Count leading zero bits (vector).
2672 void clz(const VRegister& vd, const VRegister& vn);
2673
2674 // Population count per byte.
2675 void cnt(const VRegister& vd, const VRegister& vn);
2676
2677 // Reverse bit order.
2678 void rbit(const VRegister& vd, const VRegister& vn);
2679
2680 // Reverse elements in 16-bit halfwords.
2681 void rev16(const VRegister& vd, const VRegister& vn);
2682
2683 // Reverse elements in 32-bit words.
2684 void rev32(const VRegister& vd, const VRegister& vn);
2685
2686 // Reverse elements in 64-bit doublewords.
2687 void rev64(const VRegister& vd, const VRegister& vn);
2688
2689 // Unsigned reciprocal square root estimate.
2690 void ursqrte(const VRegister& vd, const VRegister& vn);
2691
2692 // Unsigned reciprocal estimate.
2693 void urecpe(const VRegister& vd, const VRegister& vn);
2694
2695 // Signed pairwise long add and accumulate.
2696 void sadalp(const VRegister& vd, const VRegister& vn);
2697
2698 // Signed pairwise long add.
2699 void saddlp(const VRegister& vd, const VRegister& vn);
2700
2701 // Unsigned pairwise long add.
2702 void uaddlp(const VRegister& vd, const VRegister& vn);
2703
2704 // Unsigned pairwise long add and accumulate.
2705 void uadalp(const VRegister& vd, const VRegister& vn);
2706
2707 // Shift left by immediate.
2708 void shl(const VRegister& vd, const VRegister& vn, int shift);
2709
2710 // Signed saturating shift left by immediate.
2711 void sqshl(const VRegister& vd, const VRegister& vn, int shift);
2712
2713 // Signed saturating shift left unsigned by immediate.
2714 void sqshlu(const VRegister& vd, const VRegister& vn, int shift);
2715
2716 // Unsigned saturating shift left by immediate.
2717 void uqshl(const VRegister& vd, const VRegister& vn, int shift);
2718
2719 // Signed shift left long by immediate.
2720 void sshll(const VRegister& vd, const VRegister& vn, int shift);
2721
2722 // Signed shift left long by immediate (second part).
2723 void sshll2(const VRegister& vd, const VRegister& vn, int shift);
2724
2725 // Signed extend long.
2726 void sxtl(const VRegister& vd, const VRegister& vn);
2727
2728 // Signed extend long (second part).
2729 void sxtl2(const VRegister& vd, const VRegister& vn);
2730
2731 // Unsigned shift left long by immediate.
2732 void ushll(const VRegister& vd, const VRegister& vn, int shift);
2733
2734 // Unsigned shift left long by immediate (second part).
2735 void ushll2(const VRegister& vd, const VRegister& vn, int shift);
2736
2737 // Shift left long by element size.
2738 void shll(const VRegister& vd, const VRegister& vn, int shift);
2739
2740 // Shift left long by element size (second part).
2741 void shll2(const VRegister& vd, const VRegister& vn, int shift);
2742
2743 // Unsigned extend long.
2744 void uxtl(const VRegister& vd, const VRegister& vn);
2745
2746 // Unsigned extend long (second part).
2747 void uxtl2(const VRegister& vd, const VRegister& vn);
2748
2749 // Signed rounding halving add.
2750 void srhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2751
2752 // Unsigned halving sub.
2753 void uhsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2754
2755 // Signed halving sub.
2756 void shsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2757
2758 // Unsigned saturating add.
2759 void uqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2760
2761 // Signed saturating add.
2762 void sqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2763
2764 // Unsigned saturating subtract.
2765 void uqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2766
2767 // Signed saturating subtract.
2768 void sqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2769
2770 // Add pairwise.
2771 void addp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2772
2773 // Add pair of elements scalar.
2774 void addp(const VRegister& vd, const VRegister& vn);
2775
2776 // Multiply-add to accumulator.
2777 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2778
2779 // Multiply-subtract to accumulator.
2780 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2781
2782 // Multiply.
2783 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2784
2785 // Table lookup from one register.
2786 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2787
2788 // Table lookup from two registers.
2789 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2790 const VRegister& vm);
2791
2792 // Table lookup from three registers.
2793 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2794 const VRegister& vn3, const VRegister& vm);
2795
2796 // Table lookup from four registers.
2797 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2798 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
2799
2800 // Table lookup extension from one register.
2801 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2802
2803 // Table lookup extension from two registers.
2804 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2805 const VRegister& vm);
2806
2807 // Table lookup extension from three registers.
2808 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2809 const VRegister& vn3, const VRegister& vm);
2810
2811 // Table lookup extension from four registers.
2812 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2813 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
1652 2814
1653 // Instruction functions used only for test, debug, and patching. 2815 // Instruction functions used only for test, debug, and patching.
1654 // Emit raw instructions in the instruction stream. 2816 // Emit raw instructions in the instruction stream.
1655 void dci(Instr raw_inst) { Emit(raw_inst); } 2817 void dci(Instr raw_inst) { Emit(raw_inst); }
1656 2818
1657 // Emit 8 bits of data in the instruction stream. 2819 // Emit 8 bits of data in the instruction stream.
1658 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); } 2820 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); }
1659 2821
1660 // Emit 32 bits of data in the instruction stream. 2822 // Emit 32 bits of data in the instruction stream.
1661 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); } 2823 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); }
(...skipping 29 matching lines...) Expand all
1691 Instruction* InstructionAt(ptrdiff_t offset) const { 2853 Instruction* InstructionAt(ptrdiff_t offset) const {
1692 return reinterpret_cast<Instruction*>(buffer_ + offset); 2854 return reinterpret_cast<Instruction*>(buffer_ + offset);
1693 } 2855 }
1694 2856
1695 ptrdiff_t InstructionOffset(Instruction* instr) const { 2857 ptrdiff_t InstructionOffset(Instruction* instr) const {
1696 return reinterpret_cast<byte*>(instr) - buffer_; 2858 return reinterpret_cast<byte*>(instr) - buffer_;
1697 } 2859 }
1698 2860
1699 // Register encoding. 2861 // Register encoding.
1700 static Instr Rd(CPURegister rd) { 2862 static Instr Rd(CPURegister rd) {
1701 DCHECK(rd.code() != kSPRegInternalCode); 2863 DCHECK_NE(rd.code(), kSPRegInternalCode);
1702 return rd.code() << Rd_offset; 2864 return rd.code() << Rd_offset;
1703 } 2865 }
1704 2866
1705 static Instr Rn(CPURegister rn) { 2867 static Instr Rn(CPURegister rn) {
1706 DCHECK(rn.code() != kSPRegInternalCode); 2868 DCHECK_NE(rn.code(), kSPRegInternalCode);
1707 return rn.code() << Rn_offset; 2869 return rn.code() << Rn_offset;
1708 } 2870 }
1709 2871
1710 static Instr Rm(CPURegister rm) { 2872 static Instr Rm(CPURegister rm) {
1711 DCHECK(rm.code() != kSPRegInternalCode); 2873 DCHECK_NE(rm.code(), kSPRegInternalCode);
1712 return rm.code() << Rm_offset; 2874 return rm.code() << Rm_offset;
1713 } 2875 }
1714 2876
2877 static Instr RmNot31(CPURegister rm) {
2878 DCHECK_NE(rm.code(), kSPRegInternalCode);
2879 DCHECK(!rm.IsZero());
2880 return Rm(rm);
2881 }
2882
1715 static Instr Ra(CPURegister ra) { 2883 static Instr Ra(CPURegister ra) {
1716 DCHECK(ra.code() != kSPRegInternalCode); 2884 DCHECK_NE(ra.code(), kSPRegInternalCode);
1717 return ra.code() << Ra_offset; 2885 return ra.code() << Ra_offset;
1718 } 2886 }
1719 2887
1720 static Instr Rt(CPURegister rt) { 2888 static Instr Rt(CPURegister rt) {
1721 DCHECK(rt.code() != kSPRegInternalCode); 2889 DCHECK_NE(rt.code(), kSPRegInternalCode);
1722 return rt.code() << Rt_offset; 2890 return rt.code() << Rt_offset;
1723 } 2891 }
1724 2892
1725 static Instr Rt2(CPURegister rt2) { 2893 static Instr Rt2(CPURegister rt2) {
1726 DCHECK(rt2.code() != kSPRegInternalCode); 2894 DCHECK_NE(rt2.code(), kSPRegInternalCode);
1727 return rt2.code() << Rt2_offset; 2895 return rt2.code() << Rt2_offset;
1728 } 2896 }
1729 2897
1730 static Instr Rs(CPURegister rs) { 2898 static Instr Rs(CPURegister rs) {
1731 DCHECK(rs.code() != kSPRegInternalCode); 2899 DCHECK_NE(rs.code(), kSPRegInternalCode);
1732 return rs.code() << Rs_offset; 2900 return rs.code() << Rs_offset;
1733 } 2901 }
1734 2902
1735 // These encoding functions allow the stack pointer to be encoded, and 2903 // These encoding functions allow the stack pointer to be encoded, and
1736 // disallow the zero register. 2904 // disallow the zero register.
1737 static Instr RdSP(Register rd) { 2905 static Instr RdSP(Register rd) {
1738 DCHECK(!rd.IsZero()); 2906 DCHECK(!rd.IsZero());
1739 return (rd.code() & kRegCodeMask) << Rd_offset; 2907 return (rd.code() & kRegCodeMask) << Rd_offset;
1740 } 2908 }
1741 2909
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 static bool IsImmAddSub(int64_t immediate); 2945 static bool IsImmAddSub(int64_t immediate);
1778 static bool IsImmLogical(uint64_t value, 2946 static bool IsImmLogical(uint64_t value,
1779 unsigned width, 2947 unsigned width,
1780 unsigned* n, 2948 unsigned* n,
1781 unsigned* imm_s, 2949 unsigned* imm_s,
1782 unsigned* imm_r); 2950 unsigned* imm_r);
1783 2951
1784 // MemOperand offset encoding. 2952 // MemOperand offset encoding.
1785 inline static Instr ImmLSUnsigned(int imm12); 2953 inline static Instr ImmLSUnsigned(int imm12);
1786 inline static Instr ImmLS(int imm9); 2954 inline static Instr ImmLS(int imm9);
1787 inline static Instr ImmLSPair(int imm7, LSDataSize size); 2955 inline static Instr ImmLSPair(int imm7, unsigned size);
1788 inline static Instr ImmShiftLS(unsigned shift_amount); 2956 inline static Instr ImmShiftLS(unsigned shift_amount);
1789 inline static Instr ImmException(int imm16); 2957 inline static Instr ImmException(int imm16);
1790 inline static Instr ImmSystemRegister(int imm15); 2958 inline static Instr ImmSystemRegister(int imm15);
1791 inline static Instr ImmHint(int imm7); 2959 inline static Instr ImmHint(int imm7);
1792 inline static Instr ImmBarrierDomain(int imm2); 2960 inline static Instr ImmBarrierDomain(int imm2);
1793 inline static Instr ImmBarrierType(int imm2); 2961 inline static Instr ImmBarrierType(int imm2);
1794 inline static LSDataSize CalcLSDataSize(LoadStoreOp op); 2962 inline static unsigned CalcLSDataSize(LoadStoreOp op);
2963
2964 // Instruction bits for vector format in data processing operations.
2965 static Instr VFormat(VRegister vd) {
2966 if (vd.Is64Bits()) {
2967 switch (vd.LaneCount()) {
2968 case 2:
2969 return NEON_2S;
2970 case 4:
2971 return NEON_4H;
2972 case 8:
2973 return NEON_8B;
2974 default:
2975 UNREACHABLE();
2976 return kUnallocatedInstruction;
2977 }
2978 } else {
2979 DCHECK(vd.Is128Bits());
2980 switch (vd.LaneCount()) {
2981 case 2:
2982 return NEON_2D;
2983 case 4:
2984 return NEON_4S;
2985 case 8:
2986 return NEON_8H;
2987 case 16:
2988 return NEON_16B;
2989 default:
2990 UNREACHABLE();
2991 return kUnallocatedInstruction;
2992 }
2993 }
2994 }
2995
2996 // Instruction bits for vector format in floating point data processing
2997 // operations.
2998 static Instr FPFormat(VRegister vd) {
2999 if (vd.LaneCount() == 1) {
3000 // Floating point scalar formats.
3001 DCHECK(vd.Is32Bits() || vd.Is64Bits());
3002 return vd.Is64Bits() ? FP64 : FP32;
3003 }
3004
3005 // Two lane floating point vector formats.
3006 if (vd.LaneCount() == 2) {
3007 DCHECK(vd.Is64Bits() || vd.Is128Bits());
3008 return vd.Is128Bits() ? NEON_FP_2D : NEON_FP_2S;
3009 }
3010
3011 // Four lane floating point vector format.
3012 DCHECK((vd.LaneCount() == 4) && vd.Is128Bits());
3013 return NEON_FP_4S;
3014 }
3015
3016 // Instruction bits for vector format in load and store operations.
3017 static Instr LSVFormat(VRegister vd) {
3018 if (vd.Is64Bits()) {
3019 switch (vd.LaneCount()) {
3020 case 1:
3021 return LS_NEON_1D;
3022 case 2:
3023 return LS_NEON_2S;
3024 case 4:
3025 return LS_NEON_4H;
3026 case 8:
3027 return LS_NEON_8B;
3028 default:
3029 UNREACHABLE();
3030 return kUnallocatedInstruction;
3031 }
3032 } else {
3033 DCHECK(vd.Is128Bits());
3034 switch (vd.LaneCount()) {
3035 case 2:
3036 return LS_NEON_2D;
3037 case 4:
3038 return LS_NEON_4S;
3039 case 8:
3040 return LS_NEON_8H;
3041 case 16:
3042 return LS_NEON_16B;
3043 default:
3044 UNREACHABLE();
3045 return kUnallocatedInstruction;
3046 }
3047 }
3048 }
3049
3050 // Instruction bits for scalar format in data processing operations.
3051 static Instr SFormat(VRegister vd) {
3052 DCHECK(vd.IsScalar());
3053 switch (vd.SizeInBytes()) {
3054 case 1:
3055 return NEON_B;
3056 case 2:
3057 return NEON_H;
3058 case 4:
3059 return NEON_S;
3060 case 8:
3061 return NEON_D;
3062 default:
3063 UNREACHABLE();
3064 return kUnallocatedInstruction;
3065 }
3066 }
3067
3068 static Instr ImmNEONHLM(int index, int num_bits) {
3069 int h, l, m;
3070 if (num_bits == 3) {
3071 DCHECK(is_uint3(index));
3072 h = (index >> 2) & 1;
3073 l = (index >> 1) & 1;
3074 m = (index >> 0) & 1;
3075 } else if (num_bits == 2) {
3076 DCHECK(is_uint2(index));
3077 h = (index >> 1) & 1;
3078 l = (index >> 0) & 1;
3079 m = 0;
3080 } else {
3081 DCHECK(is_uint1(index) && (num_bits == 1));
3082 h = (index >> 0) & 1;
3083 l = 0;
3084 m = 0;
3085 }
3086 return (h << NEONH_offset) | (l << NEONL_offset) | (m << NEONM_offset);
3087 }
3088
3089 static Instr ImmNEONExt(int imm4) {
3090 DCHECK(is_uint4(imm4));
3091 return imm4 << ImmNEONExt_offset;
3092 }
3093
3094 static Instr ImmNEON5(Instr format, int index) {
3095 DCHECK(is_uint4(index));
3096 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3097 int imm5 = (index << (s + 1)) | (1 << s);
3098 return imm5 << ImmNEON5_offset;
3099 }
3100
3101 static Instr ImmNEON4(Instr format, int index) {
3102 DCHECK(is_uint4(index));
3103 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3104 int imm4 = index << s;
3105 return imm4 << ImmNEON4_offset;
3106 }
3107
3108 static Instr ImmNEONabcdefgh(int imm8) {
3109 DCHECK(is_uint8(imm8));
3110 Instr instr;
3111 instr = ((imm8 >> 5) & 7) << ImmNEONabc_offset;
3112 instr |= (imm8 & 0x1f) << ImmNEONdefgh_offset;
3113 return instr;
3114 }
3115
3116 static Instr NEONCmode(int cmode) {
3117 DCHECK(is_uint4(cmode));
3118 return cmode << NEONCmode_offset;
3119 }
3120
3121 static Instr NEONModImmOp(int op) {
3122 DCHECK(is_uint1(op));
3123 return op << NEONModImmOp_offset;
3124 }
1795 3125
1796 static bool IsImmLSUnscaled(int64_t offset); 3126 static bool IsImmLSUnscaled(int64_t offset);
1797 static bool IsImmLSScaled(int64_t offset, LSDataSize size); 3127 static bool IsImmLSScaled(int64_t offset, unsigned size);
1798 static bool IsImmLLiteral(int64_t offset); 3128 static bool IsImmLLiteral(int64_t offset);
1799 3129
1800 // Move immediates encoding. 3130 // Move immediates encoding.
1801 inline static Instr ImmMoveWide(int imm); 3131 inline static Instr ImmMoveWide(int imm);
1802 inline static Instr ShiftMoveWide(int shift); 3132 inline static Instr ShiftMoveWide(int shift);
1803 3133
1804 // FP Immediates. 3134 // FP Immediates.
1805 static Instr ImmFP32(float imm); 3135 static Instr ImmFP(double imm);
1806 static Instr ImmFP64(double imm); 3136 static Instr ImmNEONFP(double imm);
1807 inline static Instr FPScale(unsigned scale); 3137 inline static Instr FPScale(unsigned scale);
1808 3138
1809 // FP register type. 3139 // FP register type.
1810 inline static Instr FPType(FPRegister fd); 3140 inline static Instr FPType(VRegister fd);
1811 3141
1812 // Class for scoping postponing the constant pool generation. 3142 // Class for scoping postponing the constant pool generation.
1813 class BlockConstPoolScope { 3143 class BlockConstPoolScope {
1814 public: 3144 public:
1815 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) { 3145 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1816 assem_->StartBlockConstPool(); 3146 assem_->StartBlockConstPool();
1817 } 3147 }
1818 ~BlockConstPoolScope() { 3148 ~BlockConstPoolScope() {
1819 assem_->EndBlockConstPool(); 3149 assem_->EndBlockConstPool();
1820 } 3150 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 3204
1875 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); 3205 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope);
1876 }; 3206 };
1877 3207
1878 protected: 3208 protected:
1879 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; 3209 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const;
1880 3210
1881 void LoadStore(const CPURegister& rt, 3211 void LoadStore(const CPURegister& rt,
1882 const MemOperand& addr, 3212 const MemOperand& addr,
1883 LoadStoreOp op); 3213 LoadStoreOp op);
1884
1885 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2, 3214 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2,
1886 const MemOperand& addr, LoadStorePairOp op); 3215 const MemOperand& addr, LoadStorePairOp op);
1887 static bool IsImmLSPair(int64_t offset, LSDataSize size); 3216 void LoadStoreStruct(const VRegister& vt, const MemOperand& addr,
3217 NEONLoadStoreMultiStructOp op);
3218 void LoadStoreStruct1(const VRegister& vt, int reg_count,
3219 const MemOperand& addr);
3220 void LoadStoreStructSingle(const VRegister& vt, uint32_t lane,
3221 const MemOperand& addr,
3222 NEONLoadStoreSingleStructOp op);
3223 void LoadStoreStructSingleAllLanes(const VRegister& vt,
3224 const MemOperand& addr,
3225 NEONLoadStoreSingleStructOp op);
3226 void LoadStoreStructVerify(const VRegister& vt, const MemOperand& addr,
3227 Instr op);
3228
3229 static bool IsImmLSPair(int64_t offset, unsigned size);
1888 3230
1889 void Logical(const Register& rd, 3231 void Logical(const Register& rd,
1890 const Register& rn, 3232 const Register& rn,
1891 const Operand& operand, 3233 const Operand& operand,
1892 LogicalOp op); 3234 LogicalOp op);
1893 void LogicalImmediate(const Register& rd, 3235 void LogicalImmediate(const Register& rd,
1894 const Register& rn, 3236 const Register& rn,
1895 unsigned n, 3237 unsigned n,
1896 unsigned imm_s, 3238 unsigned imm_s,
1897 unsigned imm_r, 3239 unsigned imm_r,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt); 3284 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
1943 3285
1944 // Remove the specified branch from the unbound label link chain. 3286 // Remove the specified branch from the unbound label link chain.
1945 // If available, a veneer for this label can be used for other branches in the 3287 // If available, a veneer for this label can be used for other branches in the
1946 // chain if the link chain cannot be fixed up without this branch. 3288 // chain if the link chain cannot be fixed up without this branch.
1947 void RemoveBranchFromLabelLinkChain(Instruction* branch, 3289 void RemoveBranchFromLabelLinkChain(Instruction* branch,
1948 Label* label, 3290 Label* label,
1949 Instruction* label_veneer = NULL); 3291 Instruction* label_veneer = NULL);
1950 3292
1951 private: 3293 private:
3294 static uint32_t FPToImm8(double imm);
3295
1952 // Instruction helpers. 3296 // Instruction helpers.
1953 void MoveWide(const Register& rd, 3297 void MoveWide(const Register& rd,
1954 uint64_t imm, 3298 uint64_t imm,
1955 int shift, 3299 int shift,
1956 MoveWideImmediateOp mov_op); 3300 MoveWideImmediateOp mov_op);
1957 void DataProcShiftedRegister(const Register& rd, 3301 void DataProcShiftedRegister(const Register& rd,
1958 const Register& rn, 3302 const Register& rn,
1959 const Operand& operand, 3303 const Operand& operand,
1960 FlagsUpdate S, 3304 FlagsUpdate S,
1961 Instr op); 3305 Instr op);
1962 void DataProcExtendedRegister(const Register& rd, 3306 void DataProcExtendedRegister(const Register& rd,
1963 const Register& rn, 3307 const Register& rn,
1964 const Operand& operand, 3308 const Operand& operand,
1965 FlagsUpdate S, 3309 FlagsUpdate S,
1966 Instr op); 3310 Instr op);
1967 void ConditionalSelect(const Register& rd, 3311 void ConditionalSelect(const Register& rd,
1968 const Register& rn, 3312 const Register& rn,
1969 const Register& rm, 3313 const Register& rm,
1970 Condition cond, 3314 Condition cond,
1971 ConditionalSelectOp op); 3315 ConditionalSelectOp op);
1972 void DataProcessing1Source(const Register& rd, 3316 void DataProcessing1Source(const Register& rd,
1973 const Register& rn, 3317 const Register& rn,
1974 DataProcessing1SourceOp op); 3318 DataProcessing1SourceOp op);
1975 void DataProcessing3Source(const Register& rd, 3319 void DataProcessing3Source(const Register& rd,
1976 const Register& rn, 3320 const Register& rn,
1977 const Register& rm, 3321 const Register& rm,
1978 const Register& ra, 3322 const Register& ra,
1979 DataProcessing3SourceOp op); 3323 DataProcessing3SourceOp op);
1980 void FPDataProcessing1Source(const FPRegister& fd, 3324 void FPDataProcessing1Source(const VRegister& fd, const VRegister& fn,
1981 const FPRegister& fn,
1982 FPDataProcessing1SourceOp op); 3325 FPDataProcessing1SourceOp op);
1983 void FPDataProcessing2Source(const FPRegister& fd, 3326 void FPDataProcessing2Source(const VRegister& fd, const VRegister& fn,
1984 const FPRegister& fn, 3327 const VRegister& fm,
1985 const FPRegister& fm,
1986 FPDataProcessing2SourceOp op); 3328 FPDataProcessing2SourceOp op);
1987 void FPDataProcessing3Source(const FPRegister& fd, 3329 void FPDataProcessing3Source(const VRegister& fd, const VRegister& fn,
1988 const FPRegister& fn, 3330 const VRegister& fm, const VRegister& fa,
1989 const FPRegister& fm,
1990 const FPRegister& fa,
1991 FPDataProcessing3SourceOp op); 3331 FPDataProcessing3SourceOp op);
3332 void NEONAcrossLanesL(const VRegister& vd, const VRegister& vn,
3333 NEONAcrossLanesOp op);
3334 void NEONAcrossLanes(const VRegister& vd, const VRegister& vn,
3335 NEONAcrossLanesOp op);
3336 void NEONModifiedImmShiftLsl(const VRegister& vd, const int imm8,
3337 const int left_shift,
3338 NEONModifiedImmediateOp op);
3339 void NEONModifiedImmShiftMsl(const VRegister& vd, const int imm8,
3340 const int shift_amount,
3341 NEONModifiedImmediateOp op);
3342 void NEON3Same(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3343 NEON3SameOp vop);
3344 void NEONFP3Same(const VRegister& vd, const VRegister& vn,
3345 const VRegister& vm, Instr op);
3346 void NEON3DifferentL(const VRegister& vd, const VRegister& vn,
3347 const VRegister& vm, NEON3DifferentOp vop);
3348 void NEON3DifferentW(const VRegister& vd, const VRegister& vn,
3349 const VRegister& vm, NEON3DifferentOp vop);
3350 void NEON3DifferentHN(const VRegister& vd, const VRegister& vn,
3351 const VRegister& vm, NEON3DifferentOp vop);
3352 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn,
3353 NEON2RegMiscOp vop, double value = 0.0);
3354 void NEON2RegMisc(const VRegister& vd, const VRegister& vn,
3355 NEON2RegMiscOp vop, int value = 0);
3356 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn, Instr op);
3357 void NEONAddlp(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp op);
3358 void NEONPerm(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3359 NEONPermOp op);
3360 void NEONFPByElement(const VRegister& vd, const VRegister& vn,
3361 const VRegister& vm, int vm_index,
3362 NEONByIndexedElementOp op);
3363 void NEONByElement(const VRegister& vd, const VRegister& vn,
3364 const VRegister& vm, int vm_index,
3365 NEONByIndexedElementOp op);
3366 void NEONByElementL(const VRegister& vd, const VRegister& vn,
3367 const VRegister& vm, int vm_index,
3368 NEONByIndexedElementOp op);
3369 void NEONShiftImmediate(const VRegister& vd, const VRegister& vn,
3370 NEONShiftImmediateOp op, int immh_immb);
3371 void NEONShiftLeftImmediate(const VRegister& vd, const VRegister& vn,
3372 int shift, NEONShiftImmediateOp op);
3373 void NEONShiftRightImmediate(const VRegister& vd, const VRegister& vn,
3374 int shift, NEONShiftImmediateOp op);
3375 void NEONShiftImmediateL(const VRegister& vd, const VRegister& vn, int shift,
3376 NEONShiftImmediateOp op);
3377 void NEONShiftImmediateN(const VRegister& vd, const VRegister& vn, int shift,
3378 NEONShiftImmediateOp op);
3379 void NEONXtn(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp vop);
3380 void NEONTable(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3381 NEONTableOp op);
3382
3383 Instr LoadStoreStructAddrModeField(const MemOperand& addr);
1992 3384
1993 // Label helpers. 3385 // Label helpers.
1994 3386
1995 // Return an offset for a label-referencing instruction, typically a branch. 3387 // Return an offset for a label-referencing instruction, typically a branch.
1996 int LinkAndGetByteOffsetTo(Label* label); 3388 int LinkAndGetByteOffsetTo(Label* label);
1997 3389
1998 // This is the same as LinkAndGetByteOffsetTo, but return an offset 3390 // This is the same as LinkAndGetByteOffsetTo, but return an offset
1999 // suitable for fields that take instruction offsets. 3391 // suitable for fields that take instruction offsets.
2000 inline int LinkAndGetInstructionOffsetTo(Label* label); 3392 inline int LinkAndGetInstructionOffsetTo(Label* label);
2001 3393
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 public: 3622 public:
2231 explicit EnsureSpace(Assembler* assembler) { 3623 explicit EnsureSpace(Assembler* assembler) {
2232 assembler->CheckBufferSpace(); 3624 assembler->CheckBufferSpace();
2233 } 3625 }
2234 }; 3626 };
2235 3627
2236 } // namespace internal 3628 } // namespace internal
2237 } // namespace v8 3629 } // namespace v8
2238 3630
2239 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ 3631 #endif // V8_ARM64_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/arm64/assembler-arm64.cc » ('j') | src/arm64/constants-arm64.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698