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

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

Issue 2812573003: Reland "ARM64: Add NEON support" (Closed)
Patch Set: Add trace directory to gitignore Created 3 years, 8 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 | « DEPS ('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 return false; 624 return false;
488 } 625 }
489 } 626 }
490 }; 627 };
491 628
492 629
493 // AAPCS64 callee-saved registers. 630 // AAPCS64 callee-saved registers.
494 #define kCalleeSaved CPURegList::GetCalleeSaved() 631 #define kCalleeSaved CPURegList::GetCalleeSaved()
495 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() 632 #define kCalleeSavedV CPURegList::GetCalleeSavedV()
496
497 633
498 // AAPCS64 caller-saved registers. Note that this includes lr. 634 // AAPCS64 caller-saved registers. Note that this includes lr.
499 #define kCallerSaved CPURegList::GetCallerSaved() 635 #define kCallerSaved CPURegList::GetCallerSaved()
500 #define kCallerSavedFP CPURegList::GetCallerSavedFP() 636 #define kCallerSavedV CPURegList::GetCallerSavedV()
501 637
502 // ----------------------------------------------------------------------------- 638 // -----------------------------------------------------------------------------
503 // Immediates. 639 // Immediates.
504 class Immediate { 640 class Immediate {
505 public: 641 public:
506 template<typename T> 642 template<typename T>
507 inline explicit Immediate(Handle<T> handle); 643 inline explicit Immediate(Handle<T> handle);
508 644
509 // This is allowed to be an implicit constructor because Immediate is 645 // This is allowed to be an implicit constructor because Immediate is
510 // a wrapper class that doesn't normally perform any type conversion. 646 // a wrapper class that doesn't normally perform any type conversion.
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 // Bit clear (A & ~B). 1193 // Bit clear (A & ~B).
1058 void bic(const Register& rd, 1194 void bic(const Register& rd,
1059 const Register& rn, 1195 const Register& rn,
1060 const Operand& operand); 1196 const Operand& operand);
1061 1197
1062 // Bit clear (A & ~B) and update status flags. 1198 // Bit clear (A & ~B) and update status flags.
1063 void bics(const Register& rd, 1199 void bics(const Register& rd,
1064 const Register& rn, 1200 const Register& rn,
1065 const Operand& operand); 1201 const Operand& operand);
1066 1202
1203 // Bitwise and.
1204 void and_(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1205
1206 // Bit clear immediate.
1207 void bic(const VRegister& vd, const int imm8, const int left_shift = 0);
1208
1209 // Bit clear.
1210 void bic(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1211
1212 // Bitwise insert if false.
1213 void bif(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1214
1215 // Bitwise insert if true.
1216 void bit(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1217
1218 // Bitwise select.
1219 void bsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1220
1221 // Polynomial multiply.
1222 void pmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1223
1224 // Vector move immediate.
1225 void movi(const VRegister& vd, const uint64_t imm, Shift shift = LSL,
1226 const int shift_amount = 0);
1227
1228 // Bitwise not.
1229 void mvn(const VRegister& vd, const VRegister& vn);
1230
1231 // Vector move inverted immediate.
1232 void mvni(const VRegister& vd, const int imm8, Shift shift = LSL,
1233 const int shift_amount = 0);
1234
1235 // Signed saturating accumulate of unsigned value.
1236 void suqadd(const VRegister& vd, const VRegister& vn);
1237
1238 // Unsigned saturating accumulate of signed value.
1239 void usqadd(const VRegister& vd, const VRegister& vn);
1240
1241 // Absolute value.
1242 void abs(const VRegister& vd, const VRegister& vn);
1243
1244 // Signed saturating absolute value.
1245 void sqabs(const VRegister& vd, const VRegister& vn);
1246
1247 // Negate.
1248 void neg(const VRegister& vd, const VRegister& vn);
1249
1250 // Signed saturating negate.
1251 void sqneg(const VRegister& vd, const VRegister& vn);
1252
1253 // Bitwise not.
1254 void not_(const VRegister& vd, const VRegister& vn);
1255
1256 // Extract narrow.
1257 void xtn(const VRegister& vd, const VRegister& vn);
1258
1259 // Extract narrow (second part).
1260 void xtn2(const VRegister& vd, const VRegister& vn);
1261
1262 // Signed saturating extract narrow.
1263 void sqxtn(const VRegister& vd, const VRegister& vn);
1264
1265 // Signed saturating extract narrow (second part).
1266 void sqxtn2(const VRegister& vd, const VRegister& vn);
1267
1268 // Unsigned saturating extract narrow.
1269 void uqxtn(const VRegister& vd, const VRegister& vn);
1270
1271 // Unsigned saturating extract narrow (second part).
1272 void uqxtn2(const VRegister& vd, const VRegister& vn);
1273
1274 // Signed saturating extract unsigned narrow.
1275 void sqxtun(const VRegister& vd, const VRegister& vn);
1276
1277 // Signed saturating extract unsigned narrow (second part).
1278 void sqxtun2(const VRegister& vd, const VRegister& vn);
1279
1280 // Move register to register.
1281 void mov(const VRegister& vd, const VRegister& vn);
1282
1283 // Bitwise not or.
1284 void orn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1285
1286 // Bitwise exclusive or.
1287 void eor(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1288
1067 // Bitwise or (A | B). 1289 // Bitwise or (A | B).
1068 void orr(const Register& rd, const Register& rn, const Operand& operand); 1290 void orr(const Register& rd, const Register& rn, const Operand& operand);
1069 1291
1292 // Bitwise or.
1293 void orr(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1294
1295 // Bitwise or immediate.
1296 void orr(const VRegister& vd, const int imm8, const int left_shift = 0);
1297
1070 // Bitwise nor (A | ~B). 1298 // Bitwise nor (A | ~B).
1071 void orn(const Register& rd, const Register& rn, const Operand& operand); 1299 void orn(const Register& rd, const Register& rn, const Operand& operand);
1072 1300
1073 // Bitwise eor/xor (A ^ B). 1301 // Bitwise eor/xor (A ^ B).
1074 void eor(const Register& rd, const Register& rn, const Operand& operand); 1302 void eor(const Register& rd, const Register& rn, const Operand& operand);
1075 1303
1076 // Bitwise enor/xnor (A ^ ~B). 1304 // Bitwise enor/xnor (A ^ ~B).
1077 void eon(const Register& rd, const Register& rn, const Operand& operand); 1305 void eon(const Register& rd, const Register& rn, const Operand& operand);
1078 1306
1079 // Logical shift left variable. 1307 // Logical shift left variable.
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 ADR_FAR_NOP, 1694 ADR_FAR_NOP,
1467 FIRST_NOP_MARKER = DEBUG_BREAK_NOP, 1695 FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
1468 LAST_NOP_MARKER = ADR_FAR_NOP 1696 LAST_NOP_MARKER = ADR_FAR_NOP
1469 }; 1697 };
1470 1698
1471 void nop(NopMarkerTypes n) { 1699 void nop(NopMarkerTypes n) {
1472 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER)); 1700 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER));
1473 mov(Register::XRegFromCode(n), Register::XRegFromCode(n)); 1701 mov(Register::XRegFromCode(n), Register::XRegFromCode(n));
1474 } 1702 }
1475 1703
1704 // Add.
1705 void add(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1706
1707 // Unsigned halving add.
1708 void uhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1709
1710 // Subtract.
1711 void sub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1712
1713 // Signed halving add.
1714 void shadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1715
1716 // Multiply by scalar element.
1717 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1718 int vm_index);
1719
1720 // Multiply-add by scalar element.
1721 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1722 int vm_index);
1723
1724 // Multiply-subtract by scalar element.
1725 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1726 int vm_index);
1727
1728 // Signed long multiply-add by scalar element.
1729 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1730 int vm_index);
1731
1732 // Signed long multiply-add by scalar element (second part).
1733 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1734 int vm_index);
1735
1736 // Unsigned long multiply-add by scalar element.
1737 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1738 int vm_index);
1739
1740 // Unsigned long multiply-add by scalar element (second part).
1741 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1742 int vm_index);
1743
1744 // Signed long multiply-sub by scalar element.
1745 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1746 int vm_index);
1747
1748 // Signed long multiply-sub by scalar element (second part).
1749 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1750 int vm_index);
1751
1752 // Unsigned long multiply-sub by scalar element.
1753 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1754 int vm_index);
1755
1756 // Unsigned long multiply-sub by scalar element (second part).
1757 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1758 int vm_index);
1759
1760 // Signed long multiply by scalar element.
1761 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1762 int vm_index);
1763
1764 // Signed long multiply by scalar element (second part).
1765 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1766 int vm_index);
1767
1768 // Unsigned long multiply by scalar element.
1769 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1770 int vm_index);
1771
1772 // Unsigned long multiply by scalar element (second part).
1773 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1774 int vm_index);
1775
1776 // Add narrow returning high half.
1777 void addhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1778
1779 // Add narrow returning high half (second part).
1780 void addhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1781
1782 // Signed saturating double long multiply by element.
1783 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1784 int vm_index);
1785
1786 // Signed saturating double long multiply by element (second part).
1787 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1788 int vm_index);
1789
1790 // Signed saturating doubling long multiply-add by element.
1791 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1792 int vm_index);
1793
1794 // Signed saturating doubling long multiply-add by element (second part).
1795 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1796 int vm_index);
1797
1798 // Signed saturating doubling long multiply-sub by element.
1799 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1800 int vm_index);
1801
1802 // Signed saturating doubling long multiply-sub by element (second part).
1803 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1804 int vm_index);
1805
1806 // Compare bitwise to zero.
1807 void cmeq(const VRegister& vd, const VRegister& vn, int value);
1808
1809 // Compare signed greater than or equal to zero.
1810 void cmge(const VRegister& vd, const VRegister& vn, int value);
1811
1812 // Compare signed greater than zero.
1813 void cmgt(const VRegister& vd, const VRegister& vn, int value);
1814
1815 // Compare signed less than or equal to zero.
1816 void cmle(const VRegister& vd, const VRegister& vn, int value);
1817
1818 // Compare signed less than zero.
1819 void cmlt(const VRegister& vd, const VRegister& vn, int value);
1820
1821 // Unsigned rounding halving add.
1822 void urhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1823
1824 // Compare equal.
1825 void cmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1826
1827 // Compare signed greater than or equal.
1828 void cmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1829
1830 // Compare signed greater than.
1831 void cmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1832
1833 // Compare unsigned higher.
1834 void cmhi(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1835
1836 // Compare unsigned higher or same.
1837 void cmhs(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1838
1839 // Compare bitwise test bits nonzero.
1840 void cmtst(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1841
1842 // Signed shift left by register.
1843 void sshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1844
1845 // Unsigned shift left by register.
1846 void ushl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1847
1848 // Signed saturating doubling long multiply-subtract.
1849 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1850
1851 // Signed saturating doubling long multiply-subtract (second part).
1852 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1853
1854 // Signed saturating doubling long multiply.
1855 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1856
1857 // Signed saturating doubling long multiply (second part).
1858 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1859
1860 // Signed saturating doubling multiply returning high half.
1861 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1862
1863 // Signed saturating rounding doubling multiply returning high half.
1864 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1865
1866 // Signed saturating doubling multiply element returning high half.
1867 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1868 int vm_index);
1869
1870 // Signed saturating rounding doubling multiply element returning high half.
1871 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1872 int vm_index);
1873
1874 // Unsigned long multiply long.
1875 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1876
1877 // Unsigned long multiply (second part).
1878 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1879
1880 // Rounding add narrow returning high half.
1881 void raddhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1882
1883 // Subtract narrow returning high half.
1884 void subhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1885
1886 // Subtract narrow returning high half (second part).
1887 void subhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1888
1889 // Rounding add narrow returning high half (second part).
1890 void raddhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1891
1892 // Rounding subtract narrow returning high half.
1893 void rsubhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1894
1895 // Rounding subtract narrow returning high half (second part).
1896 void rsubhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1897
1898 // Signed saturating shift left by register.
1899 void sqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1900
1901 // Unsigned saturating shift left by register.
1902 void uqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1903
1904 // Signed rounding shift left by register.
1905 void srshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1906
1907 // Unsigned rounding shift left by register.
1908 void urshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1909
1910 // Signed saturating rounding shift left by register.
1911 void sqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1912
1913 // Unsigned saturating rounding shift left by register.
1914 void uqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1915
1916 // Signed absolute difference.
1917 void sabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1918
1919 // Unsigned absolute difference and accumulate.
1920 void uaba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1921
1922 // Shift left by immediate and insert.
1923 void sli(const VRegister& vd, const VRegister& vn, int shift);
1924
1925 // Shift right by immediate and insert.
1926 void sri(const VRegister& vd, const VRegister& vn, int shift);
1927
1928 // Signed maximum.
1929 void smax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1930
1931 // Signed pairwise maximum.
1932 void smaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1933
1934 // Add across vector.
1935 void addv(const VRegister& vd, const VRegister& vn);
1936
1937 // Signed add long across vector.
1938 void saddlv(const VRegister& vd, const VRegister& vn);
1939
1940 // Unsigned add long across vector.
1941 void uaddlv(const VRegister& vd, const VRegister& vn);
1942
1943 // FP maximum number across vector.
1944 void fmaxnmv(const VRegister& vd, const VRegister& vn);
1945
1946 // FP maximum across vector.
1947 void fmaxv(const VRegister& vd, const VRegister& vn);
1948
1949 // FP minimum number across vector.
1950 void fminnmv(const VRegister& vd, const VRegister& vn);
1951
1952 // FP minimum across vector.
1953 void fminv(const VRegister& vd, const VRegister& vn);
1954
1955 // Signed maximum across vector.
1956 void smaxv(const VRegister& vd, const VRegister& vn);
1957
1958 // Signed minimum.
1959 void smin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1960
1961 // Signed minimum pairwise.
1962 void sminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1963
1964 // Signed minimum across vector.
1965 void sminv(const VRegister& vd, const VRegister& vn);
1966
1967 // One-element structure store from one register.
1968 void st1(const VRegister& vt, const MemOperand& src);
1969
1970 // One-element structure store from two registers.
1971 void st1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
1972
1973 // One-element structure store from three registers.
1974 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1975 const MemOperand& src);
1976
1977 // One-element structure store from four registers.
1978 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1979 const VRegister& vt4, const MemOperand& src);
1980
1981 // One-element single structure store from one lane.
1982 void st1(const VRegister& vt, int lane, const MemOperand& src);
1983
1984 // Two-element structure store from two registers.
1985 void st2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
1986
1987 // Two-element single structure store from two lanes.
1988 void st2(const VRegister& vt, const VRegister& vt2, int lane,
1989 const MemOperand& src);
1990
1991 // Three-element structure store from three registers.
1992 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1993 const MemOperand& src);
1994
1995 // Three-element single structure store from three lanes.
1996 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1997 int lane, const MemOperand& src);
1998
1999 // Four-element structure store from four registers.
2000 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2001 const VRegister& vt4, const MemOperand& src);
2002
2003 // Four-element single structure store from four lanes.
2004 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2005 const VRegister& vt4, int lane, const MemOperand& src);
2006
2007 // Unsigned add long.
2008 void uaddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2009
2010 // Unsigned add long (second part).
2011 void uaddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2012
2013 // Unsigned add wide.
2014 void uaddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2015
2016 // Unsigned add wide (second part).
2017 void uaddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2018
2019 // Signed add long.
2020 void saddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2021
2022 // Signed add long (second part).
2023 void saddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2024
2025 // Signed add wide.
2026 void saddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2027
2028 // Signed add wide (second part).
2029 void saddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2030
2031 // Unsigned subtract long.
2032 void usubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2033
2034 // Unsigned subtract long (second part).
2035 void usubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2036
2037 // Unsigned subtract wide.
2038 void usubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2039
2040 // Signed subtract long.
2041 void ssubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2042
2043 // Signed subtract long (second part).
2044 void ssubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2045
2046 // Signed integer subtract wide.
2047 void ssubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2048
2049 // Signed integer subtract wide (second part).
2050 void ssubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2051
2052 // Unsigned subtract wide (second part).
2053 void usubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2054
2055 // Unsigned maximum.
2056 void umax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2057
2058 // Unsigned pairwise maximum.
2059 void umaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2060
2061 // Unsigned maximum across vector.
2062 void umaxv(const VRegister& vd, const VRegister& vn);
2063
2064 // Unsigned minimum.
2065 void umin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2066
2067 // Unsigned pairwise minimum.
2068 void uminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2069
2070 // Unsigned minimum across vector.
2071 void uminv(const VRegister& vd, const VRegister& vn);
2072
2073 // Transpose vectors (primary).
2074 void trn1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2075
2076 // Transpose vectors (secondary).
2077 void trn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2078
2079 // Unzip vectors (primary).
2080 void uzp1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2081
2082 // Unzip vectors (secondary).
2083 void uzp2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2084
2085 // Zip vectors (primary).
2086 void zip1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2087
2088 // Zip vectors (secondary).
2089 void zip2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2090
2091 // Signed shift right by immediate.
2092 void sshr(const VRegister& vd, const VRegister& vn, int shift);
2093
2094 // Unsigned shift right by immediate.
2095 void ushr(const VRegister& vd, const VRegister& vn, int shift);
2096
2097 // Signed rounding shift right by immediate.
2098 void srshr(const VRegister& vd, const VRegister& vn, int shift);
2099
2100 // Unsigned rounding shift right by immediate.
2101 void urshr(const VRegister& vd, const VRegister& vn, int shift);
2102
2103 // Signed shift right by immediate and accumulate.
2104 void ssra(const VRegister& vd, const VRegister& vn, int shift);
2105
2106 // Unsigned shift right by immediate and accumulate.
2107 void usra(const VRegister& vd, const VRegister& vn, int shift);
2108
2109 // Signed rounding shift right by immediate and accumulate.
2110 void srsra(const VRegister& vd, const VRegister& vn, int shift);
2111
2112 // Unsigned rounding shift right by immediate and accumulate.
2113 void ursra(const VRegister& vd, const VRegister& vn, int shift);
2114
2115 // Shift right narrow by immediate.
2116 void shrn(const VRegister& vd, const VRegister& vn, int shift);
2117
2118 // Shift right narrow by immediate (second part).
2119 void shrn2(const VRegister& vd, const VRegister& vn, int shift);
2120
2121 // Rounding shift right narrow by immediate.
2122 void rshrn(const VRegister& vd, const VRegister& vn, int shift);
2123
2124 // Rounding shift right narrow by immediate (second part).
2125 void rshrn2(const VRegister& vd, const VRegister& vn, int shift);
2126
2127 // Unsigned saturating shift right narrow by immediate.
2128 void uqshrn(const VRegister& vd, const VRegister& vn, int shift);
2129
2130 // Unsigned saturating shift right narrow by immediate (second part).
2131 void uqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2132
2133 // Unsigned saturating rounding shift right narrow by immediate.
2134 void uqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2135
2136 // Unsigned saturating rounding shift right narrow by immediate (second part).
2137 void uqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2138
2139 // Signed saturating shift right narrow by immediate.
2140 void sqshrn(const VRegister& vd, const VRegister& vn, int shift);
2141
2142 // Signed saturating shift right narrow by immediate (second part).
2143 void sqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2144
2145 // Signed saturating rounded shift right narrow by immediate.
2146 void sqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2147
2148 // Signed saturating rounded shift right narrow by immediate (second part).
2149 void sqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2150
2151 // Signed saturating shift right unsigned narrow by immediate.
2152 void sqshrun(const VRegister& vd, const VRegister& vn, int shift);
2153
2154 // Signed saturating shift right unsigned narrow by immediate (second part).
2155 void sqshrun2(const VRegister& vd, const VRegister& vn, int shift);
2156
2157 // Signed sat rounded shift right unsigned narrow by immediate.
2158 void sqrshrun(const VRegister& vd, const VRegister& vn, int shift);
2159
2160 // Signed sat rounded shift right unsigned narrow by immediate (second part).
2161 void sqrshrun2(const VRegister& vd, const VRegister& vn, int shift);
2162
2163 // FP reciprocal step.
2164 void frecps(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2165
2166 // FP reciprocal estimate.
2167 void frecpe(const VRegister& vd, const VRegister& vn);
2168
2169 // FP reciprocal square root estimate.
2170 void frsqrte(const VRegister& vd, const VRegister& vn);
2171
2172 // FP reciprocal square root step.
2173 void frsqrts(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2174
2175 // Signed absolute difference and accumulate long.
2176 void sabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2177
2178 // Signed absolute difference and accumulate long (second part).
2179 void sabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2180
2181 // Unsigned absolute difference and accumulate long.
2182 void uabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2183
2184 // Unsigned absolute difference and accumulate long (second part).
2185 void uabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2186
2187 // Signed absolute difference long.
2188 void sabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2189
2190 // Signed absolute difference long (second part).
2191 void sabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2192
2193 // Unsigned absolute difference long.
2194 void uabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2195
2196 // Unsigned absolute difference long (second part).
2197 void uabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2198
2199 // Polynomial multiply long.
2200 void pmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2201
2202 // Polynomial multiply long (second part).
2203 void pmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2204
2205 // Signed long multiply-add.
2206 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2207
2208 // Signed long multiply-add (second part).
2209 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2210
2211 // Unsigned long multiply-add.
2212 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2213
2214 // Unsigned long multiply-add (second part).
2215 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2216
2217 // Signed long multiply-sub.
2218 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2219
2220 // Signed long multiply-sub (second part).
2221 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2222
2223 // Unsigned long multiply-sub.
2224 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2225
2226 // Unsigned long multiply-sub (second part).
2227 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2228
2229 // Signed long multiply.
2230 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2231
2232 // Signed long multiply (second part).
2233 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2234
2235 // Signed saturating doubling long multiply-add.
2236 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2237
2238 // Signed saturating doubling long multiply-add (second part).
2239 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2240
2241 // Unsigned absolute difference.
2242 void uabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2243
2244 // Signed absolute difference and accumulate.
2245 void saba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2246
1476 // FP instructions. 2247 // FP instructions.
1477 // Move immediate to FP register. 2248 // Move immediate to FP register.
1478 void fmov(FPRegister fd, double imm); 2249 void fmov(const VRegister& fd, double imm);
1479 void fmov(FPRegister fd, float imm); 2250 void fmov(const VRegister& fd, float imm);
1480 2251
1481 // Move FP register to register. 2252 // Move FP register to register.
1482 void fmov(Register rd, FPRegister fn); 2253 void fmov(const Register& rd, const VRegister& fn);
1483 2254
1484 // Move register to FP register. 2255 // Move register to FP register.
1485 void fmov(FPRegister fd, Register rn); 2256 void fmov(const VRegister& fd, const Register& rn);
1486 2257
1487 // Move FP register to FP register. 2258 // Move FP register to FP register.
1488 void fmov(FPRegister fd, FPRegister fn); 2259 void fmov(const VRegister& fd, const VRegister& fn);
2260
2261 // Move 64-bit register to top half of 128-bit FP register.
2262 void fmov(const VRegister& vd, int index, const Register& rn);
2263
2264 // Move top half of 128-bit FP register to 64-bit register.
2265 void fmov(const Register& rd, const VRegister& vn, int index);
1489 2266
1490 // FP add. 2267 // FP add.
1491 void fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2268 void fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1492 2269
1493 // FP subtract. 2270 // FP subtract.
1494 void fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2271 void fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1495 2272
1496 // FP multiply. 2273 // FP multiply.
1497 void fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2274 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1498 2275
1499 // FP fused multiply and add. 2276 // FP compare equal to zero.
1500 void fmadd(const FPRegister& fd, 2277 void fcmeq(const VRegister& vd, const VRegister& vn, double imm);
1501 const FPRegister& fn, 2278
1502 const FPRegister& fm, 2279 // FP greater than zero.
1503 const FPRegister& fa); 2280 void fcmgt(const VRegister& vd, const VRegister& vn, double imm);
1504 2281
1505 // FP fused multiply and subtract. 2282 // FP greater than or equal to zero.
1506 void fmsub(const FPRegister& fd, 2283 void fcmge(const VRegister& vd, const VRegister& vn, double imm);
1507 const FPRegister& fn, 2284
1508 const FPRegister& fm, 2285 // FP less than or equal to zero.
1509 const FPRegister& fa); 2286 void fcmle(const VRegister& vd, const VRegister& vn, double imm);
1510 2287
1511 // FP fused multiply, add and negate. 2288 // FP less than to zero.
1512 void fnmadd(const FPRegister& fd, 2289 void fcmlt(const VRegister& vd, const VRegister& vn, double imm);
1513 const FPRegister& fn, 2290
1514 const FPRegister& fm, 2291 // FP absolute difference.
1515 const FPRegister& fa); 2292 void fabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1516 2293
1517 // FP fused multiply, subtract and negate. 2294 // FP pairwise add vector.
1518 void fnmsub(const FPRegister& fd, 2295 void faddp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1519 const FPRegister& fn, 2296
1520 const FPRegister& fm, 2297 // FP pairwise add scalar.
1521 const FPRegister& fa); 2298 void faddp(const VRegister& vd, const VRegister& vn);
2299
2300 // FP pairwise maximum scalar.
2301 void fmaxp(const VRegister& vd, const VRegister& vn);
2302
2303 // FP pairwise maximum number scalar.
2304 void fmaxnmp(const VRegister& vd, const VRegister& vn);
2305
2306 // FP pairwise minimum number scalar.
2307 void fminnmp(const VRegister& vd, const VRegister& vn);
2308
2309 // FP vector multiply accumulate.
2310 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2311
2312 // FP vector multiply subtract.
2313 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2314
2315 // FP vector multiply extended.
2316 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2317
2318 // FP absolute greater than or equal.
2319 void facge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2320
2321 // FP absolute greater than.
2322 void facgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2323
2324 // FP multiply by element.
2325 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2326 int vm_index);
2327
2328 // FP fused multiply-add to accumulator by element.
2329 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2330 int vm_index);
2331
2332 // FP fused multiply-sub from accumulator by element.
2333 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2334 int vm_index);
2335
2336 // FP multiply extended by element.
2337 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2338 int vm_index);
2339
2340 // FP compare equal.
2341 void fcmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2342
2343 // FP greater than.
2344 void fcmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2345
2346 // FP greater than or equal.
2347 void fcmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2348
2349 // FP pairwise maximum vector.
2350 void fmaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2351
2352 // FP pairwise minimum vector.
2353 void fminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2354
2355 // FP pairwise minimum scalar.
2356 void fminp(const VRegister& vd, const VRegister& vn);
2357
2358 // FP pairwise maximum number vector.
2359 void fmaxnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2360
2361 // FP pairwise minimum number vector.
2362 void fminnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2363
2364 // FP fused multiply-add.
2365 void fmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2366 const VRegister& va);
2367
2368 // FP fused multiply-subtract.
2369 void fmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2370 const VRegister& va);
2371
2372 // FP fused multiply-add and negate.
2373 void fnmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2374 const VRegister& va);
2375
2376 // FP fused multiply-subtract and negate.
2377 void fnmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2378 const VRegister& va);
2379
2380 // FP multiply-negate scalar.
2381 void fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2382
2383 // FP reciprocal exponent scalar.
2384 void frecpx(const VRegister& vd, const VRegister& vn);
1522 2385
1523 // FP divide. 2386 // FP divide.
1524 void fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2387 void fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1525 2388
1526 // FP maximum. 2389 // FP maximum.
1527 void fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2390 void fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1528 2391
1529 // FP minimum. 2392 // FP minimum.
1530 void fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2393 void fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1531 2394
1532 // FP maximum. 2395 // FP maximum.
1533 void fmaxnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2396 void fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1534 2397
1535 // FP minimum. 2398 // FP minimum.
1536 void fminnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 2399 void fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1537 2400
1538 // FP absolute. 2401 // FP absolute.
1539 void fabs(const FPRegister& fd, const FPRegister& fn); 2402 void fabs(const VRegister& vd, const VRegister& vn);
1540 2403
1541 // FP negate. 2404 // FP negate.
1542 void fneg(const FPRegister& fd, const FPRegister& fn); 2405 void fneg(const VRegister& vd, const VRegister& vn);
1543 2406
1544 // FP square root. 2407 // FP square root.
1545 void fsqrt(const FPRegister& fd, const FPRegister& fn); 2408 void fsqrt(const VRegister& vd, const VRegister& vn);
1546 2409
1547 // FP round to integer (nearest with ties to away). 2410 // FP round to integer nearest with ties to away.
1548 void frinta(const FPRegister& fd, const FPRegister& fn); 2411 void frinta(const VRegister& vd, const VRegister& vn);
1549 2412
1550 // FP round to integer (toward minus infinity). 2413 // FP round to integer, implicit rounding.
1551 void frintm(const FPRegister& fd, const FPRegister& fn); 2414 void frinti(const VRegister& vd, const VRegister& vn);
1552 2415
1553 // FP round to integer (nearest with ties to even). 2416 // FP round to integer toward minus infinity.
1554 void frintn(const FPRegister& fd, const FPRegister& fn); 2417 void frintm(const VRegister& vd, const VRegister& vn);
1555 2418
1556 // FP round to integer (towards plus infinity). 2419 // FP round to integer nearest with ties to even.
1557 void frintp(const FPRegister& fd, const FPRegister& fn); 2420 void frintn(const VRegister& vd, const VRegister& vn);
1558 2421
1559 // FP round to integer (towards zero.) 2422 // FP round to integer towards plus infinity.
1560 void frintz(const FPRegister& fd, const FPRegister& fn); 2423 void frintp(const VRegister& vd, const VRegister& vn);
2424
2425 // FP round to integer, exact, implicit rounding.
2426 void frintx(const VRegister& vd, const VRegister& vn);
2427
2428 // FP round to integer towards zero.
2429 void frintz(const VRegister& vd, const VRegister& vn);
1561 2430
1562 // FP compare registers. 2431 // FP compare registers.
1563 void fcmp(const FPRegister& fn, const FPRegister& fm); 2432 void fcmp(const VRegister& vn, const VRegister& vm);
1564 2433
1565 // FP compare immediate. 2434 // FP compare immediate.
1566 void fcmp(const FPRegister& fn, double value); 2435 void fcmp(const VRegister& vn, double value);
1567 2436
1568 // FP conditional compare. 2437 // FP conditional compare.
1569 void fccmp(const FPRegister& fn, 2438 void fccmp(const VRegister& vn, const VRegister& vm, StatusFlags nzcv,
1570 const FPRegister& fm,
1571 StatusFlags nzcv,
1572 Condition cond); 2439 Condition cond);
1573 2440
1574 // FP conditional select. 2441 // FP conditional select.
1575 void fcsel(const FPRegister& fd, 2442 void fcsel(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1576 const FPRegister& fn,
1577 const FPRegister& fm,
1578 Condition cond); 2443 Condition cond);
1579 2444
1580 // Common FP Convert function 2445 // Common FP Convert functions.
1581 void FPConvertToInt(const Register& rd, 2446 void NEONFPConvertToInt(const Register& rd, const VRegister& vn, Instr op);
1582 const FPRegister& fn, 2447 void NEONFPConvertToInt(const VRegister& vd, const VRegister& vn, Instr op);
1583 FPIntegerConvertOp op); 2448
1584 2449 // FP convert between precisions.
1585 // FP convert between single and double precision. 2450 void fcvt(const VRegister& vd, const VRegister& vn);
1586 void fcvt(const FPRegister& fd, const FPRegister& fn); 2451
1587 2452 // FP convert to higher precision.
1588 // Convert FP to unsigned integer (nearest with ties to away). 2453 void fcvtl(const VRegister& vd, const VRegister& vn);
1589 void fcvtau(const Register& rd, const FPRegister& fn); 2454
1590 2455 // FP convert to higher precision (second part).
1591 // Convert FP to signed integer (nearest with ties to away). 2456 void fcvtl2(const VRegister& vd, const VRegister& vn);
1592 void fcvtas(const Register& rd, const FPRegister& fn); 2457
1593 2458 // FP convert to lower precision.
1594 // Convert FP to unsigned integer (round towards -infinity). 2459 void fcvtn(const VRegister& vd, const VRegister& vn);
1595 void fcvtmu(const Register& rd, const FPRegister& fn); 2460
1596 2461 // FP convert to lower prevision (second part).
1597 // Convert FP to signed integer (round towards -infinity). 2462 void fcvtn2(const VRegister& vd, const VRegister& vn);
1598 void fcvtms(const Register& rd, const FPRegister& fn); 2463
1599 2464 // FP convert to lower precision, rounding to odd.
1600 // Convert FP to unsigned integer (nearest with ties to even). 2465 void fcvtxn(const VRegister& vd, const VRegister& vn);
1601 void fcvtnu(const Register& rd, const FPRegister& fn); 2466
1602 2467 // FP convert to lower precision, rounding to odd (second part).
1603 // Convert FP to signed integer (nearest with ties to even). 2468 void fcvtxn2(const VRegister& vd, const VRegister& vn);
1604 void fcvtns(const Register& rd, const FPRegister& fn); 2469
1605 2470 // FP convert to signed integer, nearest with ties to away.
1606 // Convert FP to unsigned integer (round towards zero). 2471 void fcvtas(const Register& rd, const VRegister& vn);
1607 void fcvtzu(const Register& rd, const FPRegister& fn); 2472
1608 2473 // FP convert to unsigned integer, nearest with ties to away.
1609 // Convert FP to signed integer (rounf towards zero). 2474 void fcvtau(const Register& rd, const VRegister& vn);
1610 void fcvtzs(const Register& rd, const FPRegister& fn); 2475
2476 // FP convert to signed integer, nearest with ties to away.
2477 void fcvtas(const VRegister& vd, const VRegister& vn);
2478
2479 // FP convert to unsigned integer, nearest with ties to away.
2480 void fcvtau(const VRegister& vd, const VRegister& vn);
2481
2482 // FP convert to signed integer, round towards -infinity.
2483 void fcvtms(const Register& rd, const VRegister& vn);
2484
2485 // FP convert to unsigned integer, round towards -infinity.
2486 void fcvtmu(const Register& rd, const VRegister& vn);
2487
2488 // FP convert to signed integer, round towards -infinity.
2489 void fcvtms(const VRegister& vd, const VRegister& vn);
2490
2491 // FP convert to unsigned integer, round towards -infinity.
2492 void fcvtmu(const VRegister& vd, const VRegister& vn);
2493
2494 // FP convert to signed integer, nearest with ties to even.
2495 void fcvtns(const Register& rd, const VRegister& vn);
2496
2497 // FP convert to unsigned integer, nearest with ties to even.
2498 void fcvtnu(const Register& rd, const VRegister& vn);
2499
2500 // FP convert to signed integer, nearest with ties to even.
2501 void fcvtns(const VRegister& rd, const VRegister& vn);
2502
2503 // FP convert to unsigned integer, nearest with ties to even.
2504 void fcvtnu(const VRegister& rd, const VRegister& vn);
2505
2506 // FP convert to signed integer or fixed-point, round towards zero.
2507 void fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0);
2508
2509 // FP convert to unsigned integer or fixed-point, round towards zero.
2510 void fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0);
2511
2512 // FP convert to signed integer or fixed-point, round towards zero.
2513 void fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0);
2514
2515 // FP convert to unsigned integer or fixed-point, round towards zero.
2516 void fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0);
2517
2518 // FP convert to signed integer, round towards +infinity.
2519 void fcvtps(const Register& rd, const VRegister& vn);
2520
2521 // FP convert to unsigned integer, round towards +infinity.
2522 void fcvtpu(const Register& rd, const VRegister& vn);
2523
2524 // FP convert to signed integer, round towards +infinity.
2525 void fcvtps(const VRegister& vd, const VRegister& vn);
2526
2527 // FP convert to unsigned integer, round towards +infinity.
2528 void fcvtpu(const VRegister& vd, const VRegister& vn);
1611 2529
1612 // Convert signed integer or fixed point to FP. 2530 // Convert signed integer or fixed point to FP.
1613 void scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 2531 void scvtf(const VRegister& fd, const Register& rn, int fbits = 0);
1614 2532
1615 // Convert unsigned integer or fixed point to FP. 2533 // Convert unsigned integer or fixed point to FP.
1616 void ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 2534 void ucvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2535
2536 // Convert signed integer or fixed-point to FP.
2537 void scvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2538
2539 // Convert unsigned integer or fixed-point to FP.
2540 void ucvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2541
2542 // Extract vector from pair of vectors.
2543 void ext(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2544 int index);
2545
2546 // Duplicate vector element to vector or scalar.
2547 void dup(const VRegister& vd, const VRegister& vn, int vn_index);
2548
2549 // Duplicate general-purpose register to vector.
2550 void dup(const VRegister& vd, const Register& rn);
2551
2552 // Insert vector element from general-purpose register.
2553 void ins(const VRegister& vd, int vd_index, const Register& rn);
2554
2555 // Move general-purpose register to a vector element.
2556 void mov(const VRegister& vd, int vd_index, const Register& rn);
2557
2558 // Unsigned move vector element to general-purpose register.
2559 void umov(const Register& rd, const VRegister& vn, int vn_index);
2560
2561 // Move vector element to general-purpose register.
2562 void mov(const Register& rd, const VRegister& vn, int vn_index);
2563
2564 // Move vector element to scalar.
2565 void mov(const VRegister& vd, const VRegister& vn, int vn_index);
2566
2567 // Insert vector element from another vector element.
2568 void ins(const VRegister& vd, int vd_index, const VRegister& vn,
2569 int vn_index);
2570
2571 // Move vector element to another vector element.
2572 void mov(const VRegister& vd, int vd_index, const VRegister& vn,
2573 int vn_index);
2574
2575 // Signed move vector element to general-purpose register.
2576 void smov(const Register& rd, const VRegister& vn, int vn_index);
2577
2578 // One-element structure load to one register.
2579 void ld1(const VRegister& vt, const MemOperand& src);
2580
2581 // One-element structure load to two registers.
2582 void ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2583
2584 // One-element structure load to three registers.
2585 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2586 const MemOperand& src);
2587
2588 // One-element structure load to four registers.
2589 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2590 const VRegister& vt4, const MemOperand& src);
2591
2592 // One-element single structure load to one lane.
2593 void ld1(const VRegister& vt, int lane, const MemOperand& src);
2594
2595 // One-element single structure load to all lanes.
2596 void ld1r(const VRegister& vt, const MemOperand& src);
2597
2598 // Two-element structure load.
2599 void ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2600
2601 // Two-element single structure load to one lane.
2602 void ld2(const VRegister& vt, const VRegister& vt2, int lane,
2603 const MemOperand& src);
2604
2605 // Two-element single structure load to all lanes.
2606 void ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2607
2608 // Three-element structure load.
2609 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2610 const MemOperand& src);
2611
2612 // Three-element single structure load to one lane.
2613 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2614 int lane, const MemOperand& src);
2615
2616 // Three-element single structure load to all lanes.
2617 void ld3r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2618 const MemOperand& src);
2619
2620 // Four-element structure load.
2621 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2622 const VRegister& vt4, const MemOperand& src);
2623
2624 // Four-element single structure load to one lane.
2625 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2626 const VRegister& vt4, int lane, const MemOperand& src);
2627
2628 // Four-element single structure load to all lanes.
2629 void ld4r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2630 const VRegister& vt4, const MemOperand& src);
2631
2632 // Count leading sign bits.
2633 void cls(const VRegister& vd, const VRegister& vn);
2634
2635 // Count leading zero bits (vector).
2636 void clz(const VRegister& vd, const VRegister& vn);
2637
2638 // Population count per byte.
2639 void cnt(const VRegister& vd, const VRegister& vn);
2640
2641 // Reverse bit order.
2642 void rbit(const VRegister& vd, const VRegister& vn);
2643
2644 // Reverse elements in 16-bit halfwords.
2645 void rev16(const VRegister& vd, const VRegister& vn);
2646
2647 // Reverse elements in 32-bit words.
2648 void rev32(const VRegister& vd, const VRegister& vn);
2649
2650 // Reverse elements in 64-bit doublewords.
2651 void rev64(const VRegister& vd, const VRegister& vn);
2652
2653 // Unsigned reciprocal square root estimate.
2654 void ursqrte(const VRegister& vd, const VRegister& vn);
2655
2656 // Unsigned reciprocal estimate.
2657 void urecpe(const VRegister& vd, const VRegister& vn);
2658
2659 // Signed pairwise long add and accumulate.
2660 void sadalp(const VRegister& vd, const VRegister& vn);
2661
2662 // Signed pairwise long add.
2663 void saddlp(const VRegister& vd, const VRegister& vn);
2664
2665 // Unsigned pairwise long add.
2666 void uaddlp(const VRegister& vd, const VRegister& vn);
2667
2668 // Unsigned pairwise long add and accumulate.
2669 void uadalp(const VRegister& vd, const VRegister& vn);
2670
2671 // Shift left by immediate.
2672 void shl(const VRegister& vd, const VRegister& vn, int shift);
2673
2674 // Signed saturating shift left by immediate.
2675 void sqshl(const VRegister& vd, const VRegister& vn, int shift);
2676
2677 // Signed saturating shift left unsigned by immediate.
2678 void sqshlu(const VRegister& vd, const VRegister& vn, int shift);
2679
2680 // Unsigned saturating shift left by immediate.
2681 void uqshl(const VRegister& vd, const VRegister& vn, int shift);
2682
2683 // Signed shift left long by immediate.
2684 void sshll(const VRegister& vd, const VRegister& vn, int shift);
2685
2686 // Signed shift left long by immediate (second part).
2687 void sshll2(const VRegister& vd, const VRegister& vn, int shift);
2688
2689 // Signed extend long.
2690 void sxtl(const VRegister& vd, const VRegister& vn);
2691
2692 // Signed extend long (second part).
2693 void sxtl2(const VRegister& vd, const VRegister& vn);
2694
2695 // Unsigned shift left long by immediate.
2696 void ushll(const VRegister& vd, const VRegister& vn, int shift);
2697
2698 // Unsigned shift left long by immediate (second part).
2699 void ushll2(const VRegister& vd, const VRegister& vn, int shift);
2700
2701 // Shift left long by element size.
2702 void shll(const VRegister& vd, const VRegister& vn, int shift);
2703
2704 // Shift left long by element size (second part).
2705 void shll2(const VRegister& vd, const VRegister& vn, int shift);
2706
2707 // Unsigned extend long.
2708 void uxtl(const VRegister& vd, const VRegister& vn);
2709
2710 // Unsigned extend long (second part).
2711 void uxtl2(const VRegister& vd, const VRegister& vn);
2712
2713 // Signed rounding halving add.
2714 void srhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2715
2716 // Unsigned halving sub.
2717 void uhsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2718
2719 // Signed halving sub.
2720 void shsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2721
2722 // Unsigned saturating add.
2723 void uqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2724
2725 // Signed saturating add.
2726 void sqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2727
2728 // Unsigned saturating subtract.
2729 void uqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2730
2731 // Signed saturating subtract.
2732 void sqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2733
2734 // Add pairwise.
2735 void addp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2736
2737 // Add pair of elements scalar.
2738 void addp(const VRegister& vd, const VRegister& vn);
2739
2740 // Multiply-add to accumulator.
2741 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2742
2743 // Multiply-subtract to accumulator.
2744 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2745
2746 // Multiply.
2747 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2748
2749 // Table lookup from one register.
2750 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2751
2752 // Table lookup from two registers.
2753 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2754 const VRegister& vm);
2755
2756 // Table lookup from three registers.
2757 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2758 const VRegister& vn3, const VRegister& vm);
2759
2760 // Table lookup from four registers.
2761 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2762 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
2763
2764 // Table lookup extension from one register.
2765 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2766
2767 // Table lookup extension from two registers.
2768 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2769 const VRegister& vm);
2770
2771 // Table lookup extension from three registers.
2772 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2773 const VRegister& vn3, const VRegister& vm);
2774
2775 // Table lookup extension from four registers.
2776 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2777 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
1617 2778
1618 // Instruction functions used only for test, debug, and patching. 2779 // Instruction functions used only for test, debug, and patching.
1619 // Emit raw instructions in the instruction stream. 2780 // Emit raw instructions in the instruction stream.
1620 void dci(Instr raw_inst) { Emit(raw_inst); } 2781 void dci(Instr raw_inst) { Emit(raw_inst); }
1621 2782
1622 // Emit 8 bits of data in the instruction stream. 2783 // Emit 8 bits of data in the instruction stream.
1623 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); } 2784 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); }
1624 2785
1625 // Emit 32 bits of data in the instruction stream. 2786 // Emit 32 bits of data in the instruction stream.
1626 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); } 2787 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); }
(...skipping 29 matching lines...) Expand all
1656 Instruction* InstructionAt(ptrdiff_t offset) const { 2817 Instruction* InstructionAt(ptrdiff_t offset) const {
1657 return reinterpret_cast<Instruction*>(buffer_ + offset); 2818 return reinterpret_cast<Instruction*>(buffer_ + offset);
1658 } 2819 }
1659 2820
1660 ptrdiff_t InstructionOffset(Instruction* instr) const { 2821 ptrdiff_t InstructionOffset(Instruction* instr) const {
1661 return reinterpret_cast<byte*>(instr) - buffer_; 2822 return reinterpret_cast<byte*>(instr) - buffer_;
1662 } 2823 }
1663 2824
1664 // Register encoding. 2825 // Register encoding.
1665 static Instr Rd(CPURegister rd) { 2826 static Instr Rd(CPURegister rd) {
1666 DCHECK(rd.code() != kSPRegInternalCode); 2827 DCHECK_NE(rd.code(), kSPRegInternalCode);
1667 return rd.code() << Rd_offset; 2828 return rd.code() << Rd_offset;
1668 } 2829 }
1669 2830
1670 static Instr Rn(CPURegister rn) { 2831 static Instr Rn(CPURegister rn) {
1671 DCHECK(rn.code() != kSPRegInternalCode); 2832 DCHECK_NE(rn.code(), kSPRegInternalCode);
1672 return rn.code() << Rn_offset; 2833 return rn.code() << Rn_offset;
1673 } 2834 }
1674 2835
1675 static Instr Rm(CPURegister rm) { 2836 static Instr Rm(CPURegister rm) {
1676 DCHECK(rm.code() != kSPRegInternalCode); 2837 DCHECK_NE(rm.code(), kSPRegInternalCode);
1677 return rm.code() << Rm_offset; 2838 return rm.code() << Rm_offset;
1678 } 2839 }
1679 2840
2841 static Instr RmNot31(CPURegister rm) {
2842 DCHECK_NE(rm.code(), kSPRegInternalCode);
2843 DCHECK(!rm.IsZero());
2844 return Rm(rm);
2845 }
2846
1680 static Instr Ra(CPURegister ra) { 2847 static Instr Ra(CPURegister ra) {
1681 DCHECK(ra.code() != kSPRegInternalCode); 2848 DCHECK_NE(ra.code(), kSPRegInternalCode);
1682 return ra.code() << Ra_offset; 2849 return ra.code() << Ra_offset;
1683 } 2850 }
1684 2851
1685 static Instr Rt(CPURegister rt) { 2852 static Instr Rt(CPURegister rt) {
1686 DCHECK(rt.code() != kSPRegInternalCode); 2853 DCHECK_NE(rt.code(), kSPRegInternalCode);
1687 return rt.code() << Rt_offset; 2854 return rt.code() << Rt_offset;
1688 } 2855 }
1689 2856
1690 static Instr Rt2(CPURegister rt2) { 2857 static Instr Rt2(CPURegister rt2) {
1691 DCHECK(rt2.code() != kSPRegInternalCode); 2858 DCHECK_NE(rt2.code(), kSPRegInternalCode);
1692 return rt2.code() << Rt2_offset; 2859 return rt2.code() << Rt2_offset;
1693 } 2860 }
1694 2861
1695 static Instr Rs(CPURegister rs) { 2862 static Instr Rs(CPURegister rs) {
1696 DCHECK(rs.code() != kSPRegInternalCode); 2863 DCHECK_NE(rs.code(), kSPRegInternalCode);
1697 return rs.code() << Rs_offset; 2864 return rs.code() << Rs_offset;
1698 } 2865 }
1699 2866
1700 // These encoding functions allow the stack pointer to be encoded, and 2867 // These encoding functions allow the stack pointer to be encoded, and
1701 // disallow the zero register. 2868 // disallow the zero register.
1702 static Instr RdSP(Register rd) { 2869 static Instr RdSP(Register rd) {
1703 DCHECK(!rd.IsZero()); 2870 DCHECK(!rd.IsZero());
1704 return (rd.code() & kRegCodeMask) << Rd_offset; 2871 return (rd.code() & kRegCodeMask) << Rd_offset;
1705 } 2872 }
1706 2873
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 static bool IsImmAddSub(int64_t immediate); 2909 static bool IsImmAddSub(int64_t immediate);
1743 static bool IsImmLogical(uint64_t value, 2910 static bool IsImmLogical(uint64_t value,
1744 unsigned width, 2911 unsigned width,
1745 unsigned* n, 2912 unsigned* n,
1746 unsigned* imm_s, 2913 unsigned* imm_s,
1747 unsigned* imm_r); 2914 unsigned* imm_r);
1748 2915
1749 // MemOperand offset encoding. 2916 // MemOperand offset encoding.
1750 inline static Instr ImmLSUnsigned(int imm12); 2917 inline static Instr ImmLSUnsigned(int imm12);
1751 inline static Instr ImmLS(int imm9); 2918 inline static Instr ImmLS(int imm9);
1752 inline static Instr ImmLSPair(int imm7, LSDataSize size); 2919 inline static Instr ImmLSPair(int imm7, unsigned size);
1753 inline static Instr ImmShiftLS(unsigned shift_amount); 2920 inline static Instr ImmShiftLS(unsigned shift_amount);
1754 inline static Instr ImmException(int imm16); 2921 inline static Instr ImmException(int imm16);
1755 inline static Instr ImmSystemRegister(int imm15); 2922 inline static Instr ImmSystemRegister(int imm15);
1756 inline static Instr ImmHint(int imm7); 2923 inline static Instr ImmHint(int imm7);
1757 inline static Instr ImmBarrierDomain(int imm2); 2924 inline static Instr ImmBarrierDomain(int imm2);
1758 inline static Instr ImmBarrierType(int imm2); 2925 inline static Instr ImmBarrierType(int imm2);
1759 inline static LSDataSize CalcLSDataSize(LoadStoreOp op); 2926 inline static unsigned CalcLSDataSize(LoadStoreOp op);
2927
2928 // Instruction bits for vector format in data processing operations.
2929 static Instr VFormat(VRegister vd) {
2930 if (vd.Is64Bits()) {
2931 switch (vd.LaneCount()) {
2932 case 2:
2933 return NEON_2S;
2934 case 4:
2935 return NEON_4H;
2936 case 8:
2937 return NEON_8B;
2938 default:
2939 UNREACHABLE();
2940 return kUnallocatedInstruction;
2941 }
2942 } else {
2943 DCHECK(vd.Is128Bits());
2944 switch (vd.LaneCount()) {
2945 case 2:
2946 return NEON_2D;
2947 case 4:
2948 return NEON_4S;
2949 case 8:
2950 return NEON_8H;
2951 case 16:
2952 return NEON_16B;
2953 default:
2954 UNREACHABLE();
2955 return kUnallocatedInstruction;
2956 }
2957 }
2958 }
2959
2960 // Instruction bits for vector format in floating point data processing
2961 // operations.
2962 static Instr FPFormat(VRegister vd) {
2963 if (vd.LaneCount() == 1) {
2964 // Floating point scalar formats.
2965 DCHECK(vd.Is32Bits() || vd.Is64Bits());
2966 return vd.Is64Bits() ? FP64 : FP32;
2967 }
2968
2969 // Two lane floating point vector formats.
2970 if (vd.LaneCount() == 2) {
2971 DCHECK(vd.Is64Bits() || vd.Is128Bits());
2972 return vd.Is128Bits() ? NEON_FP_2D : NEON_FP_2S;
2973 }
2974
2975 // Four lane floating point vector format.
2976 DCHECK((vd.LaneCount() == 4) && vd.Is128Bits());
2977 return NEON_FP_4S;
2978 }
2979
2980 // Instruction bits for vector format in load and store operations.
2981 static Instr LSVFormat(VRegister vd) {
2982 if (vd.Is64Bits()) {
2983 switch (vd.LaneCount()) {
2984 case 1:
2985 return LS_NEON_1D;
2986 case 2:
2987 return LS_NEON_2S;
2988 case 4:
2989 return LS_NEON_4H;
2990 case 8:
2991 return LS_NEON_8B;
2992 default:
2993 UNREACHABLE();
2994 return kUnallocatedInstruction;
2995 }
2996 } else {
2997 DCHECK(vd.Is128Bits());
2998 switch (vd.LaneCount()) {
2999 case 2:
3000 return LS_NEON_2D;
3001 case 4:
3002 return LS_NEON_4S;
3003 case 8:
3004 return LS_NEON_8H;
3005 case 16:
3006 return LS_NEON_16B;
3007 default:
3008 UNREACHABLE();
3009 return kUnallocatedInstruction;
3010 }
3011 }
3012 }
3013
3014 // Instruction bits for scalar format in data processing operations.
3015 static Instr SFormat(VRegister vd) {
3016 DCHECK(vd.IsScalar());
3017 switch (vd.SizeInBytes()) {
3018 case 1:
3019 return NEON_B;
3020 case 2:
3021 return NEON_H;
3022 case 4:
3023 return NEON_S;
3024 case 8:
3025 return NEON_D;
3026 default:
3027 UNREACHABLE();
3028 return kUnallocatedInstruction;
3029 }
3030 }
3031
3032 static Instr ImmNEONHLM(int index, int num_bits) {
3033 int h, l, m;
3034 if (num_bits == 3) {
3035 DCHECK(is_uint3(index));
3036 h = (index >> 2) & 1;
3037 l = (index >> 1) & 1;
3038 m = (index >> 0) & 1;
3039 } else if (num_bits == 2) {
3040 DCHECK(is_uint2(index));
3041 h = (index >> 1) & 1;
3042 l = (index >> 0) & 1;
3043 m = 0;
3044 } else {
3045 DCHECK(is_uint1(index) && (num_bits == 1));
3046 h = (index >> 0) & 1;
3047 l = 0;
3048 m = 0;
3049 }
3050 return (h << NEONH_offset) | (l << NEONL_offset) | (m << NEONM_offset);
3051 }
3052
3053 static Instr ImmNEONExt(int imm4) {
3054 DCHECK(is_uint4(imm4));
3055 return imm4 << ImmNEONExt_offset;
3056 }
3057
3058 static Instr ImmNEON5(Instr format, int index) {
3059 DCHECK(is_uint4(index));
3060 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3061 int imm5 = (index << (s + 1)) | (1 << s);
3062 return imm5 << ImmNEON5_offset;
3063 }
3064
3065 static Instr ImmNEON4(Instr format, int index) {
3066 DCHECK(is_uint4(index));
3067 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3068 int imm4 = index << s;
3069 return imm4 << ImmNEON4_offset;
3070 }
3071
3072 static Instr ImmNEONabcdefgh(int imm8) {
3073 DCHECK(is_uint8(imm8));
3074 Instr instr;
3075 instr = ((imm8 >> 5) & 7) << ImmNEONabc_offset;
3076 instr |= (imm8 & 0x1f) << ImmNEONdefgh_offset;
3077 return instr;
3078 }
3079
3080 static Instr NEONCmode(int cmode) {
3081 DCHECK(is_uint4(cmode));
3082 return cmode << NEONCmode_offset;
3083 }
3084
3085 static Instr NEONModImmOp(int op) {
3086 DCHECK(is_uint1(op));
3087 return op << NEONModImmOp_offset;
3088 }
1760 3089
1761 static bool IsImmLSUnscaled(int64_t offset); 3090 static bool IsImmLSUnscaled(int64_t offset);
1762 static bool IsImmLSScaled(int64_t offset, LSDataSize size); 3091 static bool IsImmLSScaled(int64_t offset, unsigned size);
1763 static bool IsImmLLiteral(int64_t offset); 3092 static bool IsImmLLiteral(int64_t offset);
1764 3093
1765 // Move immediates encoding. 3094 // Move immediates encoding.
1766 inline static Instr ImmMoveWide(int imm); 3095 inline static Instr ImmMoveWide(int imm);
1767 inline static Instr ShiftMoveWide(int shift); 3096 inline static Instr ShiftMoveWide(int shift);
1768 3097
1769 // FP Immediates. 3098 // FP Immediates.
1770 static Instr ImmFP32(float imm); 3099 static Instr ImmFP(double imm);
1771 static Instr ImmFP64(double imm); 3100 static Instr ImmNEONFP(double imm);
1772 inline static Instr FPScale(unsigned scale); 3101 inline static Instr FPScale(unsigned scale);
1773 3102
1774 // FP register type. 3103 // FP register type.
1775 inline static Instr FPType(FPRegister fd); 3104 inline static Instr FPType(VRegister fd);
1776 3105
1777 // Class for scoping postponing the constant pool generation. 3106 // Class for scoping postponing the constant pool generation.
1778 class BlockConstPoolScope { 3107 class BlockConstPoolScope {
1779 public: 3108 public:
1780 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) { 3109 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
1781 assem_->StartBlockConstPool(); 3110 assem_->StartBlockConstPool();
1782 } 3111 }
1783 ~BlockConstPoolScope() { 3112 ~BlockConstPoolScope() {
1784 assem_->EndBlockConstPool(); 3113 assem_->EndBlockConstPool();
1785 } 3114 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 3168
1840 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); 3169 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope);
1841 }; 3170 };
1842 3171
1843 protected: 3172 protected:
1844 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; 3173 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const;
1845 3174
1846 void LoadStore(const CPURegister& rt, 3175 void LoadStore(const CPURegister& rt,
1847 const MemOperand& addr, 3176 const MemOperand& addr,
1848 LoadStoreOp op); 3177 LoadStoreOp op);
1849
1850 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2, 3178 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2,
1851 const MemOperand& addr, LoadStorePairOp op); 3179 const MemOperand& addr, LoadStorePairOp op);
1852 static bool IsImmLSPair(int64_t offset, LSDataSize size); 3180 void LoadStoreStruct(const VRegister& vt, const MemOperand& addr,
3181 NEONLoadStoreMultiStructOp op);
3182 void LoadStoreStruct1(const VRegister& vt, int reg_count,
3183 const MemOperand& addr);
3184 void LoadStoreStructSingle(const VRegister& vt, uint32_t lane,
3185 const MemOperand& addr,
3186 NEONLoadStoreSingleStructOp op);
3187 void LoadStoreStructSingleAllLanes(const VRegister& vt,
3188 const MemOperand& addr,
3189 NEONLoadStoreSingleStructOp op);
3190 void LoadStoreStructVerify(const VRegister& vt, const MemOperand& addr,
3191 Instr op);
3192
3193 static bool IsImmLSPair(int64_t offset, unsigned size);
1853 3194
1854 void Logical(const Register& rd, 3195 void Logical(const Register& rd,
1855 const Register& rn, 3196 const Register& rn,
1856 const Operand& operand, 3197 const Operand& operand,
1857 LogicalOp op); 3198 LogicalOp op);
1858 void LogicalImmediate(const Register& rd, 3199 void LogicalImmediate(const Register& rd,
1859 const Register& rn, 3200 const Register& rn,
1860 unsigned n, 3201 unsigned n,
1861 unsigned imm_s, 3202 unsigned imm_s,
1862 unsigned imm_r, 3203 unsigned imm_r,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt); 3248 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
1908 3249
1909 // Remove the specified branch from the unbound label link chain. 3250 // Remove the specified branch from the unbound label link chain.
1910 // If available, a veneer for this label can be used for other branches in the 3251 // If available, a veneer for this label can be used for other branches in the
1911 // chain if the link chain cannot be fixed up without this branch. 3252 // chain if the link chain cannot be fixed up without this branch.
1912 void RemoveBranchFromLabelLinkChain(Instruction* branch, 3253 void RemoveBranchFromLabelLinkChain(Instruction* branch,
1913 Label* label, 3254 Label* label,
1914 Instruction* label_veneer = NULL); 3255 Instruction* label_veneer = NULL);
1915 3256
1916 private: 3257 private:
3258 static uint32_t FPToImm8(double imm);
3259
1917 // Instruction helpers. 3260 // Instruction helpers.
1918 void MoveWide(const Register& rd, 3261 void MoveWide(const Register& rd,
1919 uint64_t imm, 3262 uint64_t imm,
1920 int shift, 3263 int shift,
1921 MoveWideImmediateOp mov_op); 3264 MoveWideImmediateOp mov_op);
1922 void DataProcShiftedRegister(const Register& rd, 3265 void DataProcShiftedRegister(const Register& rd,
1923 const Register& rn, 3266 const Register& rn,
1924 const Operand& operand, 3267 const Operand& operand,
1925 FlagsUpdate S, 3268 FlagsUpdate S,
1926 Instr op); 3269 Instr op);
1927 void DataProcExtendedRegister(const Register& rd, 3270 void DataProcExtendedRegister(const Register& rd,
1928 const Register& rn, 3271 const Register& rn,
1929 const Operand& operand, 3272 const Operand& operand,
1930 FlagsUpdate S, 3273 FlagsUpdate S,
1931 Instr op); 3274 Instr op);
1932 void ConditionalSelect(const Register& rd, 3275 void ConditionalSelect(const Register& rd,
1933 const Register& rn, 3276 const Register& rn,
1934 const Register& rm, 3277 const Register& rm,
1935 Condition cond, 3278 Condition cond,
1936 ConditionalSelectOp op); 3279 ConditionalSelectOp op);
1937 void DataProcessing1Source(const Register& rd, 3280 void DataProcessing1Source(const Register& rd,
1938 const Register& rn, 3281 const Register& rn,
1939 DataProcessing1SourceOp op); 3282 DataProcessing1SourceOp op);
1940 void DataProcessing3Source(const Register& rd, 3283 void DataProcessing3Source(const Register& rd,
1941 const Register& rn, 3284 const Register& rn,
1942 const Register& rm, 3285 const Register& rm,
1943 const Register& ra, 3286 const Register& ra,
1944 DataProcessing3SourceOp op); 3287 DataProcessing3SourceOp op);
1945 void FPDataProcessing1Source(const FPRegister& fd, 3288 void FPDataProcessing1Source(const VRegister& fd, const VRegister& fn,
1946 const FPRegister& fn,
1947 FPDataProcessing1SourceOp op); 3289 FPDataProcessing1SourceOp op);
1948 void FPDataProcessing2Source(const FPRegister& fd, 3290 void FPDataProcessing2Source(const VRegister& fd, const VRegister& fn,
1949 const FPRegister& fn, 3291 const VRegister& fm,
1950 const FPRegister& fm,
1951 FPDataProcessing2SourceOp op); 3292 FPDataProcessing2SourceOp op);
1952 void FPDataProcessing3Source(const FPRegister& fd, 3293 void FPDataProcessing3Source(const VRegister& fd, const VRegister& fn,
1953 const FPRegister& fn, 3294 const VRegister& fm, const VRegister& fa,
1954 const FPRegister& fm,
1955 const FPRegister& fa,
1956 FPDataProcessing3SourceOp op); 3295 FPDataProcessing3SourceOp op);
3296 void NEONAcrossLanesL(const VRegister& vd, const VRegister& vn,
3297 NEONAcrossLanesOp op);
3298 void NEONAcrossLanes(const VRegister& vd, const VRegister& vn,
3299 NEONAcrossLanesOp op);
3300 void NEONModifiedImmShiftLsl(const VRegister& vd, const int imm8,
3301 const int left_shift,
3302 NEONModifiedImmediateOp op);
3303 void NEONModifiedImmShiftMsl(const VRegister& vd, const int imm8,
3304 const int shift_amount,
3305 NEONModifiedImmediateOp op);
3306 void NEON3Same(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3307 NEON3SameOp vop);
3308 void NEONFP3Same(const VRegister& vd, const VRegister& vn,
3309 const VRegister& vm, Instr op);
3310 void NEON3DifferentL(const VRegister& vd, const VRegister& vn,
3311 const VRegister& vm, NEON3DifferentOp vop);
3312 void NEON3DifferentW(const VRegister& vd, const VRegister& vn,
3313 const VRegister& vm, NEON3DifferentOp vop);
3314 void NEON3DifferentHN(const VRegister& vd, const VRegister& vn,
3315 const VRegister& vm, NEON3DifferentOp vop);
3316 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn,
3317 NEON2RegMiscOp vop, double value = 0.0);
3318 void NEON2RegMisc(const VRegister& vd, const VRegister& vn,
3319 NEON2RegMiscOp vop, int value = 0);
3320 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn, Instr op);
3321 void NEONAddlp(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp op);
3322 void NEONPerm(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3323 NEONPermOp op);
3324 void NEONFPByElement(const VRegister& vd, const VRegister& vn,
3325 const VRegister& vm, int vm_index,
3326 NEONByIndexedElementOp op);
3327 void NEONByElement(const VRegister& vd, const VRegister& vn,
3328 const VRegister& vm, int vm_index,
3329 NEONByIndexedElementOp op);
3330 void NEONByElementL(const VRegister& vd, const VRegister& vn,
3331 const VRegister& vm, int vm_index,
3332 NEONByIndexedElementOp op);
3333 void NEONShiftImmediate(const VRegister& vd, const VRegister& vn,
3334 NEONShiftImmediateOp op, int immh_immb);
3335 void NEONShiftLeftImmediate(const VRegister& vd, const VRegister& vn,
3336 int shift, NEONShiftImmediateOp op);
3337 void NEONShiftRightImmediate(const VRegister& vd, const VRegister& vn,
3338 int shift, NEONShiftImmediateOp op);
3339 void NEONShiftImmediateL(const VRegister& vd, const VRegister& vn, int shift,
3340 NEONShiftImmediateOp op);
3341 void NEONShiftImmediateN(const VRegister& vd, const VRegister& vn, int shift,
3342 NEONShiftImmediateOp op);
3343 void NEONXtn(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp vop);
3344 void NEONTable(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3345 NEONTableOp op);
3346
3347 Instr LoadStoreStructAddrModeField(const MemOperand& addr);
1957 3348
1958 // Label helpers. 3349 // Label helpers.
1959 3350
1960 // Return an offset for a label-referencing instruction, typically a branch. 3351 // Return an offset for a label-referencing instruction, typically a branch.
1961 int LinkAndGetByteOffsetTo(Label* label); 3352 int LinkAndGetByteOffsetTo(Label* label);
1962 3353
1963 // This is the same as LinkAndGetByteOffsetTo, but return an offset 3354 // This is the same as LinkAndGetByteOffsetTo, but return an offset
1964 // suitable for fields that take instruction offsets. 3355 // suitable for fields that take instruction offsets.
1965 inline int LinkAndGetInstructionOffsetTo(Label* label); 3356 inline int LinkAndGetInstructionOffsetTo(Label* label);
1966 3357
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2203 public: 3594 public:
2204 explicit EnsureSpace(Assembler* assembler) { 3595 explicit EnsureSpace(Assembler* assembler) {
2205 assembler->CheckBufferSpace(); 3596 assembler->CheckBufferSpace();
2206 } 3597 }
2207 }; 3598 };
2208 3599
2209 } // namespace internal 3600 } // namespace internal
2210 } // namespace v8 3601 } // namespace v8
2211 3602
2212 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ 3603 #endif // V8_ARM64_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « DEPS ('k') | src/arm64/assembler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698