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