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

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

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

Powered by Google App Engine
This is Rietveld 408576698