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 static const bool kSimdMaskRegisters = false; 202 203 struct FPRegister : public CPURegister { 204 enum Code { 205 #define REGISTER_CODE(R) kCode_##R, 206 DOUBLE_REGISTERS(REGISTER_CODE) 207 #undef REGISTER_CODE 208 kAfterLast, 209 kCode_no_reg = -1 210 }; 211 CreateFPRegister212 static FPRegister Create(int code, int size) { 213 return FPRegister( 214 CPURegister::Create(code, size, CPURegister::kFPRegister)); 215 } 216 FPRegisterFPRegister217 FPRegister() { 218 reg_code = 0; 219 reg_size = 0; 220 reg_type = CPURegister::kNoRegister; 221 } 222 FPRegisterFPRegister223 explicit FPRegister(const CPURegister& r) { 224 reg_code = r.reg_code; 225 reg_size = r.reg_size; 226 reg_type = r.reg_type; 227 DCHECK(IsValidOrNone()); 228 } 229 FPRegisterFPRegister230 FPRegister(const FPRegister& r) { // NOLINT(runtime/explicit) 231 reg_code = r.reg_code; 232 reg_size = r.reg_size; 233 reg_type = r.reg_type; 234 DCHECK(IsValidOrNone()); 235 } 236 IsValidFPRegister237 bool IsValid() const { 238 DCHECK(IsFPRegister() || IsNone()); 239 return IsValidFPRegister(); 240 } 241 242 static FPRegister SRegFromCode(unsigned code); 243 static FPRegister DRegFromCode(unsigned code); 244 245 // Start of V8 compatibility section --------------------- 246 static const int kMaxNumRegisters = kNumberOfFPRegisters; 247 STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast); 248 249 // Crankshaft can use all the FP registers except: 250 // - d15 which is used to keep the 0 double value 251 // - d30 which is used in crankshaft as a double scratch register 252 // - d31 which is used in the MacroAssembler as a double scratch register from_codeFPRegister253 static FPRegister from_code(int code) { 254 // Always return a D register. 255 return FPRegister::Create(code, kDRegSizeInBits); 256 } 257 // End of V8 compatibility section ----------------------- 258 }; 259 260 261 STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); 262 STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); 263 264 265 #if defined(ARM64_DEFINE_REG_STATICS) 266 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 267 const CPURegister init_##register_class##_##name = {code, size, type}; \ 268 const register_class& name = *reinterpret_cast<const register_class*>( \ 269 &init_##register_class##_##name) 270 #define ALIAS_REGISTER(register_class, alias, name) \ 271 const register_class& alias = *reinterpret_cast<const register_class*>( \ 272 &init_##register_class##_##name) 273 #else 274 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ 275 extern const register_class& name 276 #define ALIAS_REGISTER(register_class, alias, name) \ 277 extern const register_class& alias 278 #endif // defined(ARM64_DEFINE_REG_STATICS) 279 280 // No*Reg is used to indicate an unused argument, or an error case. Note that 281 // these all compare equal (using the Is() method). The Register and FPRegister 282 // variants are provided for convenience. 283 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister); 284 INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister); 285 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister); 286 287 // v8 compatibility. 288 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); 289 290 #define DEFINE_REGISTERS(N) \ 291 INITIALIZE_REGISTER(Register, w##N, N, \ 292 kWRegSizeInBits, CPURegister::kRegister); \ 293 INITIALIZE_REGISTER(Register, x##N, N, \ 294 kXRegSizeInBits, CPURegister::kRegister); 295 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) 296 #undef DEFINE_REGISTERS 297 298 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits, 299 CPURegister::kRegister); 300 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits, 301 CPURegister::kRegister); 302 303 #define DEFINE_FPREGISTERS(N) \ 304 INITIALIZE_REGISTER(FPRegister, s##N, N, \ 305 kSRegSizeInBits, CPURegister::kFPRegister); \ 306 INITIALIZE_REGISTER(FPRegister, d##N, N, \ 307 kDRegSizeInBits, CPURegister::kFPRegister); 308 GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS) 309 #undef DEFINE_FPREGISTERS 310 311 #undef INITIALIZE_REGISTER 312 313 // Registers aliases. 314 ALIAS_REGISTER(Register, ip0, x16); 315 ALIAS_REGISTER(Register, ip1, x17); 316 ALIAS_REGISTER(Register, wip0, w16); 317 ALIAS_REGISTER(Register, wip1, w17); 318 // Root register. 319 ALIAS_REGISTER(Register, root, x26); 320 ALIAS_REGISTER(Register, rr, x26); 321 // Context pointer register. 322 ALIAS_REGISTER(Register, cp, x27); 323 // We use a register as a JS stack pointer to overcome the restriction on the 324 // architectural SP alignment. 325 // We chose x28 because it is contiguous with the other specific purpose 326 // registers. 327 STATIC_ASSERT(kJSSPCode == 28); 328 ALIAS_REGISTER(Register, jssp, x28); 329 ALIAS_REGISTER(Register, wjssp, w28); 330 ALIAS_REGISTER(Register, fp, x29); 331 ALIAS_REGISTER(Register, lr, x30); 332 ALIAS_REGISTER(Register, xzr, x31); 333 ALIAS_REGISTER(Register, wzr, w31); 334 335 // Keeps the 0 double value. 336 ALIAS_REGISTER(FPRegister, fp_zero, d15); 337 // Crankshaft double scratch register. 338 ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29); 339 // MacroAssembler double scratch registers. 340 ALIAS_REGISTER(FPRegister, fp_scratch, d30); 341 ALIAS_REGISTER(FPRegister, fp_scratch1, d30); 342 ALIAS_REGISTER(FPRegister, fp_scratch2, d31); 343 344 #undef ALIAS_REGISTER 345 346 347 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, 348 Register reg2 = NoReg, 349 Register reg3 = NoReg, 350 Register reg4 = NoReg); 351 352 353 // AreAliased returns true if any of the named registers overlap. Arguments set 354 // to NoReg are ignored. The system stack pointer may be specified. 355 bool AreAliased(const CPURegister& reg1, 356 const CPURegister& reg2, 357 const CPURegister& reg3 = NoReg, 358 const CPURegister& reg4 = NoReg, 359 const CPURegister& reg5 = NoReg, 360 const CPURegister& reg6 = NoReg, 361 const CPURegister& reg7 = NoReg, 362 const CPURegister& reg8 = NoReg); 363 364 // AreSameSizeAndType returns true if all of the specified registers have the 365 // same size, and are of the same type. The system stack pointer may be 366 // specified. Arguments set to NoReg are ignored, as are any subsequent 367 // arguments. At least one argument (reg1) must be valid (not NoCPUReg). 368 bool AreSameSizeAndType(const CPURegister& reg1, 369 const CPURegister& reg2, 370 const CPURegister& reg3 = NoCPUReg, 371 const CPURegister& reg4 = NoCPUReg, 372 const CPURegister& reg5 = NoCPUReg, 373 const CPURegister& reg6 = NoCPUReg, 374 const CPURegister& reg7 = NoCPUReg, 375 const CPURegister& reg8 = NoCPUReg); 376 377 typedef FPRegister FloatRegister; 378 typedef FPRegister DoubleRegister; 379 380 // TODO(arm64) Define SIMD registers. 381 typedef FPRegister Simd128Register; 382 383 // ----------------------------------------------------------------------------- 384 // Lists of registers. 385 class CPURegList { 386 public: 387 explicit CPURegList(CPURegister reg1, 388 CPURegister reg2 = NoCPUReg, 389 CPURegister reg3 = NoCPUReg, 390 CPURegister reg4 = NoCPUReg) 391 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()), 392 size_(reg1.SizeInBits()), type_(reg1.type()) { 393 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4)); 394 DCHECK(IsValid()); 395 } 396 CPURegList(CPURegister::RegisterType type,int size,RegList list)397 CPURegList(CPURegister::RegisterType type, int size, RegList list) 398 : list_(list), size_(size), type_(type) { 399 DCHECK(IsValid()); 400 } 401 CPURegList(CPURegister::RegisterType type,int size,int first_reg,int last_reg)402 CPURegList(CPURegister::RegisterType type, int size, int first_reg, 403 int last_reg) 404 : size_(size), type_(type) { 405 DCHECK(((type == CPURegister::kRegister) && 406 (last_reg < kNumberOfRegisters)) || 407 ((type == CPURegister::kFPRegister) && 408 (last_reg < kNumberOfFPRegisters))); 409 DCHECK(last_reg >= first_reg); 410 list_ = (1UL << (last_reg + 1)) - 1; 411 list_ &= ~((1UL << first_reg) - 1); 412 DCHECK(IsValid()); 413 } 414 type()415 CPURegister::RegisterType type() const { 416 DCHECK(IsValid()); 417 return type_; 418 } 419 list()420 RegList list() const { 421 DCHECK(IsValid()); 422 return list_; 423 } 424 set_list(RegList new_list)425 inline void set_list(RegList new_list) { 426 DCHECK(IsValid()); 427 list_ = new_list; 428 } 429 430 // Combine another CPURegList into this one. Registers that already exist in 431 // this list are left unchanged. The type and size of the registers in the 432 // 'other' list must match those in this list. 433 void Combine(const CPURegList& other); 434 435 // Remove every register in the other CPURegList from this one. Registers that 436 // do not exist in this list are ignored. The type of the registers in the 437 // 'other' list must match those in this list. 438 void Remove(const CPURegList& other); 439 440 // Variants of Combine and Remove which take CPURegisters. 441 void Combine(const CPURegister& other); 442 void Remove(const CPURegister& other1, 443 const CPURegister& other2 = NoCPUReg, 444 const CPURegister& other3 = NoCPUReg, 445 const CPURegister& other4 = NoCPUReg); 446 447 // Variants of Combine and Remove which take a single register by its code; 448 // the type and size of the register is inferred from this list. 449 void Combine(int code); 450 void Remove(int code); 451 452 // Remove all callee-saved registers from the list. This can be useful when 453 // preparing registers for an AAPCS64 function call, for example. 454 void RemoveCalleeSaved(); 455 456 CPURegister PopLowestIndex(); 457 CPURegister PopHighestIndex(); 458 459 // AAPCS64 callee-saved registers. 460 static CPURegList GetCalleeSaved(int size = kXRegSizeInBits); 461 static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits); 462 463 // AAPCS64 caller-saved registers. Note that this includes lr. 464 static CPURegList GetCallerSaved(int size = kXRegSizeInBits); 465 static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits); 466 467 // Registers saved as safepoints. 468 static CPURegList GetSafepointSavedRegisters(); 469 IsEmpty()470 bool IsEmpty() const { 471 DCHECK(IsValid()); 472 return list_ == 0; 473 } 474 475 bool IncludesAliasOf(const CPURegister& other1, 476 const CPURegister& other2 = NoCPUReg, 477 const CPURegister& other3 = NoCPUReg, 478 const CPURegister& other4 = NoCPUReg) const { 479 DCHECK(IsValid()); 480 RegList list = 0; 481 if (!other1.IsNone() && (other1.type() == type_)) list |= other1.Bit(); 482 if (!other2.IsNone() && (other2.type() == type_)) list |= other2.Bit(); 483 if (!other3.IsNone() && (other3.type() == type_)) list |= other3.Bit(); 484 if (!other4.IsNone() && (other4.type() == type_)) list |= other4.Bit(); 485 return (list_ & list) != 0; 486 } 487 Count()488 int Count() const { 489 DCHECK(IsValid()); 490 return CountSetBits(list_, kRegListSizeInBits); 491 } 492 RegisterSizeInBits()493 int RegisterSizeInBits() const { 494 DCHECK(IsValid()); 495 return size_; 496 } 497 RegisterSizeInBytes()498 int RegisterSizeInBytes() const { 499 int size_in_bits = RegisterSizeInBits(); 500 DCHECK((size_in_bits % kBitsPerByte) == 0); 501 return size_in_bits / kBitsPerByte; 502 } 503 TotalSizeInBytes()504 int TotalSizeInBytes() const { 505 DCHECK(IsValid()); 506 return RegisterSizeInBytes() * Count(); 507 } 508 509 private: 510 RegList list_; 511 int size_; 512 CPURegister::RegisterType type_; 513 IsValid()514 bool IsValid() const { 515 const RegList kValidRegisters = 0x8000000ffffffff; 516 const RegList kValidFPRegisters = 0x0000000ffffffff; 517 switch (type_) { 518 case CPURegister::kRegister: 519 return (list_ & kValidRegisters) == list_; 520 case CPURegister::kFPRegister: 521 return (list_ & kValidFPRegisters) == list_; 522 case CPURegister::kNoRegister: 523 return list_ == 0; 524 default: 525 UNREACHABLE(); 526 return false; 527 } 528 } 529 }; 530 531 532 // AAPCS64 callee-saved registers. 533 #define kCalleeSaved CPURegList::GetCalleeSaved() 534 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() 535 536 537 // AAPCS64 caller-saved registers. Note that this includes lr. 538 #define kCallerSaved CPURegList::GetCallerSaved() 539 #define kCallerSavedFP CPURegList::GetCallerSavedFP() 540 541 // ----------------------------------------------------------------------------- 542 // Immediates. 543 class Immediate { 544 public: 545 template<typename T> 546 inline explicit Immediate(Handle<T> handle); 547 548 // This is allowed to be an implicit constructor because Immediate is 549 // a wrapper class that doesn't normally perform any type conversion. 550 template<typename T> 551 inline Immediate(T value); // NOLINT(runtime/explicit) 552 553 template<typename T> 554 inline Immediate(T value, RelocInfo::Mode rmode); 555 value()556 int64_t value() const { return value_; } rmode()557 RelocInfo::Mode rmode() const { return rmode_; } 558 559 private: 560 void InitializeHandle(Handle<Object> value); 561 562 int64_t value_; 563 RelocInfo::Mode rmode_; 564 }; 565 566 567 // ----------------------------------------------------------------------------- 568 // Operands. 569 const int kSmiShift = kSmiTagSize + kSmiShiftSize; 570 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; 571 572 // Represents an operand in a machine instruction. 573 class Operand { 574 // TODO(all): If necessary, study more in details which methods 575 // TODO(all): should be inlined or not. 576 public: 577 // rm, {<shift> {#<shift_amount>}} 578 // where <shift> is one of {LSL, LSR, ASR, ROR}. 579 // <shift_amount> is uint6_t. 580 // This is allowed to be an implicit constructor because Operand is 581 // a wrapper class that doesn't normally perform any type conversion. 582 inline Operand(Register reg, 583 Shift shift = LSL, 584 unsigned shift_amount = 0); // NOLINT(runtime/explicit) 585 586 // rm, <extend> {#<shift_amount>} 587 // where <extend> is one of {UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX}. 588 // <shift_amount> is uint2_t. 589 inline Operand(Register reg, 590 Extend extend, 591 unsigned shift_amount = 0); 592 593 template<typename T> 594 inline explicit Operand(Handle<T> handle); 595 596 // Implicit constructor for all int types, ExternalReference, and Smi. 597 template<typename T> 598 inline Operand(T t); // NOLINT(runtime/explicit) 599 600 // Implicit constructor for int types. 601 template<typename T> 602 inline Operand(T t, RelocInfo::Mode rmode); 603 604 inline bool IsImmediate() const; 605 inline bool IsShiftedRegister() const; 606 inline bool IsExtendedRegister() const; 607 inline bool IsZero() const; 608 609 // This returns an LSL shift (<= 4) operand as an equivalent extend operand, 610 // which helps in the encoding of instructions that use the stack pointer. 611 inline Operand ToExtendedRegister() const; 612 613 inline Immediate immediate() const; 614 inline int64_t ImmediateValue() const; 615 inline Register reg() const; 616 inline Shift shift() const; 617 inline Extend extend() const; 618 inline unsigned shift_amount() const; 619 620 // Relocation information. 621 bool NeedsRelocation(const Assembler* assembler) const; 622 623 // Helpers 624 inline static Operand UntagSmi(Register smi); 625 inline static Operand UntagSmiAndScale(Register smi, int scale); 626 627 private: 628 Immediate immediate_; 629 Register reg_; 630 Shift shift_; 631 Extend extend_; 632 unsigned shift_amount_; 633 }; 634 635 636 // MemOperand represents a memory operand in a load or store instruction. 637 class MemOperand { 638 public: 639 inline MemOperand(); 640 inline explicit MemOperand(Register base, 641 int64_t offset = 0, 642 AddrMode addrmode = Offset); 643 inline explicit MemOperand(Register base, 644 Register regoffset, 645 Shift shift = LSL, 646 unsigned shift_amount = 0); 647 inline explicit MemOperand(Register base, 648 Register regoffset, 649 Extend extend, 650 unsigned shift_amount = 0); 651 inline explicit MemOperand(Register base, 652 const Operand& offset, 653 AddrMode addrmode = Offset); 654 base()655 const Register& base() const { return base_; } regoffset()656 const Register& regoffset() const { return regoffset_; } offset()657 int64_t offset() const { return offset_; } addrmode()658 AddrMode addrmode() const { return addrmode_; } shift()659 Shift shift() const { return shift_; } extend()660 Extend extend() const { return extend_; } shift_amount()661 unsigned shift_amount() const { return shift_amount_; } 662 inline bool IsImmediateOffset() const; 663 inline bool IsRegisterOffset() const; 664 inline bool IsPreIndex() const; 665 inline bool IsPostIndex() const; 666 667 // For offset modes, return the offset as an Operand. This helper cannot 668 // handle indexed modes. 669 inline Operand OffsetAsOperand() const; 670 671 enum PairResult { 672 kNotPair, // Can't use a pair instruction. 673 kPairAB, // Can use a pair instruction (operandA has lower address). 674 kPairBA // Can use a pair instruction (operandB has lower address). 675 }; 676 // Check if two MemOperand are consistent for stp/ldp use. 677 static PairResult AreConsistentForPair(const MemOperand& operandA, 678 const MemOperand& operandB, 679 int access_size_log2 = kXRegSizeLog2); 680 681 private: 682 Register base_; 683 Register regoffset_; 684 int64_t offset_; 685 AddrMode addrmode_; 686 Shift shift_; 687 Extend extend_; 688 unsigned shift_amount_; 689 }; 690 691 692 class ConstPool { 693 public: ConstPool(Assembler * assm)694 explicit ConstPool(Assembler* assm) 695 : assm_(assm), 696 first_use_(-1), 697 shared_entries_count(0) {} 698 void RecordEntry(intptr_t data, RelocInfo::Mode mode); EntryCount()699 int EntryCount() const { 700 return shared_entries_count + static_cast<int>(unique_entries_.size()); 701 } IsEmpty()702 bool IsEmpty() const { 703 return shared_entries_.empty() && unique_entries_.empty(); 704 } 705 // Distance in bytes between the current pc and the first instruction 706 // using the pool. If there are no pending entries return kMaxInt. 707 int DistanceToFirstUse(); 708 // Offset after which instructions using the pool will be out of range. 709 int MaxPcOffset(); 710 // Maximum size the constant pool can be with current entries. It always 711 // includes alignment padding and branch over. 712 int WorstCaseSize(); 713 // Size in bytes of the literal pool *if* it is emitted at the current 714 // pc. The size will include the branch over the pool if it was requested. 715 int SizeIfEmittedAtCurrentPc(bool require_jump); 716 // Emit the literal pool at the current pc with a branch over the pool if 717 // requested. 718 void Emit(bool require_jump); 719 // Discard any pending pool entries. 720 void Clear(); 721 722 private: 723 bool CanBeShared(RelocInfo::Mode mode); 724 void EmitMarker(); 725 void EmitGuard(); 726 void EmitEntries(); 727 728 Assembler* assm_; 729 // Keep track of the first instruction requiring a constant pool entry 730 // since the previous constant pool was emitted. 731 int first_use_; 732 // values, pc offset(s) of entries which can be shared. 733 std::multimap<uint64_t, int> shared_entries_; 734 // Number of distinct literal in shared entries. 735 int shared_entries_count; 736 // values, pc offset of entries which cannot be shared. 737 std::vector<std::pair<uint64_t, int> > unique_entries_; 738 }; 739 740 741 // ----------------------------------------------------------------------------- 742 // Assembler. 743 744 class Assembler : public AssemblerBase { 745 public: 746 // Create an assembler. Instructions and relocation information are emitted 747 // into a buffer, with the instructions starting from the beginning and the 748 // relocation information starting from the end of the buffer. See CodeDesc 749 // for a detailed comment on the layout (globals.h). 750 // 751 // If the provided buffer is NULL, the assembler allocates and grows its own 752 // buffer, and buffer_size determines the initial buffer size. The buffer is 753 // owned by the assembler and deallocated upon destruction of the assembler. 754 // 755 // If the provided buffer is not NULL, the assembler uses the provided buffer 756 // for code generation and assumes its size to be buffer_size. If the buffer 757 // is too small, a fatal error occurs. No deallocation of the buffer is done 758 // upon destruction of the assembler. 759 Assembler(Isolate* arg_isolate, void* buffer, int buffer_size); 760 761 virtual ~Assembler(); 762 AbortedCodeGeneration()763 virtual void AbortedCodeGeneration() { 764 constpool_.Clear(); 765 } 766 767 // System functions --------------------------------------------------------- 768 // Start generating code from the beginning of the buffer, discarding any code 769 // and data that has already been emitted into the buffer. 770 // 771 // In order to avoid any accidental transfer of state, Reset DCHECKs that the 772 // constant pool is not blocked. 773 void Reset(); 774 775 // GetCode emits any pending (non-emitted) code and fills the descriptor 776 // desc. GetCode() is idempotent; it returns the same result if no other 777 // Assembler functions are invoked in between GetCode() calls. 778 // 779 // The descriptor (desc) can be NULL. In that case, the code is finalized as 780 // usual, but the descriptor is not populated. 781 void GetCode(CodeDesc* desc); 782 783 // Insert the smallest number of nop instructions 784 // possible to align the pc offset to a multiple 785 // of m. m must be a power of 2 (>= 4). 786 void Align(int m); 787 // Insert the smallest number of zero bytes possible to align the pc offset 788 // to a mulitple of m. m must be a power of 2 (>= 2). 789 void DataAlign(int m); 790 791 inline void Unreachable(); 792 793 // Label -------------------------------------------------------------------- 794 // Bind a label to the current pc. Note that labels can only be bound once, 795 // and if labels are linked to other instructions, they _must_ be bound 796 // before they go out of scope. 797 void bind(Label* label); 798 799 800 // RelocInfo and pools ------------------------------------------------------ 801 802 // Record relocation information for current pc_. 803 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 804 805 // Return the address in the constant pool of the code target address used by 806 // the branch/call instruction at pc. 807 inline static Address target_pointer_address_at(Address pc); 808 809 // Read/Modify the code target address in the branch/call instruction at pc. 810 inline static Address target_address_at(Address pc, Address constant_pool); 811 inline static void set_target_address_at( 812 Isolate* isolate, Address pc, Address constant_pool, Address target, 813 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 814 static inline Address target_address_at(Address pc, Code* code); 815 static inline void set_target_address_at( 816 Isolate* isolate, Address pc, Code* code, Address target, 817 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 818 819 // Return the code target address at a call site from the return address of 820 // that call in the instruction stream. 821 inline static Address target_address_from_return_address(Address pc); 822 823 // Given the address of the beginning of a call, return the address in the 824 // instruction stream that call will return from. 825 inline static Address return_address_from_call_start(Address pc); 826 827 // This sets the branch destination (which is in the constant pool on ARM). 828 // This is for calls and branches within generated code. 829 inline static void deserialization_set_special_target_at( 830 Isolate* isolate, Address constant_pool_entry, Code* code, 831 Address target); 832 833 // This sets the internal reference at the pc. 834 inline static void deserialization_set_target_internal_reference_at( 835 Isolate* isolate, Address pc, Address target, 836 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 837 838 // All addresses in the constant pool are the same size as pointers. 839 static const int kSpecialTargetSize = kPointerSize; 840 841 // The sizes of the call sequences emitted by MacroAssembler::Call. 842 // Wherever possible, use MacroAssembler::CallSize instead of these constants, 843 // as it will choose the correct value for a given relocation mode. 844 // 845 // Without relocation: 846 // movz temp, #(target & 0x000000000000ffff) 847 // movk temp, #(target & 0x00000000ffff0000) 848 // movk temp, #(target & 0x0000ffff00000000) 849 // blr temp 850 // 851 // With relocation: 852 // ldr temp, =target 853 // blr temp 854 static const int kCallSizeWithoutRelocation = 4 * kInstructionSize; 855 static const int kCallSizeWithRelocation = 2 * kInstructionSize; 856 857 // Size of the generated code in bytes SizeOfGeneratedCode()858 uint64_t SizeOfGeneratedCode() const { 859 DCHECK((pc_ >= buffer_) && (pc_ < (buffer_ + buffer_size_))); 860 return pc_ - buffer_; 861 } 862 863 // Return the code size generated from label to the current position. SizeOfCodeGeneratedSince(const Label * label)864 uint64_t SizeOfCodeGeneratedSince(const Label* label) { 865 DCHECK(label->is_bound()); 866 DCHECK(pc_offset() >= label->pos()); 867 DCHECK(pc_offset() < buffer_size_); 868 return pc_offset() - label->pos(); 869 } 870 871 // Check the size of the code generated since the given label. This function 872 // is used primarily to work around comparisons between signed and unsigned 873 // quantities, since V8 uses both. 874 // TODO(jbramley): Work out what sign to use for these things and if possible, 875 // change things to be consistent. AssertSizeOfCodeGeneratedSince(const Label * label,ptrdiff_t size)876 void AssertSizeOfCodeGeneratedSince(const Label* label, ptrdiff_t size) { 877 DCHECK(size >= 0); 878 DCHECK(static_cast<uint64_t>(size) == SizeOfCodeGeneratedSince(label)); 879 } 880 881 // Return the number of instructions generated from label to the 882 // current position. InstructionsGeneratedSince(const Label * label)883 uint64_t InstructionsGeneratedSince(const Label* label) { 884 return SizeOfCodeGeneratedSince(label) / kInstructionSize; 885 } 886 887 static const int kPatchDebugBreakSlotAddressOffset = 0; 888 889 // Number of instructions necessary to be able to later patch it to a call. 890 static const int kDebugBreakSlotInstructions = 5; 891 static const int kDebugBreakSlotLength = 892 kDebugBreakSlotInstructions * kInstructionSize; 893 894 // Prevent contant pool emission until EndBlockConstPool is called. 895 // Call to this function can be nested but must be followed by an equal 896 // number of call to EndBlockConstpool. 897 void StartBlockConstPool(); 898 899 // Resume constant pool emission. Need to be called as many time as 900 // StartBlockConstPool to have an effect. 901 void EndBlockConstPool(); 902 903 bool is_const_pool_blocked() const; 904 static bool IsConstantPoolAt(Instruction* instr); 905 static int ConstantPoolSizeAt(Instruction* instr); 906 // See Assembler::CheckConstPool for more info. 907 void EmitPoolGuard(); 908 909 // Prevent veneer pool emission until EndBlockVeneerPool is called. 910 // Call to this function can be nested but must be followed by an equal 911 // number of call to EndBlockConstpool. 912 void StartBlockVeneerPool(); 913 914 // Resume constant pool emission. Need to be called as many time as 915 // StartBlockVeneerPool to have an effect. 916 void EndBlockVeneerPool(); 917 is_veneer_pool_blocked()918 bool is_veneer_pool_blocked() const { 919 return veneer_pool_blocked_nesting_ > 0; 920 } 921 922 // Block/resume emission of constant pools and veneer pools. StartBlockPools()923 void StartBlockPools() { 924 StartBlockConstPool(); 925 StartBlockVeneerPool(); 926 } EndBlockPools()927 void EndBlockPools() { 928 EndBlockConstPool(); 929 EndBlockVeneerPool(); 930 } 931 932 // Debugging ---------------------------------------------------------------- 933 void RecordComment(const char* msg); 934 935 // Record a deoptimization reason that can be used by a log or cpu profiler. 936 // Use --trace-deopt to enable. 937 void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position, 938 int id); 939 940 int buffer_space() const; 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. bfi(const Register & rd,const Register & rn,int lsb,int width)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. bfxil(const Register & rd,const Register & rn,int lsb,int width)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. asr(const Register & rd,const Register & rn,int shift)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. sbfiz(const Register & rd,const Register & rn,int lsb,int width)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. sbfx(const Register & rd,const Register & rn,int lsb,int width)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. sxtb(const Register & rd,const Register & rn)1174 void sxtb(const Register& rd, const Register& rn) { 1175 sbfm(rd, rn, 0, 7); 1176 } 1177 1178 // Signed extend halfword. sxth(const Register & rd,const Register & rn)1179 void sxth(const Register& rd, const Register& rn) { 1180 sbfm(rd, rn, 0, 15); 1181 } 1182 1183 // Signed extend word. sxtw(const Register & rd,const Register & rn)1184 void sxtw(const Register& rd, const Register& rn) { 1185 sbfm(rd, rn, 0, 31); 1186 } 1187 1188 // Ubfm aliases. 1189 // Logical shift left. lsl(const Register & rd,const Register & rn,int shift)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. lsr(const Register & rd,const Register & rn,int shift)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. ubfiz(const Register & rd,const Register & rn,int lsb,int width)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. ubfx(const Register & rd,const Register & rn,int lsb,int width)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. uxtb(const Register & rd,const Register & rn)1217 void uxtb(const Register& rd, const Register& rn) { 1218 ubfm(rd, rn, 0, 7); 1219 } 1220 1221 // Unsigned extend halfword. uxth(const Register & rd,const Register & rn)1222 void uxth(const Register& rd, const Register& rn) { 1223 ubfm(rd, rn, 0, 15); 1224 } 1225 1226 // Unsigned extend word. uxtw(const Register & rd,const Register & rn)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. ror(const Register & rd,const Register & rs,unsigned shift)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. nop()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 nop(NopMarkerTypes n)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. dci(Instr raw_inst)1656 void dci(Instr raw_inst) { Emit(raw_inst); } 1657 1658 // Emit 8 bits of data in the instruction stream. dc8(uint8_t data)1659 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); } 1660 1661 // Emit 32 bits of data in the instruction stream. dc32(uint32_t data)1662 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); } 1663 1664 // Emit 64 bits of data in the instruction stream. dc64(uint64_t data)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. dd(uint32_t data)1681 void dd(uint32_t data) { dc32(data); } db(uint8_t data)1682 void db(uint8_t data) { dc8(data); } dq(uint64_t data)1683 void dq(uint64_t data) { dc64(data); } dp(uintptr_t data)1684 void dp(uintptr_t data) { dc64(data); } 1685 1686 // Code generation helpers -------------------------------------------------- 1687 IsConstPoolEmpty()1688 bool IsConstPoolEmpty() const { return constpool_.IsEmpty(); } 1689 pc()1690 Instruction* pc() const { return Instruction::Cast(pc_); } 1691 InstructionAt(ptrdiff_t offset)1692 Instruction* InstructionAt(ptrdiff_t offset) const { 1693 return reinterpret_cast<Instruction*>(buffer_ + offset); 1694 } 1695 InstructionOffset(Instruction * instr)1696 ptrdiff_t InstructionOffset(Instruction* instr) const { 1697 return reinterpret_cast<byte*>(instr) - buffer_; 1698 } 1699 1700 // Register encoding. Rd(CPURegister rd)1701 static Instr Rd(CPURegister rd) { 1702 DCHECK(rd.code() != kSPRegInternalCode); 1703 return rd.code() << Rd_offset; 1704 } 1705 Rn(CPURegister rn)1706 static Instr Rn(CPURegister rn) { 1707 DCHECK(rn.code() != kSPRegInternalCode); 1708 return rn.code() << Rn_offset; 1709 } 1710 Rm(CPURegister rm)1711 static Instr Rm(CPURegister rm) { 1712 DCHECK(rm.code() != kSPRegInternalCode); 1713 return rm.code() << Rm_offset; 1714 } 1715 Ra(CPURegister ra)1716 static Instr Ra(CPURegister ra) { 1717 DCHECK(ra.code() != kSPRegInternalCode); 1718 return ra.code() << Ra_offset; 1719 } 1720 Rt(CPURegister rt)1721 static Instr Rt(CPURegister rt) { 1722 DCHECK(rt.code() != kSPRegInternalCode); 1723 return rt.code() << Rt_offset; 1724 } 1725 Rt2(CPURegister rt2)1726 static Instr Rt2(CPURegister rt2) { 1727 DCHECK(rt2.code() != kSPRegInternalCode); 1728 return rt2.code() << Rt2_offset; 1729 } 1730 Rs(CPURegister rs)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. RdSP(Register rd)1738 static Instr RdSP(Register rd) { 1739 DCHECK(!rd.IsZero()); 1740 return (rd.code() & kRegCodeMask) << Rd_offset; 1741 } 1742 RnSP(Register rn)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: BlockConstPoolScope(Assembler * assem)1816 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) { 1817 assem_->StartBlockConstPool(); 1818 } ~BlockConstPoolScope()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 PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)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); EmitVeneersGuard()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: BlockPoolsScope(Assembler * assem)1866 explicit BlockPoolsScope(Assembler* assem) : assem_(assem) { 1867 assem_->StartBlockPools(); 1868 } ~BlockPoolsScope()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. SetNextConstPoolCheckIn(int instructions)2015 void SetNextConstPoolCheckIn(int instructions) { 2016 next_constant_pool_check_ = pc_offset() + instructions * kInstructionSize; 2017 } 2018 2019 // Emit the instruction at pc_. Emit(Instr instruction)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. EmitData(void const * data,unsigned size)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. SetRecordedAstId(TypeFeedbackId ast_id)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: FarBranchInfo(int offset,Label * label)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; unresolved_branches_first_limit()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 friend class EnsureSpace; 2185 friend class ConstPool; 2186 }; 2187 2188 class PatchingAssembler : public Assembler { 2189 public: 2190 // Create an Assembler with a buffer starting at 'start'. 2191 // The buffer size is 2192 // size of instructions to patch + kGap 2193 // Where kGap is the distance from which the Assembler tries to grow the 2194 // buffer. 2195 // If more or fewer instructions than expected are generated or if some 2196 // relocation information takes space in the buffer, the PatchingAssembler 2197 // will crash trying to grow the buffer. PatchingAssembler(Isolate * isolate,Instruction * start,unsigned count)2198 PatchingAssembler(Isolate* isolate, Instruction* start, unsigned count) 2199 : Assembler(isolate, reinterpret_cast<byte*>(start), 2200 count * kInstructionSize + kGap) { 2201 StartBlockPools(); 2202 } 2203 PatchingAssembler(Isolate * isolate,byte * start,unsigned count)2204 PatchingAssembler(Isolate* isolate, byte* start, unsigned count) 2205 : Assembler(isolate, start, count * kInstructionSize + kGap) { 2206 // Block constant pool emission. 2207 StartBlockPools(); 2208 } 2209 ~PatchingAssembler()2210 ~PatchingAssembler() { 2211 // Const pool should still be blocked. 2212 DCHECK(is_const_pool_blocked()); 2213 EndBlockPools(); 2214 // Verify we have generated the number of instruction we expected. 2215 DCHECK((pc_offset() + kGap) == buffer_size_); 2216 // Verify no relocation information has been emitted. 2217 DCHECK(IsConstPoolEmpty()); 2218 // Flush the Instruction cache. 2219 size_t length = buffer_size_ - kGap; 2220 Assembler::FlushICache(isolate(), buffer_, length); 2221 } 2222 2223 // See definition of PatchAdrFar() for details. 2224 static const int kAdrFarPatchableNNops = 2; 2225 static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2; 2226 void PatchAdrFar(int64_t target_offset); 2227 }; 2228 2229 2230 class EnsureSpace BASE_EMBEDDED { 2231 public: EnsureSpace(Assembler * assembler)2232 explicit EnsureSpace(Assembler* assembler) { 2233 assembler->CheckBufferSpace(); 2234 } 2235 }; 2236 2237 } // namespace internal 2238 } // namespace v8 2239 2240 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ 2241