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