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

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

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

Powered by Google App Engine
This is Rietveld 408576698