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