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