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 3 // found in the LICENSE file. 4 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ 7 8 #include <deque> 9 #include <list> 10 #include <map> 11 #include <vector> 12 13 #include "src/arm64/instructions-arm64.h" 14 #include "src/assembler.h" 15 #include "src/globals.h" 16 #include "src/utils.h" 17 18 19 namespace v8 { 20 namespace internal { 21 22 23 // ----------------------------------------------------------------------------- 24 // Registers. 25 // clang-format off 26 #define GENERAL_REGISTER_CODE_LIST(R) \ 27 R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 28 R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 29 R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 30 R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 31 32 #define GENERAL_REGISTERS(R) \ 33 R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ 34 R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ 35 R(x16) R(x17) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) \ 36 R(x24) R(x25) R(x26) R(x27) R(x28) R(x29) R(x30) R(x31) 37 38 #define ALLOCATABLE_GENERAL_REGISTERS(R) \ 39 R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ 40 R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ 41 R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27) 42 43 #define FLOAT_REGISTERS(V) \ 44 V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \ 45 V(s8) V(s9) V(s10) V(s11) V(s12) V(s13) V(s14) V(s15) \ 46 V(s16) V(s17) V(s18) V(s19) V(s20) V(s21) V(s22) V(s23) \ 47 V(s24) V(s25) V(s26) V(s27) V(s28) V(s29) V(s30) V(s31) 48 49 #define DOUBLE_REGISTERS(R) \ 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) \ 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) 54 55 #define ALLOCATABLE_DOUBLE_REGISTERS(R) \ 56 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ 57 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \ 58 R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \ 59 R(d25) R(d26) R(d27) R(d28) 60 // clang-format on 61 62 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte; 63 64 65 // Some CPURegister methods can return Register and FPRegister types, so we 66 // need to declare them in advance. 67 struct Register; 68 struct FPRegister; 69 70 71 struct CPURegister { 72 enum Code { 73 #define REGISTER_CODE(R) kCode_##R, 74 GENERAL_REGISTERS(REGISTER_CODE) 75 #undef REGISTER_CODE 76 kAfterLast, 77 kCode_no_reg = -1 78 }; 79 80 enum RegisterType { 81 // The kInvalid value is used to detect uninitialized static instances, 82 // which are always zero-initialized before any constructors are called. 83 kInvalid = 0, 84 kRegister, 85 kFPRegister, 86 kNoRegister 87 }; 88 89 static CPURegister Create(int code, int size, RegisterType type) { 90 CPURegister r = {code, size, type}; 91 return r; 92 } 93 94 int code() const; 95 RegisterType type() const; 96 RegList Bit() const; 97 int SizeInBits() const; 98 int SizeInBytes() const; 99 bool Is32Bits() const; 100 bool Is64Bits() const; 101 bool IsValid() const; 102 bool IsValidOrNone() const; 103 bool IsValidRegister() const; 104 bool IsValidFPRegister() const; 105 bool IsNone() const; 106 bool Is(const CPURegister& other) const; 107 bool Aliases(const CPURegister& other) const; 108 109 bool IsZero() const; 110 bool IsSP() const; 111 112 bool IsRegister() const; 113 bool IsFPRegister() const; 114 115 Register X() const; 116 Register W() const; 117 FPRegister D() const; 118 FPRegister S() const; 119 120 bool IsSameSizeAndType(const CPURegister& other) const; 121 122 // V8 compatibility. 123 bool is(const CPURegister& other) const { return Is(other); } 124 bool is_valid() const { return IsValid(); } 125 126 int reg_code; 127 int reg_size; 128 RegisterType reg_type; 129 }; 130 131 132 struct Register : public CPURegister { 133 static Register Create(int code, int size) { 134 return Register(CPURegister::Create(code, size, CPURegister::kRegister)); 135 } 136 137 Register() { 138 reg_code = 0; 139 reg_size = 0; 140 reg_type = CPURegister::kNoRegister; 141 } 142 143 explicit Register(const CPURegister& r) { 144 reg_code = r.reg_code; 145 reg_size = r.reg_size; 146 reg_type = r.reg_type; 147 DCHECK(IsValidOrNone()); 148 } 149 150 Register(const Register& r) { // NOLINT(runtime/explicit) 151 reg_code = r.reg_code; 152 reg_size = r.reg_size; 153 reg_type = r.reg_type; 154 DCHECK(IsValidOrNone()); 155 } 156 157 bool IsValid() const { 158 DCHECK(IsRegister() || IsNone()); 159 return IsValidRegister(); 160 } 161 162 static Register XRegFromCode(unsigned code); 163 static Register WRegFromCode(unsigned code); 164 165 // Start of V8 compatibility section --------------------- 166 // These memebers are necessary for compilation. 167 // A few of them may be unused for now. 168 169 static const int kNumRegisters = kNumberOfRegisters; 170 STATIC_ASSERT(kNumRegisters == Code::kAfterLast); 171 static int NumRegisters() { return kNumRegisters; } 172 173 // We allow crankshaft to use the following registers: 174 // - x0 to x15 175 // - x18 to x24 176 // - x27 (also context) 177 // 178 // TODO(all): Register x25 is currently free and could be available for 179 // crankshaft, but we don't use it as we might use it as a per function 180 // literal pool pointer in the future. 181 // 182 // TODO(all): Consider storing cp in x25 to have only two ranges. 183 // We split allocatable registers in three ranges called 184 // - "low range" 185 // - "high range" 186 // - "context" 187 188 static Register from_code(int code) { 189 // Always return an X register. 190 return Register::Create(code, kXRegSizeInBits); 191 } 192 193 // End of V8 compatibility section ----------------------- 194 }; 195 196 static const bool kSimpleFPAliasing = true; 197 198 struct FPRegister : public CPURegister { 199 enum Code { 200 #define REGISTER_CODE(R) kCode_##R, 201 DOUBLE_REGISTERS(REGISTER_CODE) 202 #undef REGISTER_CODE 203 kAfterLast, 204 kCode_no_reg = -1 205 }; 206 207 static FPRegister Create(int code, int size) { 208 return FPRegister( 209 CPURegister::Create(code, size, CPURegister::kFPRegister)); 210 } 211 212 FPRegister() { 213 reg_code = 0; 214 reg_size = 0; 215 reg_type = CPURegister::kNoRegister; 216 } 217 218 explicit FPRegister(const CPURegister& r) { 219 reg_code = r.reg_code; 220 reg_size = r.reg_size; 221 reg_type = r.reg_type; 222 DCHECK(IsValidOrNone()); 223 } 224 225 FPRegister(const FPRegister& r) { // NOLINT(runtime/explicit) 226 reg_code = r.reg_code; 227 reg_size = r.reg_size; 228 reg_type = r.reg_type; 229 DCHECK(IsValidOrNone()); 230 } 231 232 bool IsValid() const { 233 DCHECK(IsFPRegister() || IsNone()); 234 return IsValidFPRegister(); 235 } 236 237 static FPRegister SRegFromCode(unsigned code); 238 static FPRegister DRegFromCode(unsigned code); 239 240 // Start of V8 compatibility section --------------------- 241 static const int kMaxNumRegisters = kNumberOfFPRegisters; 242 STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast); 243 244 // Crankshaft can use all the FP registers except: 245 // - d15 which is used to keep the 0 double value 246 // - d30 which is used in crankshaft as a double scratch register 247 // - d31 which is used in the MacroAssembler as a double scratch register 248 static FPRegister from_code(int code) { 249 // Always return a D register. 250 return FPRegister::Create(code, kDRegSizeInBits); 251 } 252 // End of V8 compatibility section ----------------------- 253 }; 254 255 256 STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); 257 STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); 258 259 260 #if defined(ARM64_DEFINE_REG_STATICS) 261 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 262 const CPURegister init_##register_class##_##name = {code, size, type}; \ 263 const register_class& name = *reinterpret_cast<const register_class*>( \ 264 &init_##register_class##_##name) 265 #define ALIAS_REGISTER(register_class, alias, name) \ 266 const register_class& alias = *reinterpret_cast<const register_class*>( \ 267 &init_##register_class##_##name) 268 #else 269 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 270 extern const register_class& name 271 #define ALIAS_REGISTER(register_class, alias, name) \ 272 extern const register_class& alias 273 #endif // defined(ARM64_DEFINE_REG_STATICS) 274 275 // No*Reg is used to indicate an unused argument, or an error case. Note that 276 // these all compare equal (using the Is() method). The Register and FPRegister 277 // variants are provided for convenience. 278 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister); 279 INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister); 280 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister); 281 282 // v8 compatibility. 283 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); 284 285 #define DEFINE_REGISTERS(N) \ 286 INITIALIZE_REGISTER(Register, w##N, N, \ 287 kWRegSizeInBits, CPURegister::kRegister); \ 288 INITIALIZE_REGISTER(Register, x##N, N, \ 289 kXRegSizeInBits, CPURegister::kRegister); 290 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) 291 #undef DEFINE_REGISTERS 292 293 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits, 294 CPURegister::kRegister); 295 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits, 296 CPURegister::kRegister); 297 298 #define DEFINE_FPREGISTERS(N) \ 299 INITIALIZE_REGISTER(FPRegister, s##N, N, \ 300 kSRegSizeInBits, CPURegister::kFPRegister); \ 301 INITIALIZE_REGISTER(FPRegister, d##N, N, \ 302 kDRegSizeInBits, CPURegister::kFPRegister); 303 GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS) 304 #undef DEFINE_FPREGISTERS 305 306 #undef INITIALIZE_REGISTER 307 308 // Registers aliases. 309 ALIAS_REGISTER(Register, ip0, x16); 310 ALIAS_REGISTER(Register, ip1, x17); 311 ALIAS_REGISTER(Register, wip0, w16); 312 ALIAS_REGISTER(Register, wip1, w17); 313 // Root register. 314 ALIAS_REGISTER(Register, root, x26); 315 ALIAS_REGISTER(Register, rr, x26); 316 // Context pointer register. 317 ALIAS_REGISTER(Register, cp, x27); 318 // We use a register as a JS stack pointer to overcome the restriction on the 319 // architectural SP alignment. 320 // We chose x28 because it is contiguous with the other specific purpose 321 // registers. 322 STATIC_ASSERT(kJSSPCode == 28); 323 ALIAS_REGISTER(Register, jssp, x28); 324 ALIAS_REGISTER(Register, wjssp, w28); 325 ALIAS_REGISTER(Register, fp, x29); 326 ALIAS_REGISTER(Register, lr, x30); 327 ALIAS_REGISTER(Register, xzr, x31); 328 ALIAS_REGISTER(Register, wzr, w31); 329 330 // Keeps the 0 double value. 331 ALIAS_REGISTER(FPRegister, fp_zero, d15); 332 // Crankshaft double scratch register. 333 ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29); 334 // MacroAssembler double scratch registers. 335 ALIAS_REGISTER(FPRegister, fp_scratch, d30); 336 ALIAS_REGISTER(FPRegister, fp_scratch1, d30); 337 ALIAS_REGISTER(FPRegister, fp_scratch2, d31); 338 339 #undef ALIAS_REGISTER 340 341 342 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, 343 Register reg2 = NoReg, 344 Register reg3 = NoReg, 345 Register reg4 = NoReg); 346 347 348 // AreAliased returns true if any of the named registers overlap. Arguments set 349 // to NoReg are ignored. The system stack pointer may be specified. 350 bool AreAliased(const CPURegister& reg1, 351 const CPURegister& reg2, 352 const CPURegister& reg3 = NoReg, 353 const CPURegister& reg4 = NoReg, 354 const CPURegister& reg5 = NoReg, 355 const CPURegister& reg6 = NoReg, 356 const CPURegister& reg7 = NoReg, 357 const CPURegister& reg8 = NoReg); 358 359 // AreSameSizeAndType returns true if all of the specified registers have the 360 // same size, and are of the same type. The system stack pointer may be 361 // specified. Arguments set to NoReg are ignored, as are any subsequent 362 // arguments. At least one argument (reg1) must be valid (not NoCPUReg). 363 bool AreSameSizeAndType(const CPURegister& reg1, 364 const CPURegister& reg2, 365 const CPURegister& reg3 = NoCPUReg, 366 const CPURegister& reg4 = NoCPUReg, 367 const CPURegister& reg5 = NoCPUReg, 368 const CPURegister& reg6 = NoCPUReg, 369 const CPURegister& reg7 = NoCPUReg, 370 const CPURegister& reg8 = NoCPUReg); 371 372 typedef FPRegister FloatRegister; 373 typedef FPRegister DoubleRegister; 374 375 // TODO(arm64) Define SIMD registers. 376 typedef FPRegister Simd128Register; 377 378 // ----------------------------------------------------------------------------- 379 // Lists of registers. 380 class CPURegList { 381 public: 382 explicit CPURegList(CPURegister reg1, 383 CPURegister reg2 = NoCPUReg, 384 CPURegister reg3 = NoCPUReg, 385 CPURegister reg4 = NoCPUReg) 386 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()), 387 size_(reg1.SizeInBits()), type_(reg1.type()) { 388 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4)); 389 DCHECK(IsValid()); 390 } 391 392 CPURegList(CPURegister::RegisterType type, int size, RegList list) 393 : list_(list), size_(size), type_(type) { 394 DCHECK(IsValid()); 395 } 396 397 CPURegList(CPURegister::RegisterType type, int size, int first_reg, 398 int last_reg) 399 : size_(size), type_(type) { 400 DCHECK(((type == CPURegister::kRegister) && 401 (last_reg < kNumberOfRegisters)) || 402 ((type == CPURegister::kFPRegister) && 403 (last_reg < kNumberOfFPRegisters))); 404 DCHECK(last_reg >= first_reg); 405 list_ = (1UL << (last_reg + 1)) - 1; 406 list_ &= ~((1UL << first_reg) - 1); 407 DCHECK(IsValid()); 408 } 409 410 CPURegister::RegisterType type() const { 411 DCHECK(IsValid()); 412 return type_; 413 } 414 415 RegList list() const { 416 DCHECK(IsValid()); 417 return list_; 418 } 419 420 inline void set_list(RegList new_list) { 421 DCHECK(IsValid()); 422 list_ = new_list; 423 } 424 425 // Combine another CPURegList into this one. Registers that already exist in 426 // this list are left unchanged. The type and size of the registers in the 427 // 'other' list must match those in this list. 428 void Combine(const CPURegList& other); 429 430 // Remove every register in the other CPURegList from this one. Registers that 431 // do not exist in this list are ignored. The type of the registers in the 432 // 'other' list must match those in this list. 433 void Remove(const CPURegList& other); 434 435 // Variants of Combine and Remove which take CPURegisters. 436 void Combine(const CPURegister& other); 437 void Remove(const CPURegister& other1, 438 const CPURegister& other2 = NoCPUReg, 439 const CPURegister& other3 = NoCPUReg, 440 const CPURegister& other4 = NoCPUReg); 441 442 // Variants of Combine and Remove which take a single register by its code; 443 // the type and size of the register is inferred from this list. 444 void Combine(int code); 445 void Remove(int code); 446 447 // Remove all callee-saved registers from the list. This can be useful when 448 // preparing registers for an AAPCS64 function call, for example. 449 void RemoveCalleeSaved(); 450 451 CPURegister PopLowestIndex(); 452 CPURegister PopHighestIndex(); 453 454 // AAPCS64 callee-saved registers. 455 static CPURegList GetCalleeSaved(int size = kXRegSizeInBits); 456 static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits); 457 458 // AAPCS64 caller-saved registers. Note that this includes lr. 459 static CPURegList GetCallerSaved(int size = kXRegSizeInBits); 460 static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits); 461 462 // Registers saved as safepoints. 463 static CPURegList GetSafepointSavedRegisters(); 464 465 bool IsEmpty() const { 466 DCHECK(IsValid()); 467 return list_ == 0; 468 } 469 470 bool IncludesAliasOf(const CPURegister& other1, 471 const CPURegister& other2 = NoCPUReg, 472 const CPURegister& other3 = NoCPUReg, 473 const CPURegister& other4 = NoCPUReg) const { 474 DCHECK(IsValid()); 475 RegList list = 0; 476 if (!other1.IsNone() && (other1.type() == type_)) list |= other1.Bit(); 477 if (!other2.IsNone() && (other2.type() == type_)) list |= other2.Bit(); 478 if (!other3.IsNone() && (other3.type() == type_)) list |= other3.Bit(); 479 if (!other4.IsNone() && (other4.type() == type_)) list |= other4.Bit(); 480 return (list_ & list) != 0; 481 } 482 483 int Count() const { 484 DCHECK(IsValid()); 485 return CountSetBits(list_, kRegListSizeInBits); 486 } 487 488 int RegisterSizeInBits() const { 489 DCHECK(IsValid()); 490 return size_; 491 } 492 493 int RegisterSizeInBytes() const { 494 int size_in_bits = RegisterSizeInBits(); 495 DCHECK((size_in_bits % kBitsPerByte) == 0); 496 return size_in_bits / kBitsPerByte; 497 } 498 499 int TotalSizeInBytes() const { 500 DCHECK(IsValid()); 501 return RegisterSizeInBytes() * Count(); 502 } 503 504 private: 505 RegList list_; 506 int size_; 507 CPURegister::RegisterType type_; 508 509 bool IsValid() const { 510 const RegList kValidRegisters = 0x8000000ffffffff; 511 const RegList kValidFPRegisters = 0x0000000ffffffff; 512 switch (type_) { 513 case CPURegister::kRegister: 514 return (list_ & kValidRegisters) == list_; 515 case CPURegister::kFPRegister: 516 return (list_ & kValidFPRegisters) == list_; 517 case CPURegister::kNoRegister: 518 return list_ == 0; 519 default: 520 UNREACHABLE(); 521 return false; 522 } 523 } 524 }; 525 526 527 // AAPCS64 callee-saved registers. 528 #define kCalleeSaved CPURegList::GetCalleeSaved() 529 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() 530 531 532 // AAPCS64 caller-saved registers. Note that this includes lr. 533 #define kCallerSaved CPURegList::GetCallerSaved() 534 #define kCallerSavedFP CPURegList::GetCallerSavedFP() 535 536 // ----------------------------------------------------------------------------- 537 // Immediates. 538 class Immediate { 539 public: 540 template<typename T> 541 inline explicit Immediate(Handle<T> handle); 542 543 // This is allowed to be an implicit constructor because Immediate is 544 // a wrapper class that doesn't normally perform any type conversion. 545 template<typename T> 546 inline Immediate(T value); // NOLINT(runtime/explicit) 547 548 template<typename T> 549 inline Immediate(T value, RelocInfo::Mode rmode); 550 551 int64_t value() const { return value_; } 552 RelocInfo::Mode rmode() const { return rmode_; } 553 554 private: 555 void InitializeHandle(Handle<Object> value); 556 557 int64_t value_; 558 RelocInfo::Mode rmode_; 559 }; 560 561 562 // ----------------------------------------------------------------------------- 563 // Operands. 564 const int kSmiShift = kSmiTagSize + kSmiShiftSize; 565 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; 566 567 // Represents an operand in a machine instruction. 568 class Operand { 569 // TODO(all): If necessary, study more in details which methods 570 // TODO(all): should be inlined or not. 571 public: 572 // rm, {<shift> {#<shift_amount>}} 573 // where <shift> is one of {LSL, LSR, ASR, ROR}. 574 // <shift_amount> is uint6_t. 575 // This is allowed to be an implicit constructor because Operand is 576 // a wrapper class that doesn't normally perform any type conversion. 577 inline Operand(Register reg, 578 Shift shift = LSL, 579 unsigned shift_amount = 0); // NOLINT(runtime/explicit) 580 581 // rm, <extend> {#<shift_amount>} 582 // where <extend> is one of {UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX}. 583 // <shift_amount> is uint2_t. 584 inline Operand(Register reg, 585 Extend extend, 586 unsigned shift_amount = 0); 587 588 template<typename T> 589 inline explicit Operand(Handle<T> handle); 590 591 // Implicit constructor for all int types, ExternalReference, and Smi. 592 template<typename T> 593 inline Operand(T t); // NOLINT(runtime/explicit) 594 595 // Implicit constructor for int types. 596 template<typename T> 597 inline Operand(T t, RelocInfo::Mode rmode); 598 599 inline bool IsImmediate() const; 600 inline bool IsShiftedRegister() const; 601 inline bool IsExtendedRegister() const; 602 inline bool IsZero() const; 603 604 // This returns an LSL shift (<= 4) operand as an equivalent extend operand, 605 // which helps in the encoding of instructions that use the stack pointer. 606 inline Operand ToExtendedRegister() const; 607 608 inline Immediate immediate() const; 609 inline int64_t ImmediateValue() const; 610 inline Register reg() const; 611 inline Shift shift() const; 612 inline Extend extend() const; 613 inline unsigned shift_amount() const; 614 615 // Relocation information. 616 bool NeedsRelocation(const Assembler* assembler) const; 617 618 // Helpers 619 inline static Operand UntagSmi(Register smi); 620 inline static Operand UntagSmiAndScale(Register smi, int scale); 621 622 private: 623 Immediate immediate_; 624 Register reg_; 625 Shift shift_; 626 Extend extend_; 627 unsigned shift_amount_; 628 }; 629 630 631 // MemOperand represents a memory operand in a load or store instruction. 632 class MemOperand { 633 public: 634 inline MemOperand(); 635 inline explicit MemOperand(Register base, 636 int64_t offset = 0, 637 AddrMode addrmode = Offset); 638 inline explicit MemOperand(Register base, 639 Register regoffset, 640 Shift shift = LSL, 641 unsigned shift_amount = 0); 642 inline explicit MemOperand(Register base, 643 Register regoffset, 644 Extend extend, 645 unsigned shift_amount = 0); 646 inline explicit MemOperand(Register base, 647 const Operand& offset, 648 AddrMode addrmode = Offset); 649 650 const Register& base() const { return base_; } 651 const Register& regoffset() const { return regoffset_; } 652 int64_t offset() const { return offset_; } 653 AddrMode addrmode() const { return addrmode_; } 654 Shift shift() const { return shift_; } 655 Extend extend() const { return extend_; } 656 unsigned shift_amount() const { return shift_amount_; } 657 inline bool IsImmediateOffset() const; 658 inline bool IsRegisterOffset() const; 659 inline bool IsPreIndex() const; 660 inline bool IsPostIndex() const; 661 662 // For offset modes, return the offset as an Operand. This helper cannot 663 // handle indexed modes. 664 inline Operand OffsetAsOperand() const; 665 666 enum PairResult { 667 kNotPair, // Can't use a pair instruction. 668 kPairAB, // Can use a pair instruction (operandA has lower address). 669 kPairBA // Can use a pair instruction (operandB has lower address). 670 }; 671 // Check if two MemOperand are consistent for stp/ldp use. 672 static PairResult AreConsistentForPair(const MemOperand& operandA, 673 const MemOperand& operandB, 674 int access_size_log2 = kXRegSizeLog2); 675 676 private: 677 Register base_; 678 Register regoffset_; 679 int64_t offset_; 680 AddrMode addrmode_; 681 Shift shift_; 682 Extend extend_; 683 unsigned shift_amount_; 684 }; 685 686 687 class ConstPool { 688 public: 689 explicit ConstPool(Assembler* assm) 690 : assm_(assm), 691 first_use_(-1), 692 shared_entries_count(0) {} 693 void RecordEntry(intptr_t data, RelocInfo::Mode mode); 694 int EntryCount() const { 695 return shared_entries_count + static_cast<int>(unique_entries_.size()); 696 } 697 bool IsEmpty() const { 698 return shared_entries_.empty() && unique_entries_.empty(); 699 } 700 // Distance in bytes between the current pc and the first instruction 701 // using the pool. If there are no pending entries return kMaxInt. 702 int DistanceToFirstUse(); 703 // Offset after which instructions using the pool will be out of range. 704 int MaxPcOffset(); 705 // Maximum size the constant pool can be with current entries. It always 706 // includes alignment padding and branch over. 707 int WorstCaseSize(); 708 // Size in bytes of the literal pool *if* it is emitted at the current 709 // pc. The size will include the branch over the pool if it was requested. 710 int SizeIfEmittedAtCurrentPc(bool require_jump); 711 // Emit the literal pool at the current pc with a branch over the pool if 712 // requested. 713 void Emit(bool require_jump); 714 // Discard any pending pool entries. 715 void Clear(); 716 717 private: 718 bool CanBeShared(RelocInfo::Mode mode); 719 void EmitMarker(); 720 void EmitGuard(); 721 void EmitEntries(); 722 723 Assembler* assm_; 724 // Keep track of the first instruction requiring a constant pool entry 725 // since the previous constant pool was emitted. 726 int first_use_; 727 // values, pc offset(s) of entries which can be shared. 728 std::multimap<uint64_t, int> shared_entries_; 729 // Number of distinct literal in shared entries. 730 int shared_entries_count; 731 // values, pc offset of entries which cannot be shared. 732 std::vector<std::pair<uint64_t, int> > unique_entries_; 733 }; 734 735 736 // ----------------------------------------------------------------------------- 737 // Assembler. 738 739 class Assembler : public AssemblerBase { 740 public: 741 // Create an assembler. Instructions and relocation information are emitted 742 // into a buffer, with the instructions starting from the beginning and the 743 // relocation information starting from the end of the buffer. See CodeDesc 744 // for a detailed comment on the layout (globals.h). 745 // 746 // If the provided buffer is NULL, the assembler allocates and grows its own 747 // buffer, and buffer_size determines the initial buffer size. The buffer is 748 // owned by the assembler and deallocated upon destruction of the assembler. 749 // 750 // If the provided buffer is not NULL, the assembler uses the provided buffer 751 // for code generation and assumes its size to be buffer_size. If the buffer 752 // is too small, a fatal error occurs. No deallocation of the buffer is done 753 // upon destruction of the assembler. 754 Assembler(Isolate* arg_isolate, void* buffer, int buffer_size); 755 756 virtual ~Assembler(); 757 758 virtual void AbortedCodeGeneration() { 759 constpool_.Clear(); 760 } 761 762 // System functions --------------------------------------------------------- 763 // Start generating code from the beginning of the buffer, discarding any code 764 // and data that has already been emitted into the buffer. 765 // 766 // In order to avoid any accidental transfer of state, Reset DCHECKs that the 767 // constant pool is not blocked. 768 void Reset(); 769 770 // GetCode emits any pending (non-emitted) code and fills the descriptor 771 // desc. GetCode() is idempotent; it returns the same result if no other 772 // Assembler functions are invoked in between GetCode() calls. 773 // 774 // The descriptor (desc) can be NULL. In that case, the code is finalized as 775 // usual, but the descriptor is not populated. 776 void GetCode(CodeDesc* desc); 777 778 // Insert the smallest number of nop instructions 779 // possible to align the pc offset to a multiple 780 // of m. m must be a power of 2 (>= 4). 781 void Align(int m); 782 // Insert the smallest number of zero bytes possible to align the pc offset 783 // to a mulitple of m. m must be a power of 2 (>= 2). 784 void DataAlign(int m); 785 786 inline void Unreachable(); 787 788 // Label -------------------------------------------------------------------- 789 // Bind a label to the current pc. Note that labels can only be bound once, 790 // and if labels are linked to other instructions, they _must_ be bound 791 // before they go out of scope. 792 void bind(Label* label); 793 794 795 // RelocInfo and pools ------------------------------------------------------ 796 797 // Record relocation information for current pc_. 798 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 799 800 // Return the address in the constant pool of the code target address used by 801 // the branch/call instruction at pc. 802 inline static Address target_pointer_address_at(Address pc); 803 804 // Read/Modify the code target address in the branch/call instruction at pc. 805 inline static Address target_address_at(Address pc, Address constant_pool); 806 inline static void set_target_address_at( 807 Isolate* isolate, Address pc, Address constant_pool, Address target, 808 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 809 static inline Address target_address_at(Address pc, Code* code); 810 static inline void set_target_address_at( 811 Isolate* isolate, Address pc, Code* code, Address target, 812 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 813 814 // Return the code target address at a call site from the return address of 815 // that call in the instruction stream. 816 inline static Address target_address_from_return_address(Address pc); 817 818 // Given the address of the beginning of a call, return the address in the 819 // instruction stream that call will return from. 820 inline static Address return_address_from_call_start(Address pc); 821 822 // This sets the branch destination (which is in the constant pool on ARM). 823 // This is for calls and branches within generated code. 824 inline static void deserialization_set_special_target_at( 825 Isolate* isolate, Address constant_pool_entry, Code* code, 826 Address target); 827 828 // This sets the internal reference at the pc. 829 inline static void deserialization_set_target_internal_reference_at( 830 Isolate* isolate, Address pc, Address target, 831 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 832 833 // All addresses in the constant pool are the same size as pointers. 834 static const int kSpecialTargetSize = kPointerSize; 835 836 // The sizes of the call sequences emitted by MacroAssembler::Call. 837 // Wherever possible, use MacroAssembler::CallSize instead of these constants, 838 // as it will choose the correct value for a given relocation mode. 839 // 840 // Without relocation: 841 // movz temp, #(target & 0x000000000000ffff) 842 // movk temp, #(target & 0x00000000ffff0000) 843 // movk temp, #(target & 0x0000ffff00000000) 844 // blr temp 845 // 846 // With relocation: 847 // ldr temp, =target 848 // blr temp 849 static const int kCallSizeWithoutRelocation = 4 * kInstructionSize; 850 static const int kCallSizeWithRelocation = 2 * kInstructionSize; 851 852 // Size of the generated code in bytes 853 uint64_t SizeOfGeneratedCode() const { 854 DCHECK((pc_ >= buffer_) && (pc_ < (buffer_ + buffer_size_))); 855 return pc_ - buffer_; 856 } 857 858 // Return the code size generated from label to the current position. 859 uint64_t SizeOfCodeGeneratedSince(const Label* label) { 860 DCHECK(label->is_bound()); 861 DCHECK(pc_offset() >= label->pos()); 862 DCHECK(pc_offset() < buffer_size_); 863 return pc_offset() - label->pos(); 864 } 865 866 // Check the size of the code generated since the given label. This function 867 // is used primarily to work around comparisons between signed and unsigned 868 // quantities, since V8 uses both. 869 // TODO(jbramley): Work out what sign to use for these things and if possible, 870 // change things to be consistent. 871 void AssertSizeOfCodeGeneratedSince(const Label* label, ptrdiff_t size) { 872 DCHECK(size >= 0); 873 DCHECK(static_cast<uint64_t>(size) == SizeOfCodeGeneratedSince(label)); 874 } 875 876 // Return the number of instructions generated from label to the 877 // current position. 878 uint64_t InstructionsGeneratedSince(const Label* label) { 879 return SizeOfCodeGeneratedSince(label) / kInstructionSize; 880 } 881 882 static const int kPatchDebugBreakSlotAddressOffset = 0; 883 884 // Number of instructions necessary to be able to later patch it to a call. 885 static const int kDebugBreakSlotInstructions = 5; 886 static const int kDebugBreakSlotLength = 887 kDebugBreakSlotInstructions * kInstructionSize; 888 889 // Prevent contant pool emission until EndBlockConstPool is called. 890 // Call to this function can be nested but must be followed by an equal 891 // number of call to EndBlockConstpool. 892 void StartBlockConstPool(); 893 894 // Resume constant pool emission. Need to be called as many time as 895 // StartBlockConstPool to have an effect. 896 void EndBlockConstPool(); 897 898 bool is_const_pool_blocked() const; 899 static bool IsConstantPoolAt(Instruction* instr); 900 static int ConstantPoolSizeAt(Instruction* instr); 901 // See Assembler::CheckConstPool for more info. 902 void EmitPoolGuard(); 903 904 // Prevent veneer pool emission until EndBlockVeneerPool is called. 905 // Call to this function can be nested but must be followed by an equal 906 // number of call to EndBlockConstpool. 907 void StartBlockVeneerPool(); 908 909 // Resume constant pool emission. Need to be called as many time as 910 // StartBlockVeneerPool to have an effect. 911 void EndBlockVeneerPool(); 912 913 bool is_veneer_pool_blocked() const { 914 return veneer_pool_blocked_nesting_ > 0; 915 } 916 917 // Block/resume emission of constant pools and veneer pools. 918 void StartBlockPools() { 919 StartBlockConstPool(); 920 StartBlockVeneerPool(); 921 } 922 void EndBlockPools() { 923 EndBlockConstPool(); 924 EndBlockVeneerPool(); 925 } 926 927 // Debugging ---------------------------------------------------------------- 928 AssemblerPositionsRecorder* positions_recorder() { 929 return &positions_recorder_; 930 } 931 void RecordComment(const char* msg); 932 933 // Record a deoptimization reason that can be used by a log or cpu profiler. 934 // Use --trace-deopt to enable. 935 void RecordDeoptReason(const int reason, int raw_position, int id); 936 937 int buffer_space() const; 938 939 // Mark generator continuation. 940 void RecordGeneratorContinuation(); 941 942 // Mark address of a debug break slot. 943 void RecordDebugBreakSlot(RelocInfo::Mode mode); 944 945 // Record the emission of a constant pool. 946 // 947 // The emission of constant and veneer pools depends on the size of the code 948 // generated and the number of RelocInfo recorded. 949 // The Debug mechanism needs to map code offsets between two versions of a 950 // function, compiled with and without debugger support (see for example 951 // Debug::PrepareForBreakPoints()). 952 // Compiling functions with debugger support generates additional code 953 // (DebugCodegen::GenerateSlot()). This may affect the emission of the pools 954 // and cause the version of the code with debugger support to have pools 955 // generated in different places. 956 // Recording the position and size of emitted pools allows to correctly 957 // compute the offset mappings between the different versions of a function in 958 // all situations. 959 // 960 // The parameter indicates the size of the pool (in bytes), including 961 // the marker and branch over the data. 962 void RecordConstPool(int size); 963 964 965 // Instruction set functions ------------------------------------------------ 966 967 // Branch / Jump instructions. 968 // For branches offsets are scaled, i.e. they in instrcutions not in bytes. 969 // Branch to register. 970 void br(const Register& xn); 971 972 // Branch-link to register. 973 void blr(const Register& xn); 974 975 // Branch to register with return hint. 976 void ret(const Register& xn = lr); 977 978 // Unconditional branch to label. 979 void b(Label* label); 980 981 // Conditional branch to label. 982 void b(Label* label, Condition cond); 983 984 // Unconditional branch to PC offset. 985 void b(int imm26); 986 987 // Conditional branch to PC offset. 988 void b(int imm19, Condition cond); 989 990 // Branch-link to label / pc offset. 991 void bl(Label* label); 992 void bl(int imm26); 993 994 // Compare and branch to label / pc offset if zero. 995 void cbz(const Register& rt, Label* label); 996 void cbz(const Register& rt, int imm19); 997 998 // Compare and branch to label / pc offset if not zero. 999 void cbnz(const Register& rt, Label* label); 1000 void cbnz(const Register& rt, int imm19); 1001 1002 // Test bit and branch to label / pc offset if zero. 1003 void tbz(const Register& rt, unsigned bit_pos, Label* label); 1004 void tbz(const Register& rt, unsigned bit_pos, int imm14); 1005 1006 // Test bit and branch to label / pc offset if not zero. 1007 void tbnz(const Register& rt, unsigned bit_pos, Label* label); 1008 void tbnz(const Register& rt, unsigned bit_pos, int imm14); 1009 1010 // Address calculation instructions. 1011 // Calculate a PC-relative address. Unlike for branches the offset in adr is 1012 // unscaled (i.e. the result can be unaligned). 1013 void adr(const Register& rd, Label* label); 1014 void adr(const Register& rd, int imm21); 1015 1016 // Data Processing instructions. 1017 // Add. 1018 void add(const Register& rd, 1019 const Register& rn, 1020 const Operand& operand); 1021 1022 // Add and update status flags. 1023 void adds(const Register& rd, 1024 const Register& rn, 1025 const Operand& operand); 1026 1027 // Compare negative. 1028 void cmn(const Register& rn, const Operand& operand); 1029 1030 // Subtract. 1031 void sub(const Register& rd, 1032 const Register& rn, 1033 const Operand& operand); 1034 1035 // Subtract and update status flags. 1036 void subs(const Register& rd, 1037 const Register& rn, 1038 const Operand& operand); 1039 1040 // Compare. 1041 void cmp(const Register& rn, const Operand& operand); 1042 1043 // Negate. 1044 void neg(const Register& rd, 1045 const Operand& operand); 1046 1047 // Negate and update status flags. 1048 void negs(const Register& rd, 1049 const Operand& operand); 1050 1051 // Add with carry bit. 1052 void adc(const Register& rd, 1053 const Register& rn, 1054 const Operand& operand); 1055 1056 // Add with carry bit and update status flags. 1057 void adcs(const Register& rd, 1058 const Register& rn, 1059 const Operand& operand); 1060 1061 // Subtract with carry bit. 1062 void sbc(const Register& rd, 1063 const Register& rn, 1064 const Operand& operand); 1065 1066 // Subtract with carry bit and update status flags. 1067 void sbcs(const Register& rd, 1068 const Register& rn, 1069 const Operand& operand); 1070 1071 // Negate with carry bit. 1072 void ngc(const Register& rd, 1073 const Operand& operand); 1074 1075 // Negate with carry bit and update status flags. 1076 void ngcs(const Register& rd, 1077 const Operand& operand); 1078 1079 // Logical instructions. 1080 // Bitwise and (A & B). 1081 void and_(const Register& rd, 1082 const Register& rn, 1083 const Operand& operand); 1084 1085 // Bitwise and (A & B) and update status flags. 1086 void ands(const Register& rd, 1087 const Register& rn, 1088 const Operand& operand); 1089 1090 // Bit test, and set flags. 1091 void tst(const Register& rn, const Operand& operand); 1092 1093 // Bit clear (A & ~B). 1094 void bic(const Register& rd, 1095 const Register& rn, 1096 const Operand& operand); 1097 1098 // Bit clear (A & ~B) and update status flags. 1099 void bics(const Register& rd, 1100 const Register& rn, 1101 const Operand& operand); 1102 1103 // Bitwise or (A | B). 1104 void orr(const Register& rd, const Register& rn, const Operand& operand); 1105 1106 // Bitwise nor (A | ~B). 1107 void orn(const Register& rd, const Register& rn, const Operand& operand); 1108 1109 // Bitwise eor/xor (A ^ B). 1110 void eor(const Register& rd, const Register& rn, const Operand& operand); 1111 1112 // Bitwise enor/xnor (A ^ ~B). 1113 void eon(const Register& rd, const Register& rn, const Operand& operand); 1114 1115 // Logical shift left variable. 1116 void lslv(const Register& rd, const Register& rn, const Register& rm); 1117 1118 // Logical shift right variable. 1119 void lsrv(const Register& rd, const Register& rn, const Register& rm); 1120 1121 // Arithmetic shift right variable. 1122 void asrv(const Register& rd, const Register& rn, const Register& rm); 1123 1124 // Rotate right variable. 1125 void rorv(const Register& rd, const Register& rn, const Register& rm); 1126 1127 // Bitfield instructions. 1128 // Bitfield move. 1129 void bfm(const Register& rd, const Register& rn, int immr, int imms); 1130 1131 // Signed bitfield move. 1132 void sbfm(const Register& rd, const Register& rn, int immr, int imms); 1133 1134 // Unsigned bitfield move. 1135 void ubfm(const Register& rd, const Register& rn, int immr, int imms); 1136 1137 // Bfm aliases. 1138 // Bitfield insert. 1139 void bfi(const Register& rd, const Register& rn, int lsb, int width) { 1140 DCHECK(width >= 1); 1141 DCHECK(lsb + width <= rn.SizeInBits()); 1142 bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); 1143 } 1144 1145 // Bitfield extract and insert low. 1146 void bfxil(const Register& rd, const Register& rn, int lsb, int width) { 1147 DCHECK(width >= 1); 1148 DCHECK(lsb + width <= rn.SizeInBits()); 1149 bfm(rd, rn, lsb, lsb + width - 1); 1150 } 1151 1152 // Sbfm aliases. 1153 // Arithmetic shift right. 1154 void asr(const Register& rd, const Register& rn, int shift) { 1155 DCHECK(shift < rd.SizeInBits()); 1156 sbfm(rd, rn, shift, rd.SizeInBits() - 1); 1157 } 1158 1159 // Signed bitfield insert in zero. 1160 void sbfiz(const Register& rd, const Register& rn, int lsb, int width) { 1161 DCHECK(width >= 1); 1162 DCHECK(lsb + width <= rn.SizeInBits()); 1163 sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); 1164 } 1165 1166 // Signed bitfield extract. 1167 void sbfx(const Register& rd, const Register& rn, int lsb, int width) { 1168 DCHECK(width >= 1); 1169 DCHECK(lsb + width <= rn.SizeInBits()); 1170 sbfm(rd, rn, lsb, lsb + width - 1); 1171 } 1172 1173 // Signed extend byte. 1174 void sxtb(const Register& rd, const Register& rn) { 1175 sbfm(rd, rn, 0, 7); 1176 } 1177 1178 // Signed extend halfword. 1179 void sxth(const Register& rd, const Register& rn) { 1180 sbfm(rd, rn, 0, 15); 1181 } 1182 1183 // Signed extend word. 1184 void sxtw(const Register& rd, const Register& rn) { 1185 sbfm(rd, rn, 0, 31); 1186 } 1187 1188 // Ubfm aliases. 1189 // Logical shift left. 1190 void lsl(const Register& rd, const Register& rn, int shift) { 1191 int reg_size = rd.SizeInBits(); 1192 DCHECK(shift < reg_size); 1193 ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1); 1194 } 1195 1196 // Logical shift right. 1197 void lsr(const Register& rd, const Register& rn, int shift) { 1198 DCHECK(shift < rd.SizeInBits()); 1199 ubfm(rd, rn, shift, rd.SizeInBits() - 1); 1200 } 1201 1202 // Unsigned bitfield insert in zero. 1203 void ubfiz(const Register& rd, const Register& rn, int lsb, int width) { 1204 DCHECK(width >= 1); 1205 DCHECK(lsb + width <= rn.SizeInBits()); 1206 ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); 1207 } 1208 1209 // Unsigned bitfield extract. 1210 void ubfx(const Register& rd, const Register& rn, int lsb, int width) { 1211 DCHECK(width >= 1); 1212 DCHECK(lsb + width <= rn.SizeInBits()); 1213 ubfm(rd, rn, lsb, lsb + width - 1); 1214 } 1215 1216 // Unsigned extend byte. 1217 void uxtb(const Register& rd, const Register& rn) { 1218 ubfm(rd, rn, 0, 7); 1219 } 1220 1221 // Unsigned extend halfword. 1222 void uxth(const Register& rd, const Register& rn) { 1223 ubfm(rd, rn, 0, 15); 1224 } 1225 1226 // Unsigned extend word. 1227 void uxtw(const Register& rd, const Register& rn) { 1228 ubfm(rd, rn, 0, 31); 1229 } 1230 1231 // Extract. 1232 void extr(const Register& rd, const Register& rn, const Register& rm, 1233 int lsb); 1234 1235 // Conditional select: rd = cond ? rn : rm. 1236 void csel(const Register& rd, 1237 const Register& rn, 1238 const Register& rm, 1239 Condition cond); 1240 1241 // Conditional select increment: rd = cond ? rn : rm + 1. 1242 void csinc(const Register& rd, 1243 const Register& rn, 1244 const Register& rm, 1245 Condition cond); 1246 1247 // Conditional select inversion: rd = cond ? rn : ~rm. 1248 void csinv(const Register& rd, 1249 const Register& rn, 1250 const Register& rm, 1251 Condition cond); 1252 1253 // Conditional select negation: rd = cond ? rn : -rm. 1254 void csneg(const Register& rd, 1255 const Register& rn, 1256 const Register& rm, 1257 Condition cond); 1258 1259 // Conditional set: rd = cond ? 1 : 0. 1260 void cset(const Register& rd, Condition cond); 1261 1262 // Conditional set minus: rd = cond ? -1 : 0. 1263 void csetm(const Register& rd, Condition cond); 1264 1265 // Conditional increment: rd = cond ? rn + 1 : rn. 1266 void cinc(const Register& rd, const Register& rn, Condition cond); 1267 1268 // Conditional invert: rd = cond ? ~rn : rn. 1269 void cinv(const Register& rd, const Register& rn, Condition cond); 1270 1271 // Conditional negate: rd = cond ? -rn : rn. 1272 void cneg(const Register& rd, const Register& rn, Condition cond); 1273 1274 // Extr aliases. 1275 void ror(const Register& rd, const Register& rs, unsigned shift) { 1276 extr(rd, rs, rs, shift); 1277 } 1278 1279 // Conditional comparison. 1280 // Conditional compare negative. 1281 void ccmn(const Register& rn, 1282 const Operand& operand, 1283 StatusFlags nzcv, 1284 Condition cond); 1285 1286 // Conditional compare. 1287 void ccmp(const Register& rn, 1288 const Operand& operand, 1289 StatusFlags nzcv, 1290 Condition cond); 1291 1292 // Multiplication. 1293 // 32 x 32 -> 32-bit and 64 x 64 -> 64-bit multiply. 1294 void mul(const Register& rd, const Register& rn, const Register& rm); 1295 1296 // 32 + 32 x 32 -> 32-bit and 64 + 64 x 64 -> 64-bit multiply accumulate. 1297 void madd(const Register& rd, 1298 const Register& rn, 1299 const Register& rm, 1300 const Register& ra); 1301 1302 // -(32 x 32) -> 32-bit and -(64 x 64) -> 64-bit multiply. 1303 void mneg(const Register& rd, const Register& rn, const Register& rm); 1304 1305 // 32 - 32 x 32 -> 32-bit and 64 - 64 x 64 -> 64-bit multiply subtract. 1306 void msub(const Register& rd, 1307 const Register& rn, 1308 const Register& rm, 1309 const Register& ra); 1310 1311 // 32 x 32 -> 64-bit multiply. 1312 void smull(const Register& rd, const Register& rn, const Register& rm); 1313 1314 // Xd = bits<127:64> of Xn * Xm. 1315 void smulh(const Register& rd, const Register& rn, const Register& rm); 1316 1317 // Signed 32 x 32 -> 64-bit multiply and accumulate. 1318 void smaddl(const Register& rd, 1319 const Register& rn, 1320 const Register& rm, 1321 const Register& ra); 1322 1323 // Unsigned 32 x 32 -> 64-bit multiply and accumulate. 1324 void umaddl(const Register& rd, 1325 const Register& rn, 1326 const Register& rm, 1327 const Register& ra); 1328 1329 // Signed 32 x 32 -> 64-bit multiply and subtract. 1330 void smsubl(const Register& rd, 1331 const Register& rn, 1332 const Register& rm, 1333 const Register& ra); 1334 1335 // Unsigned 32 x 32 -> 64-bit multiply and subtract. 1336 void umsubl(const Register& rd, 1337 const Register& rn, 1338 const Register& rm, 1339 const Register& ra); 1340 1341 // Signed integer divide. 1342 void sdiv(const Register& rd, const Register& rn, const Register& rm); 1343 1344 // Unsigned integer divide. 1345 void udiv(const Register& rd, const Register& rn, const Register& rm); 1346 1347 // Bit count, bit reverse and endian reverse. 1348 void rbit(const Register& rd, const Register& rn); 1349 void rev16(const Register& rd, const Register& rn); 1350 void rev32(const Register& rd, const Register& rn); 1351 void rev(const Register& rd, const Register& rn); 1352 void clz(const Register& rd, const Register& rn); 1353 void cls(const Register& rd, const Register& rn); 1354 1355 // Memory instructions. 1356 1357 // Load integer or FP register. 1358 void ldr(const CPURegister& rt, const MemOperand& src); 1359 1360 // Store integer or FP register. 1361 void str(const CPURegister& rt, const MemOperand& dst); 1362 1363 // Load word with sign extension. 1364 void ldrsw(const Register& rt, const MemOperand& src); 1365 1366 // Load byte. 1367 void ldrb(const Register& rt, const MemOperand& src); 1368 1369 // Store byte. 1370 void strb(const Register& rt, const MemOperand& dst); 1371 1372 // Load byte with sign extension. 1373 void ldrsb(const Register& rt, const MemOperand& src); 1374 1375 // Load half-word. 1376 void ldrh(const Register& rt, const MemOperand& src); 1377 1378 // Store half-word. 1379 void strh(const Register& rt, const MemOperand& dst); 1380 1381 // Load half-word with sign extension. 1382 void ldrsh(const Register& rt, const MemOperand& src); 1383 1384 // Load integer or FP register pair. 1385 void ldp(const CPURegister& rt, const CPURegister& rt2, 1386 const MemOperand& src); 1387 1388 // Store integer or FP register pair. 1389 void stp(const CPURegister& rt, const CPURegister& rt2, 1390 const MemOperand& dst); 1391 1392 // Load word pair with sign extension. 1393 void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src); 1394 1395 // Load literal to register from a pc relative address. 1396 void ldr_pcrel(const CPURegister& rt, int imm19); 1397 1398 // Load literal to register. 1399 void ldr(const CPURegister& rt, const Immediate& imm); 1400 1401 // Load-acquire word. 1402 void ldar(const Register& rt, const Register& rn); 1403 1404 // Load-acquire exclusive word. 1405 void ldaxr(const Register& rt, const Register& rn); 1406 1407 // Store-release word. 1408 void stlr(const Register& rt, const Register& rn); 1409 1410 // Store-release exclusive word. 1411 void stlxr(const Register& rs, const Register& rt, const Register& rn); 1412 1413 // Load-acquire byte. 1414 void ldarb(const Register& rt, const Register& rn); 1415 1416 // Load-acquire exclusive byte. 1417 void ldaxrb(const Register& rt, const Register& rn); 1418 1419 // Store-release byte. 1420 void stlrb(const Register& rt, const Register& rn); 1421 1422 // Store-release exclusive byte. 1423 void stlxrb(const Register& rs, const Register& rt, const Register& rn); 1424 1425 // Load-acquire half-word. 1426 void ldarh(const Register& rt, const Register& rn); 1427 1428 // Load-acquire exclusive half-word. 1429 void ldaxrh(const Register& rt, const Register& rn); 1430 1431 // Store-release half-word. 1432 void stlrh(const Register& rt, const Register& rn); 1433 1434 // Store-release exclusive half-word. 1435 void stlxrh(const Register& rs, const Register& rt, const Register& rn); 1436 1437 // Move instructions. The default shift of -1 indicates that the move 1438 // instruction will calculate an appropriate 16-bit immediate and left shift 1439 // that is equal to the 64-bit immediate argument. If an explicit left shift 1440 // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value. 1441 // 1442 // For movk, an explicit shift can be used to indicate which half word should 1443 // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant 1444 // half word with zero, whereas movk(x0, 0, 48) will overwrite the 1445 // most-significant. 1446 1447 // Move and keep. 1448 void movk(const Register& rd, uint64_t imm, int shift = -1) { 1449 MoveWide(rd, imm, shift, MOVK); 1450 } 1451 1452 // Move with non-zero. 1453 void movn(const Register& rd, uint64_t imm, int shift = -1) { 1454 MoveWide(rd, imm, shift, MOVN); 1455 } 1456 1457 // Move with zero. 1458 void movz(const Register& rd, uint64_t imm, int shift = -1) { 1459 MoveWide(rd, imm, shift, MOVZ); 1460 } 1461 1462 // Misc instructions. 1463 // Monitor debug-mode breakpoint. 1464 void brk(int code); 1465 1466 // Halting debug-mode breakpoint. 1467 void hlt(int code); 1468 1469 // Move register to register. 1470 void mov(const Register& rd, const Register& rn); 1471 1472 // Move NOT(operand) to register. 1473 void mvn(const Register& rd, const Operand& operand); 1474 1475 // System instructions. 1476 // Move to register from system register. 1477 void mrs(const Register& rt, SystemRegister sysreg); 1478 1479 // Move from register to system register. 1480 void msr(SystemRegister sysreg, const Register& rt); 1481 1482 // System hint. 1483 void hint(SystemHint code); 1484 1485 // Data memory barrier 1486 void dmb(BarrierDomain domain, BarrierType type); 1487 1488 // Data synchronization barrier 1489 void dsb(BarrierDomain domain, BarrierType type); 1490 1491 // Instruction synchronization barrier 1492 void isb(); 1493 1494 // Alias for system instructions. 1495 void nop() { hint(NOP); } 1496 1497 // Different nop operations are used by the code generator to detect certain 1498 // states of the generated code. 1499 enum NopMarkerTypes { 1500 DEBUG_BREAK_NOP, 1501 INTERRUPT_CODE_NOP, 1502 ADR_FAR_NOP, 1503 FIRST_NOP_MARKER = DEBUG_BREAK_NOP, 1504 LAST_NOP_MARKER = ADR_FAR_NOP 1505 }; 1506 1507 void nop(NopMarkerTypes n) { 1508 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER)); 1509 mov(Register::XRegFromCode(n), Register::XRegFromCode(n)); 1510 } 1511 1512 // FP instructions. 1513 // Move immediate to FP register. 1514 void fmov(FPRegister fd, double imm); 1515 void fmov(FPRegister fd, float imm); 1516 1517 // Move FP register to register. 1518 void fmov(Register rd, FPRegister fn); 1519 1520 // Move register to FP register. 1521 void fmov(FPRegister fd, Register rn); 1522 1523 // Move FP register to FP register. 1524 void fmov(FPRegister fd, FPRegister fn); 1525 1526 // FP add. 1527 void fadd(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1528 1529 // FP subtract. 1530 void fsub(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1531 1532 // FP multiply. 1533 void fmul(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1534 1535 // FP fused multiply and add. 1536 void fmadd(const FPRegister& fd, 1537 const FPRegister& fn, 1538 const FPRegister& fm, 1539 const FPRegister& fa); 1540 1541 // FP fused multiply and subtract. 1542 void fmsub(const FPRegister& fd, 1543 const FPRegister& fn, 1544 const FPRegister& fm, 1545 const FPRegister& fa); 1546 1547 // FP fused multiply, add and negate. 1548 void fnmadd(const FPRegister& fd, 1549 const FPRegister& fn, 1550 const FPRegister& fm, 1551 const FPRegister& fa); 1552 1553 // FP fused multiply, subtract and negate. 1554 void fnmsub(const FPRegister& fd, 1555 const FPRegister& fn, 1556 const FPRegister& fm, 1557 const FPRegister& fa); 1558 1559 // FP divide. 1560 void fdiv(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1561 1562 // FP maximum. 1563 void fmax(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1564 1565 // FP minimum. 1566 void fmin(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1567 1568 // FP maximum. 1569 void fmaxnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1570 1571 // FP minimum. 1572 void fminnm(const FPRegister& fd, const FPRegister& fn, const FPRegister& fm); 1573 1574 // FP absolute. 1575 void fabs(const FPRegister& fd, const FPRegister& fn); 1576 1577 // FP negate. 1578 void fneg(const FPRegister& fd, const FPRegister& fn); 1579 1580 // FP square root. 1581 void fsqrt(const FPRegister& fd, const FPRegister& fn); 1582 1583 // FP round to integer (nearest with ties to away). 1584 void frinta(const FPRegister& fd, const FPRegister& fn); 1585 1586 // FP round to integer (toward minus infinity). 1587 void frintm(const FPRegister& fd, const FPRegister& fn); 1588 1589 // FP round to integer (nearest with ties to even). 1590 void frintn(const FPRegister& fd, const FPRegister& fn); 1591 1592 // FP round to integer (towards plus infinity). 1593 void frintp(const FPRegister& fd, const FPRegister& fn); 1594 1595 // FP round to integer (towards zero.) 1596 void frintz(const FPRegister& fd, const FPRegister& fn); 1597 1598 // FP compare registers. 1599 void fcmp(const FPRegister& fn, const FPRegister& fm); 1600 1601 // FP compare immediate. 1602 void fcmp(const FPRegister& fn, double value); 1603 1604 // FP conditional compare. 1605 void fccmp(const FPRegister& fn, 1606 const FPRegister& fm, 1607 StatusFlags nzcv, 1608 Condition cond); 1609 1610 // FP conditional select. 1611 void fcsel(const FPRegister& fd, 1612 const FPRegister& fn, 1613 const FPRegister& fm, 1614 Condition cond); 1615 1616 // Common FP Convert function 1617 void FPConvertToInt(const Register& rd, 1618 const FPRegister& fn, 1619 FPIntegerConvertOp op); 1620 1621 // FP convert between single and double precision. 1622 void fcvt(const FPRegister& fd, const FPRegister& fn); 1623 1624 // Convert FP to unsigned integer (nearest with ties to away). 1625 void fcvtau(const Register& rd, const FPRegister& fn); 1626 1627 // Convert FP to signed integer (nearest with ties to away). 1628 void fcvtas(const Register& rd, const FPRegister& fn); 1629 1630 // Convert FP to unsigned integer (round towards -infinity). 1631 void fcvtmu(const Register& rd, const FPRegister& fn); 1632 1633 // Convert FP to signed integer (round towards -infinity). 1634 void fcvtms(const Register& rd, const FPRegister& fn); 1635 1636 // Convert FP to unsigned integer (nearest with ties to even). 1637 void fcvtnu(const Register& rd, const FPRegister& fn); 1638 1639 // Convert FP to signed integer (nearest with ties to even). 1640 void fcvtns(const Register& rd, const FPRegister& fn); 1641 1642 // Convert FP to unsigned integer (round towards zero). 1643 void fcvtzu(const Register& rd, const FPRegister& fn); 1644 1645 // Convert FP to signed integer (rounf towards zero). 1646 void fcvtzs(const Register& rd, const FPRegister& fn); 1647 1648 // Convert signed integer or fixed point to FP. 1649 void scvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 1650 1651 // Convert unsigned integer or fixed point to FP. 1652 void ucvtf(const FPRegister& fd, const Register& rn, unsigned fbits = 0); 1653 1654 // Instruction functions used only for test, debug, and patching. 1655 // Emit raw instructions in the instruction stream. 1656 void dci(Instr raw_inst) { Emit(raw_inst); } 1657 1658 // Emit 8 bits of data in the instruction stream. 1659 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); } 1660 1661 // Emit 32 bits of data in the instruction stream. 1662 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); } 1663 1664 // Emit 64 bits of data in the instruction stream. 1665 void dc64(uint64_t data) { EmitData(&data, sizeof(data)); } 1666 1667 // Emit an address in the instruction stream. 1668 void dcptr(Label* label); 1669 1670 // Copy a string into the instruction stream, including the terminating NULL 1671 // character. The instruction pointer (pc_) is then aligned correctly for 1672 // subsequent instructions. 1673 void EmitStringData(const char* string); 1674 1675 // Pseudo-instructions ------------------------------------------------------ 1676 1677 // Parameters are described in arm64/instructions-arm64.h. 1678 void debug(const char* message, uint32_t code, Instr params = BREAK); 1679 1680 // Required by V8. 1681 void dd(uint32_t data) { dc32(data); } 1682 void db(uint8_t data) { dc8(data); } 1683 void dq(uint64_t data) { dc64(data); } 1684 void dp(uintptr_t data) { dc64(data); } 1685 1686 // Code generation helpers -------------------------------------------------- 1687 1688 bool IsConstPoolEmpty() const { return constpool_.IsEmpty(); } 1689 1690 Instruction* pc() const { return Instruction::Cast(pc_); } 1691 1692 Instruction* InstructionAt(ptrdiff_t offset) const { 1693 return reinterpret_cast<Instruction*>(buffer_ + offset); 1694 } 1695 1696 ptrdiff_t InstructionOffset(Instruction* instr) const { 1697 return reinterpret_cast<byte*>(instr) - buffer_; 1698 } 1699 1700 // Register encoding. 1701 static Instr Rd(CPURegister rd) { 1702 DCHECK(rd.code() != kSPRegInternalCode); 1703 return rd.code() << Rd_offset; 1704 } 1705 1706 static Instr Rn(CPURegister rn) { 1707 DCHECK(rn.code() != kSPRegInternalCode); 1708 return rn.code() << Rn_offset; 1709 } 1710 1711 static Instr Rm(CPURegister rm) { 1712 DCHECK(rm.code() != kSPRegInternalCode); 1713 return rm.code() << Rm_offset; 1714 } 1715 1716 static Instr Ra(CPURegister ra) { 1717 DCHECK(ra.code() != kSPRegInternalCode); 1718 return ra.code() << Ra_offset; 1719 } 1720 1721 static Instr Rt(CPURegister rt) { 1722 DCHECK(rt.code() != kSPRegInternalCode); 1723 return rt.code() << Rt_offset; 1724 } 1725 1726 static Instr Rt2(CPURegister rt2) { 1727 DCHECK(rt2.code() != kSPRegInternalCode); 1728 return rt2.code() << Rt2_offset; 1729 } 1730 1731 static Instr Rs(CPURegister rs) { 1732 DCHECK(rs.code() != kSPRegInternalCode); 1733 return rs.code() << Rs_offset; 1734 } 1735 1736 // These encoding functions allow the stack pointer to be encoded, and 1737 // disallow the zero register. 1738 static Instr RdSP(Register rd) { 1739 DCHECK(!rd.IsZero()); 1740 return (rd.code() & kRegCodeMask) << Rd_offset; 1741 } 1742 1743 static Instr RnSP(Register rn) { 1744 DCHECK(!rn.IsZero()); 1745 return (rn.code() & kRegCodeMask) << Rn_offset; 1746 } 1747 1748 // Flags encoding. 1749 inline static Instr Flags(FlagsUpdate S); 1750 inline static Instr Cond(Condition cond); 1751 1752 // PC-relative address encoding. 1753 inline static Instr ImmPCRelAddress(int imm21); 1754 1755 // Branch encoding. 1756 inline static Instr ImmUncondBranch(int imm26); 1757 inline static Instr ImmCondBranch(int imm19); 1758 inline static Instr ImmCmpBranch(int imm19); 1759 inline static Instr ImmTestBranch(int imm14); 1760 inline static Instr ImmTestBranchBit(unsigned bit_pos); 1761 1762 // Data Processing encoding. 1763 inline static Instr SF(Register rd); 1764 inline static Instr ImmAddSub(int imm); 1765 inline static Instr ImmS(unsigned imms, unsigned reg_size); 1766 inline static Instr ImmR(unsigned immr, unsigned reg_size); 1767 inline static Instr ImmSetBits(unsigned imms, unsigned reg_size); 1768 inline static Instr ImmRotate(unsigned immr, unsigned reg_size); 1769 inline static Instr ImmLLiteral(int imm19); 1770 inline static Instr BitN(unsigned bitn, unsigned reg_size); 1771 inline static Instr ShiftDP(Shift shift); 1772 inline static Instr ImmDPShift(unsigned amount); 1773 inline static Instr ExtendMode(Extend extend); 1774 inline static Instr ImmExtendShift(unsigned left_shift); 1775 inline static Instr ImmCondCmp(unsigned imm); 1776 inline static Instr Nzcv(StatusFlags nzcv); 1777 1778 static bool IsImmAddSub(int64_t immediate); 1779 static bool IsImmLogical(uint64_t value, 1780 unsigned width, 1781 unsigned* n, 1782 unsigned* imm_s, 1783 unsigned* imm_r); 1784 1785 // MemOperand offset encoding. 1786 inline static Instr ImmLSUnsigned(int imm12); 1787 inline static Instr ImmLS(int imm9); 1788 inline static Instr ImmLSPair(int imm7, LSDataSize size); 1789 inline static Instr ImmShiftLS(unsigned shift_amount); 1790 inline static Instr ImmException(int imm16); 1791 inline static Instr ImmSystemRegister(int imm15); 1792 inline static Instr ImmHint(int imm7); 1793 inline static Instr ImmBarrierDomain(int imm2); 1794 inline static Instr ImmBarrierType(int imm2); 1795 inline static LSDataSize CalcLSDataSize(LoadStoreOp op); 1796 1797 static bool IsImmLSUnscaled(int64_t offset); 1798 static bool IsImmLSScaled(int64_t offset, LSDataSize size); 1799 static bool IsImmLLiteral(int64_t offset); 1800 1801 // Move immediates encoding. 1802 inline static Instr ImmMoveWide(int imm); 1803 inline static Instr ShiftMoveWide(int shift); 1804 1805 // FP Immediates. 1806 static Instr ImmFP32(float imm); 1807 static Instr ImmFP64(double imm); 1808 inline static Instr FPScale(unsigned scale); 1809 1810 // FP register type. 1811 inline static Instr FPType(FPRegister fd); 1812 1813 // Class for scoping postponing the constant pool generation. 1814 class BlockConstPoolScope { 1815 public: 1816 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) { 1817 assem_->StartBlockConstPool(); 1818 } 1819 ~BlockConstPoolScope() { 1820 assem_->EndBlockConstPool(); 1821 } 1822 1823 private: 1824 Assembler* assem_; 1825 1826 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); 1827 }; 1828 1829 // Check if is time to emit a constant pool. 1830 void CheckConstPool(bool force_emit, bool require_jump); 1831 1832 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1833 ConstantPoolEntry::Access access, 1834 ConstantPoolEntry::Type type) { 1835 // No embedded constant pool support. 1836 UNREACHABLE(); 1837 } 1838 1839 // Returns true if we should emit a veneer as soon as possible for a branch 1840 // which can at most reach to specified pc. 1841 bool ShouldEmitVeneer(int max_reachable_pc, 1842 int margin = kVeneerDistanceMargin); 1843 bool ShouldEmitVeneers(int margin = kVeneerDistanceMargin) { 1844 return ShouldEmitVeneer(unresolved_branches_first_limit(), margin); 1845 } 1846 1847 // The maximum code size generated for a veneer. Currently one branch 1848 // instruction. This is for code size checking purposes, and can be extended 1849 // in the future for example if we decide to add nops between the veneers. 1850 static const int kMaxVeneerCodeSize = 1 * kInstructionSize; 1851 1852 void RecordVeneerPool(int location_offset, int size); 1853 // Emits veneers for branches that are approaching their maximum range. 1854 // If need_protection is true, the veneers are protected by a branch jumping 1855 // over the code. 1856 void EmitVeneers(bool force_emit, bool need_protection, 1857 int margin = kVeneerDistanceMargin); 1858 void EmitVeneersGuard() { EmitPoolGuard(); } 1859 // Checks whether veneers need to be emitted at this point. 1860 // If force_emit is set, a veneer is generated for *all* unresolved branches. 1861 void CheckVeneerPool(bool force_emit, bool require_jump, 1862 int margin = kVeneerDistanceMargin); 1863 1864 class BlockPoolsScope { 1865 public: 1866 explicit BlockPoolsScope(Assembler* assem) : assem_(assem) { 1867 assem_->StartBlockPools(); 1868 } 1869 ~BlockPoolsScope() { 1870 assem_->EndBlockPools(); 1871 } 1872 1873 private: 1874 Assembler* assem_; 1875 1876 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); 1877 }; 1878 1879 protected: 1880 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; 1881 1882 void LoadStore(const CPURegister& rt, 1883 const MemOperand& addr, 1884 LoadStoreOp op); 1885 1886 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2, 1887 const MemOperand& addr, LoadStorePairOp op); 1888 static bool IsImmLSPair(int64_t offset, LSDataSize size); 1889 1890 void Logical(const Register& rd, 1891 const Register& rn, 1892 const Operand& operand, 1893 LogicalOp op); 1894 void LogicalImmediate(const Register& rd, 1895 const Register& rn, 1896 unsigned n, 1897 unsigned imm_s, 1898 unsigned imm_r, 1899 LogicalOp op); 1900 1901 void ConditionalCompare(const Register& rn, 1902 const Operand& operand, 1903 StatusFlags nzcv, 1904 Condition cond, 1905 ConditionalCompareOp op); 1906 static bool IsImmConditionalCompare(int64_t immediate); 1907 1908 void AddSubWithCarry(const Register& rd, 1909 const Register& rn, 1910 const Operand& operand, 1911 FlagsUpdate S, 1912 AddSubWithCarryOp op); 1913 1914 // Functions for emulating operands not directly supported by the instruction 1915 // set. 1916 void EmitShift(const Register& rd, 1917 const Register& rn, 1918 Shift shift, 1919 unsigned amount); 1920 void EmitExtendShift(const Register& rd, 1921 const Register& rn, 1922 Extend extend, 1923 unsigned left_shift); 1924 1925 void AddSub(const Register& rd, 1926 const Register& rn, 1927 const Operand& operand, 1928 FlagsUpdate S, 1929 AddSubOp op); 1930 1931 static bool IsImmFP32(float imm); 1932 static bool IsImmFP64(double imm); 1933 1934 // Find an appropriate LoadStoreOp or LoadStorePairOp for the specified 1935 // registers. Only simple loads are supported; sign- and zero-extension (such 1936 // as in LDPSW_x or LDRB_w) are not supported. 1937 static inline LoadStoreOp LoadOpFor(const CPURegister& rt); 1938 static inline LoadStorePairOp LoadPairOpFor(const CPURegister& rt, 1939 const CPURegister& rt2); 1940 static inline LoadStoreOp StoreOpFor(const CPURegister& rt); 1941 static inline LoadStorePairOp StorePairOpFor(const CPURegister& rt, 1942 const CPURegister& rt2); 1943 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt); 1944 1945 // Remove the specified branch from the unbound label link chain. 1946 // If available, a veneer for this label can be used for other branches in the 1947 // chain if the link chain cannot be fixed up without this branch. 1948 void RemoveBranchFromLabelLinkChain(Instruction* branch, 1949 Label* label, 1950 Instruction* label_veneer = NULL); 1951 1952 private: 1953 // Instruction helpers. 1954 void MoveWide(const Register& rd, 1955 uint64_t imm, 1956 int shift, 1957 MoveWideImmediateOp mov_op); 1958 void DataProcShiftedRegister(const Register& rd, 1959 const Register& rn, 1960 const Operand& operand, 1961 FlagsUpdate S, 1962 Instr op); 1963 void DataProcExtendedRegister(const Register& rd, 1964 const Register& rn, 1965 const Operand& operand, 1966 FlagsUpdate S, 1967 Instr op); 1968 void ConditionalSelect(const Register& rd, 1969 const Register& rn, 1970 const Register& rm, 1971 Condition cond, 1972 ConditionalSelectOp op); 1973 void DataProcessing1Source(const Register& rd, 1974 const Register& rn, 1975 DataProcessing1SourceOp op); 1976 void DataProcessing3Source(const Register& rd, 1977 const Register& rn, 1978 const Register& rm, 1979 const Register& ra, 1980 DataProcessing3SourceOp op); 1981 void FPDataProcessing1Source(const FPRegister& fd, 1982 const FPRegister& fn, 1983 FPDataProcessing1SourceOp op); 1984 void FPDataProcessing2Source(const FPRegister& fd, 1985 const FPRegister& fn, 1986 const FPRegister& fm, 1987 FPDataProcessing2SourceOp op); 1988 void FPDataProcessing3Source(const FPRegister& fd, 1989 const FPRegister& fn, 1990 const FPRegister& fm, 1991 const FPRegister& fa, 1992 FPDataProcessing3SourceOp op); 1993 1994 // Label helpers. 1995 1996 // Return an offset for a label-referencing instruction, typically a branch. 1997 int LinkAndGetByteOffsetTo(Label* label); 1998 1999 // This is the same as LinkAndGetByteOffsetTo, but return an offset 2000 // suitable for fields that take instruction offsets. 2001 inline int LinkAndGetInstructionOffsetTo(Label* label); 2002 2003 static const int kStartOfLabelLinkChain = 0; 2004 2005 // Verify that a label's link chain is intact. 2006 void CheckLabelLinkChain(Label const * label); 2007 2008 void RecordLiteral(int64_t imm, unsigned size); 2009 2010 // Postpone the generation of the constant pool for the specified number of 2011 // instructions. 2012 void BlockConstPoolFor(int instructions); 2013 2014 // Set how far from current pc the next constant pool check will be. 2015 void SetNextConstPoolCheckIn(int instructions) { 2016 next_constant_pool_check_ = pc_offset() + instructions * kInstructionSize; 2017 } 2018 2019 // Emit the instruction at pc_. 2020 void Emit(Instr instruction) { 2021 STATIC_ASSERT(sizeof(*pc_) == 1); 2022 STATIC_ASSERT(sizeof(instruction) == kInstructionSize); 2023 DCHECK((pc_ + sizeof(instruction)) <= (buffer_ + buffer_size_)); 2024 2025 memcpy(pc_, &instruction, sizeof(instruction)); 2026 pc_ += sizeof(instruction); 2027 CheckBuffer(); 2028 } 2029 2030 // Emit data inline in the instruction stream. 2031 void EmitData(void const * data, unsigned size) { 2032 DCHECK(sizeof(*pc_) == 1); 2033 DCHECK((pc_ + size) <= (buffer_ + buffer_size_)); 2034 2035 // TODO(all): Somehow register we have some data here. Then we can 2036 // disassemble it correctly. 2037 memcpy(pc_, data, size); 2038 pc_ += size; 2039 CheckBuffer(); 2040 } 2041 2042 void GrowBuffer(); 2043 void CheckBufferSpace(); 2044 void CheckBuffer(); 2045 2046 // Pc offset of the next constant pool check. 2047 int next_constant_pool_check_; 2048 2049 // Constant pool generation 2050 // Pools are emitted in the instruction stream. They are emitted when: 2051 // * the distance to the first use is above a pre-defined distance or 2052 // * the numbers of entries in the pool is above a pre-defined size or 2053 // * code generation is finished 2054 // If a pool needs to be emitted before code generation is finished a branch 2055 // over the emitted pool will be inserted. 2056 2057 // Constants in the pool may be addresses of functions that gets relocated; 2058 // if so, a relocation info entry is associated to the constant pool entry. 2059 2060 // Repeated checking whether the constant pool should be emitted is rather 2061 // expensive. By default we only check again once a number of instructions 2062 // has been generated. That also means that the sizing of the buffers is not 2063 // an exact science, and that we rely on some slop to not overrun buffers. 2064 static const int kCheckConstPoolInterval = 128; 2065 2066 // Distance to first use after a which a pool will be emitted. Pool entries 2067 // are accessed with pc relative load therefore this cannot be more than 2068 // 1 * MB. Since constant pool emission checks are interval based this value 2069 // is an approximation. 2070 static const int kApproxMaxDistToConstPool = 64 * KB; 2071 2072 // Number of pool entries after which a pool will be emitted. Since constant 2073 // pool emission checks are interval based this value is an approximation. 2074 static const int kApproxMaxPoolEntryCount = 512; 2075 2076 // Emission of the constant pool may be blocked in some code sequences. 2077 int const_pool_blocked_nesting_; // Block emission if this is not zero. 2078 int no_const_pool_before_; // Block emission before this pc offset. 2079 2080 // Emission of the veneer pools may be blocked in some code sequences. 2081 int veneer_pool_blocked_nesting_; // Block emission if this is not zero. 2082 2083 // Relocation info generation 2084 // Each relocation is encoded as a variable size value 2085 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 2086 RelocInfoWriter reloc_info_writer; 2087 // Internal reference positions, required for (potential) patching in 2088 // GrowBuffer(); contains only those internal references whose labels 2089 // are already bound. 2090 std::deque<int> internal_reference_positions_; 2091 2092 // Relocation info records are also used during code generation as temporary 2093 // containers for constants and code target addresses until they are emitted 2094 // to the constant pool. These pending relocation info records are temporarily 2095 // stored in a separate buffer until a constant pool is emitted. 2096 // If every instruction in a long sequence is accessing the pool, we need one 2097 // pending relocation entry per instruction. 2098 2099 // The pending constant pool. 2100 ConstPool constpool_; 2101 2102 // Relocation for a type-recording IC has the AST id added to it. This 2103 // member variable is a way to pass the information from the call site to 2104 // the relocation info. 2105 TypeFeedbackId recorded_ast_id_; 2106 2107 inline TypeFeedbackId RecordedAstId(); 2108 inline void ClearRecordedAstId(); 2109 2110 protected: 2111 // Record the AST id of the CallIC being compiled, so that it can be placed 2112 // in the relocation information. 2113 void SetRecordedAstId(TypeFeedbackId ast_id) { 2114 DCHECK(recorded_ast_id_.IsNone()); 2115 recorded_ast_id_ = ast_id; 2116 } 2117 2118 // Code generation 2119 // The relocation writer's position is at least kGap bytes below the end of 2120 // the generated instructions. This is so that multi-instruction sequences do 2121 // not have to check for overflow. The same is true for writes of large 2122 // relocation info entries, and debug strings encoded in the instruction 2123 // stream. 2124 static const int kGap = 128; 2125 2126 public: 2127 class FarBranchInfo { 2128 public: 2129 FarBranchInfo(int offset, Label* label) 2130 : pc_offset_(offset), label_(label) {} 2131 // Offset of the branch in the code generation buffer. 2132 int pc_offset_; 2133 // The label branched to. 2134 Label* label_; 2135 }; 2136 2137 protected: 2138 // Information about unresolved (forward) branches. 2139 // The Assembler is only allowed to delete out-of-date information from here 2140 // after a label is bound. The MacroAssembler uses this information to 2141 // generate veneers. 2142 // 2143 // The second member gives information about the unresolved branch. The first 2144 // member of the pair is the maximum offset that the branch can reach in the 2145 // buffer. The map is sorted according to this reachable offset, allowing to 2146 // easily check when veneers need to be emitted. 2147 // Note that the maximum reachable offset (first member of the pairs) should 2148 // always be positive but has the same type as the return value for 2149 // pc_offset() for convenience. 2150 std::multimap<int, FarBranchInfo> unresolved_branches_; 2151 2152 // We generate a veneer for a branch if we reach within this distance of the 2153 // limit of the range. 2154 static const int kVeneerDistanceMargin = 1 * KB; 2155 // The factor of 2 is a finger in the air guess. With a default margin of 2156 // 1KB, that leaves us an addional 256 instructions to avoid generating a 2157 // protective branch. 2158 static const int kVeneerNoProtectionFactor = 2; 2159 static const int kVeneerDistanceCheckMargin = 2160 kVeneerNoProtectionFactor * kVeneerDistanceMargin; 2161 int unresolved_branches_first_limit() const { 2162 DCHECK(!unresolved_branches_.empty()); 2163 return unresolved_branches_.begin()->first; 2164 } 2165 // This is similar to next_constant_pool_check_ and helps reduce the overhead 2166 // of checking for veneer pools. 2167 // It is maintained to the closest unresolved branch limit minus the maximum 2168 // veneer margin (or kMaxInt if there are no unresolved branches). 2169 int next_veneer_pool_check_; 2170 2171 private: 2172 // If a veneer is emitted for a branch instruction, that instruction must be 2173 // removed from the associated label's link chain so that the assembler does 2174 // not later attempt (likely unsuccessfully) to patch it to branch directly to 2175 // the label. 2176 void DeleteUnresolvedBranchInfoForLabel(Label* label); 2177 // This function deletes the information related to the label by traversing 2178 // the label chain, and for each PC-relative instruction in the chain checking 2179 // if pending unresolved information exists. Its complexity is proportional to 2180 // the length of the label chain. 2181 void DeleteUnresolvedBranchInfoForLabelTraverse(Label* label); 2182 2183 private: 2184 AssemblerPositionsRecorder positions_recorder_; 2185 friend class AssemblerPositionsRecorder; 2186 friend class EnsureSpace; 2187 friend class ConstPool; 2188 }; 2189 2190 class PatchingAssembler : public Assembler { 2191 public: 2192 // Create an Assembler with a buffer starting at 'start'. 2193 // The buffer size is 2194 // size of instructions to patch + kGap 2195 // Where kGap is the distance from which the Assembler tries to grow the 2196 // buffer. 2197 // If more or fewer instructions than expected are generated or if some 2198 // relocation information takes space in the buffer, the PatchingAssembler 2199 // will crash trying to grow the buffer. 2200 PatchingAssembler(Isolate* isolate, Instruction* start, unsigned count) 2201 : Assembler(isolate, reinterpret_cast<byte*>(start), 2202 count * kInstructionSize + kGap) { 2203 StartBlockPools(); 2204 } 2205 2206 PatchingAssembler(Isolate* isolate, byte* start, unsigned count) 2207 : Assembler(isolate, start, count * kInstructionSize + kGap) { 2208 // Block constant pool emission. 2209 StartBlockPools(); 2210 } 2211 2212 ~PatchingAssembler() { 2213 // Const pool should still be blocked. 2214 DCHECK(is_const_pool_blocked()); 2215 EndBlockPools(); 2216 // Verify we have generated the number of instruction we expected. 2217 DCHECK((pc_offset() + kGap) == buffer_size_); 2218 // Verify no relocation information has been emitted. 2219 DCHECK(IsConstPoolEmpty()); 2220 // Flush the Instruction cache. 2221 size_t length = buffer_size_ - kGap; 2222 Assembler::FlushICache(isolate(), buffer_, length); 2223 } 2224 2225 // See definition of PatchAdrFar() for details. 2226 static const int kAdrFarPatchableNNops = 2; 2227 static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2; 2228 void PatchAdrFar(int64_t target_offset); 2229 }; 2230 2231 2232 class EnsureSpace BASE_EMBEDDED { 2233 public: 2234 explicit EnsureSpace(Assembler* assembler) { 2235 assembler->CheckBufferSpace(); 2236 } 2237 }; 2238 2239 } // namespace internal 2240 } // namespace v8 2241 2242 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ 2243