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