1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following 11 // disclaimer in the documentation and/or other materials provided 12 // with the distribution. 13 // * Neither the name of Google Inc. nor the names of its 14 // contributors may be used to endorse or promote products derived 15 // from this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "src/v8.h" 30 31 #if V8_TARGET_ARCH_ARM64 32 33 #define ARM64_DEFINE_REG_STATICS 34 35 #include "src/arm64/assembler-arm64-inl.h" 36 #include "src/base/bits.h" 37 #include "src/base/cpu.h" 38 39 namespace v8 { 40 namespace internal { 41 42 43 // ----------------------------------------------------------------------------- 44 // CpuFeatures implementation. 45 46 void CpuFeatures::ProbeImpl(bool cross_compile) { 47 if (cross_compile) { 48 // Always align csp in cross compiled code - this is safe and ensures that 49 // csp will always be aligned if it is enabled by probing at runtime. 50 if (FLAG_enable_always_align_csp) supported_ |= 1u << ALWAYS_ALIGN_CSP; 51 } else { 52 base::CPU cpu; 53 if (FLAG_enable_always_align_csp && 54 (cpu.implementer() == base::CPU::NVIDIA || FLAG_debug_code)) { 55 supported_ |= 1u << ALWAYS_ALIGN_CSP; 56 } 57 } 58 } 59 60 61 void CpuFeatures::PrintTarget() { } 62 void CpuFeatures::PrintFeatures() { } 63 64 65 // ----------------------------------------------------------------------------- 66 // CPURegList utilities. 67 68 CPURegister CPURegList::PopLowestIndex() { 69 DCHECK(IsValid()); 70 if (IsEmpty()) { 71 return NoCPUReg; 72 } 73 int index = CountTrailingZeros(list_, kRegListSizeInBits); 74 DCHECK((1 << index) & list_); 75 Remove(index); 76 return CPURegister::Create(index, size_, type_); 77 } 78 79 80 CPURegister CPURegList::PopHighestIndex() { 81 DCHECK(IsValid()); 82 if (IsEmpty()) { 83 return NoCPUReg; 84 } 85 int index = CountLeadingZeros(list_, kRegListSizeInBits); 86 index = kRegListSizeInBits - 1 - index; 87 DCHECK((1 << index) & list_); 88 Remove(index); 89 return CPURegister::Create(index, size_, type_); 90 } 91 92 93 void CPURegList::RemoveCalleeSaved() { 94 if (type() == CPURegister::kRegister) { 95 Remove(GetCalleeSaved(RegisterSizeInBits())); 96 } else if (type() == CPURegister::kFPRegister) { 97 Remove(GetCalleeSavedFP(RegisterSizeInBits())); 98 } else { 99 DCHECK(type() == CPURegister::kNoRegister); 100 DCHECK(IsEmpty()); 101 // The list must already be empty, so do nothing. 102 } 103 } 104 105 106 CPURegList CPURegList::GetCalleeSaved(unsigned size) { 107 return CPURegList(CPURegister::kRegister, size, 19, 29); 108 } 109 110 111 CPURegList CPURegList::GetCalleeSavedFP(unsigned size) { 112 return CPURegList(CPURegister::kFPRegister, size, 8, 15); 113 } 114 115 116 CPURegList CPURegList::GetCallerSaved(unsigned size) { 117 // Registers x0-x18 and lr (x30) are caller-saved. 118 CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18); 119 list.Combine(lr); 120 return list; 121 } 122 123 124 CPURegList CPURegList::GetCallerSavedFP(unsigned size) { 125 // Registers d0-d7 and d16-d31 are caller-saved. 126 CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7); 127 list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31)); 128 return list; 129 } 130 131 132 // This function defines the list of registers which are associated with a 133 // safepoint slot. Safepoint register slots are saved contiguously on the stack. 134 // MacroAssembler::SafepointRegisterStackIndex handles mapping from register 135 // code to index in the safepoint register slots. Any change here can affect 136 // this mapping. 137 CPURegList CPURegList::GetSafepointSavedRegisters() { 138 CPURegList list = CPURegList::GetCalleeSaved(); 139 list.Combine( 140 CPURegList(CPURegister::kRegister, kXRegSizeInBits, kJSCallerSaved)); 141 142 // Note that unfortunately we can't use symbolic names for registers and have 143 // to directly use register codes. This is because this function is used to 144 // initialize some static variables and we can't rely on register variables 145 // to be initialized due to static initialization order issues in C++. 146 147 // Drop ip0 and ip1 (i.e. x16 and x17), as they should not be expected to be 148 // preserved outside of the macro assembler. 149 list.Remove(16); 150 list.Remove(17); 151 152 // Add x18 to the safepoint list, as although it's not in kJSCallerSaved, it 153 // is a caller-saved register according to the procedure call standard. 154 list.Combine(18); 155 156 // Drop jssp as the stack pointer doesn't need to be included. 157 list.Remove(28); 158 159 // Add the link register (x30) to the safepoint list. 160 list.Combine(30); 161 162 return list; 163 } 164 165 166 // ----------------------------------------------------------------------------- 167 // Implementation of RelocInfo 168 169 const int RelocInfo::kApplyMask = 0; 170 171 172 bool RelocInfo::IsCodedSpecially() { 173 // The deserializer needs to know whether a pointer is specially coded. Being 174 // specially coded on ARM64 means that it is a movz/movk sequence. We don't 175 // generate those for relocatable pointers. 176 return false; 177 } 178 179 180 bool RelocInfo::IsInConstantPool() { 181 Instruction* instr = reinterpret_cast<Instruction*>(pc_); 182 return instr->IsLdrLiteralX(); 183 } 184 185 186 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 187 // Patch the code at the current address with the supplied instructions. 188 Instr* pc = reinterpret_cast<Instr*>(pc_); 189 Instr* instr = reinterpret_cast<Instr*>(instructions); 190 for (int i = 0; i < instruction_count; i++) { 191 *(pc + i) = *(instr + i); 192 } 193 194 // Indicate that code has changed. 195 CpuFeatures::FlushICache(pc_, instruction_count * kInstructionSize); 196 } 197 198 199 // Patch the code at the current PC with a call to the target address. 200 // Additional guard instructions can be added if required. 201 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { 202 UNIMPLEMENTED(); 203 } 204 205 206 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2, 207 Register reg3, Register reg4) { 208 CPURegList regs(reg1, reg2, reg3, reg4); 209 for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { 210 Register candidate = Register::FromAllocationIndex(i); 211 if (regs.IncludesAliasOf(candidate)) continue; 212 return candidate; 213 } 214 UNREACHABLE(); 215 return NoReg; 216 } 217 218 219 bool AreAliased(const CPURegister& reg1, const CPURegister& reg2, 220 const CPURegister& reg3, const CPURegister& reg4, 221 const CPURegister& reg5, const CPURegister& reg6, 222 const CPURegister& reg7, const CPURegister& reg8) { 223 int number_of_valid_regs = 0; 224 int number_of_valid_fpregs = 0; 225 226 RegList unique_regs = 0; 227 RegList unique_fpregs = 0; 228 229 const CPURegister regs[] = {reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8}; 230 231 for (unsigned i = 0; i < arraysize(regs); i++) { 232 if (regs[i].IsRegister()) { 233 number_of_valid_regs++; 234 unique_regs |= regs[i].Bit(); 235 } else if (regs[i].IsFPRegister()) { 236 number_of_valid_fpregs++; 237 unique_fpregs |= regs[i].Bit(); 238 } else { 239 DCHECK(!regs[i].IsValid()); 240 } 241 } 242 243 int number_of_unique_regs = 244 CountSetBits(unique_regs, sizeof(unique_regs) * kBitsPerByte); 245 int number_of_unique_fpregs = 246 CountSetBits(unique_fpregs, sizeof(unique_fpregs) * kBitsPerByte); 247 248 DCHECK(number_of_valid_regs >= number_of_unique_regs); 249 DCHECK(number_of_valid_fpregs >= number_of_unique_fpregs); 250 251 return (number_of_valid_regs != number_of_unique_regs) || 252 (number_of_valid_fpregs != number_of_unique_fpregs); 253 } 254 255 256 bool AreSameSizeAndType(const CPURegister& reg1, const CPURegister& reg2, 257 const CPURegister& reg3, const CPURegister& reg4, 258 const CPURegister& reg5, const CPURegister& reg6, 259 const CPURegister& reg7, const CPURegister& reg8) { 260 DCHECK(reg1.IsValid()); 261 bool match = true; 262 match &= !reg2.IsValid() || reg2.IsSameSizeAndType(reg1); 263 match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1); 264 match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1); 265 match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1); 266 match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1); 267 match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1); 268 match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1); 269 return match; 270 } 271 272 273 void Immediate::InitializeHandle(Handle<Object> handle) { 274 AllowDeferredHandleDereference using_raw_address; 275 276 // Verify all Objects referred by code are NOT in new space. 277 Object* obj = *handle; 278 if (obj->IsHeapObject()) { 279 DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); 280 value_ = reinterpret_cast<intptr_t>(handle.location()); 281 rmode_ = RelocInfo::EMBEDDED_OBJECT; 282 } else { 283 STATIC_ASSERT(sizeof(intptr_t) == sizeof(int64_t)); 284 value_ = reinterpret_cast<intptr_t>(obj); 285 rmode_ = RelocInfo::NONE64; 286 } 287 } 288 289 290 bool Operand::NeedsRelocation(const Assembler* assembler) const { 291 RelocInfo::Mode rmode = immediate_.rmode(); 292 293 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 294 return assembler->serializer_enabled(); 295 } 296 297 return !RelocInfo::IsNone(rmode); 298 } 299 300 301 // Constant Pool. 302 void ConstPool::RecordEntry(intptr_t data, 303 RelocInfo::Mode mode) { 304 DCHECK(mode != RelocInfo::COMMENT && 305 mode != RelocInfo::POSITION && 306 mode != RelocInfo::STATEMENT_POSITION && 307 mode != RelocInfo::CONST_POOL && 308 mode != RelocInfo::VENEER_POOL && 309 mode != RelocInfo::CODE_AGE_SEQUENCE); 310 311 uint64_t raw_data = static_cast<uint64_t>(data); 312 int offset = assm_->pc_offset(); 313 if (IsEmpty()) { 314 first_use_ = offset; 315 } 316 317 std::pair<uint64_t, int> entry = std::make_pair(raw_data, offset); 318 if (CanBeShared(mode)) { 319 shared_entries_.insert(entry); 320 if (shared_entries_.count(entry.first) == 1) { 321 shared_entries_count++; 322 } 323 } else { 324 unique_entries_.push_back(entry); 325 } 326 327 if (EntryCount() > Assembler::kApproxMaxPoolEntryCount) { 328 // Request constant pool emission after the next instruction. 329 assm_->SetNextConstPoolCheckIn(1); 330 } 331 } 332 333 334 int ConstPool::DistanceToFirstUse() { 335 DCHECK(first_use_ >= 0); 336 return assm_->pc_offset() - first_use_; 337 } 338 339 340 int ConstPool::MaxPcOffset() { 341 // There are no pending entries in the pool so we can never get out of 342 // range. 343 if (IsEmpty()) return kMaxInt; 344 345 // Entries are not necessarily emitted in the order they are added so in the 346 // worst case the first constant pool use will be accessing the last entry. 347 return first_use_ + kMaxLoadLiteralRange - WorstCaseSize(); 348 } 349 350 351 int ConstPool::WorstCaseSize() { 352 if (IsEmpty()) return 0; 353 354 // Max size prologue: 355 // b over 356 // ldr xzr, #pool_size 357 // blr xzr 358 // nop 359 // All entries are 64-bit for now. 360 return 4 * kInstructionSize + EntryCount() * kPointerSize; 361 } 362 363 364 int ConstPool::SizeIfEmittedAtCurrentPc(bool require_jump) { 365 if (IsEmpty()) return 0; 366 367 // Prologue is: 368 // b over ;; if require_jump 369 // ldr xzr, #pool_size 370 // blr xzr 371 // nop ;; if not 64-bit aligned 372 int prologue_size = require_jump ? kInstructionSize : 0; 373 prologue_size += 2 * kInstructionSize; 374 prologue_size += IsAligned(assm_->pc_offset() + prologue_size, 8) ? 375 0 : kInstructionSize; 376 377 // All entries are 64-bit for now. 378 return prologue_size + EntryCount() * kPointerSize; 379 } 380 381 382 void ConstPool::Emit(bool require_jump) { 383 DCHECK(!assm_->is_const_pool_blocked()); 384 // Prevent recursive pool emission and protect from veneer pools. 385 Assembler::BlockPoolsScope block_pools(assm_); 386 387 int size = SizeIfEmittedAtCurrentPc(require_jump); 388 Label size_check; 389 assm_->bind(&size_check); 390 391 assm_->RecordConstPool(size); 392 // Emit the constant pool. It is preceded by an optional branch if 393 // require_jump and a header which will: 394 // 1) Encode the size of the constant pool, for use by the disassembler. 395 // 2) Terminate the program, to try to prevent execution from accidentally 396 // flowing into the constant pool. 397 // 3) align the pool entries to 64-bit. 398 // The header is therefore made of up to three arm64 instructions: 399 // ldr xzr, #<size of the constant pool in 32-bit words> 400 // blr xzr 401 // nop 402 // 403 // If executed, the header will likely segfault and lr will point to the 404 // instruction following the offending blr. 405 // TODO(all): Make the alignment part less fragile. Currently code is 406 // allocated as a byte array so there are no guarantees the alignment will 407 // be preserved on compaction. Currently it works as allocation seems to be 408 // 64-bit aligned. 409 410 // Emit branch if required 411 Label after_pool; 412 if (require_jump) { 413 assm_->b(&after_pool); 414 } 415 416 // Emit the header. 417 assm_->RecordComment("[ Constant Pool"); 418 EmitMarker(); 419 EmitGuard(); 420 assm_->Align(8); 421 422 // Emit constant pool entries. 423 // TODO(all): currently each relocated constant is 64 bits, consider adding 424 // support for 32-bit entries. 425 EmitEntries(); 426 assm_->RecordComment("]"); 427 428 if (after_pool.is_linked()) { 429 assm_->bind(&after_pool); 430 } 431 432 DCHECK(assm_->SizeOfCodeGeneratedSince(&size_check) == 433 static_cast<unsigned>(size)); 434 } 435 436 437 void ConstPool::Clear() { 438 shared_entries_.clear(); 439 shared_entries_count = 0; 440 unique_entries_.clear(); 441 first_use_ = -1; 442 } 443 444 445 bool ConstPool::CanBeShared(RelocInfo::Mode mode) { 446 // Constant pool currently does not support 32-bit entries. 447 DCHECK(mode != RelocInfo::NONE32); 448 449 return RelocInfo::IsNone(mode) || 450 (!assm_->serializer_enabled() && (mode >= RelocInfo::CELL)); 451 } 452 453 454 void ConstPool::EmitMarker() { 455 // A constant pool size is expressed in number of 32-bits words. 456 // Currently all entries are 64-bit. 457 // + 1 is for the crash guard. 458 // + 0/1 for alignment. 459 int word_count = EntryCount() * 2 + 1 + 460 (IsAligned(assm_->pc_offset(), 8) ? 0 : 1); 461 assm_->Emit(LDR_x_lit | 462 Assembler::ImmLLiteral(word_count) | 463 Assembler::Rt(xzr)); 464 } 465 466 467 MemOperand::PairResult MemOperand::AreConsistentForPair( 468 const MemOperand& operandA, 469 const MemOperand& operandB, 470 int access_size_log2) { 471 DCHECK(access_size_log2 >= 0); 472 DCHECK(access_size_log2 <= 3); 473 // Step one: check that they share the same base, that the mode is Offset 474 // and that the offset is a multiple of access size. 475 if (!operandA.base().Is(operandB.base()) || 476 (operandA.addrmode() != Offset) || 477 (operandB.addrmode() != Offset) || 478 ((operandA.offset() & ((1 << access_size_log2) - 1)) != 0)) { 479 return kNotPair; 480 } 481 // Step two: check that the offsets are contiguous and that the range 482 // is OK for ldp/stp. 483 if ((operandB.offset() == operandA.offset() + (1 << access_size_log2)) && 484 is_int7(operandA.offset() >> access_size_log2)) { 485 return kPairAB; 486 } 487 if ((operandA.offset() == operandB.offset() + (1 << access_size_log2)) && 488 is_int7(operandB.offset() >> access_size_log2)) { 489 return kPairBA; 490 } 491 return kNotPair; 492 } 493 494 495 void ConstPool::EmitGuard() { 496 #ifdef DEBUG 497 Instruction* instr = reinterpret_cast<Instruction*>(assm_->pc()); 498 DCHECK(instr->preceding()->IsLdrLiteralX() && 499 instr->preceding()->Rt() == xzr.code()); 500 #endif 501 assm_->EmitPoolGuard(); 502 } 503 504 505 void ConstPool::EmitEntries() { 506 DCHECK(IsAligned(assm_->pc_offset(), 8)); 507 508 typedef std::multimap<uint64_t, int>::const_iterator SharedEntriesIterator; 509 SharedEntriesIterator value_it; 510 // Iterate through the keys (constant pool values). 511 for (value_it = shared_entries_.begin(); 512 value_it != shared_entries_.end(); 513 value_it = shared_entries_.upper_bound(value_it->first)) { 514 std::pair<SharedEntriesIterator, SharedEntriesIterator> range; 515 uint64_t data = value_it->first; 516 range = shared_entries_.equal_range(data); 517 SharedEntriesIterator offset_it; 518 // Iterate through the offsets of a given key. 519 for (offset_it = range.first; offset_it != range.second; offset_it++) { 520 Instruction* instr = assm_->InstructionAt(offset_it->second); 521 522 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 523 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 524 instr->SetImmPCOffsetTarget(assm_->pc()); 525 } 526 assm_->dc64(data); 527 } 528 shared_entries_.clear(); 529 shared_entries_count = 0; 530 531 // Emit unique entries. 532 std::vector<std::pair<uint64_t, int> >::const_iterator unique_it; 533 for (unique_it = unique_entries_.begin(); 534 unique_it != unique_entries_.end(); 535 unique_it++) { 536 Instruction* instr = assm_->InstructionAt(unique_it->second); 537 538 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 539 DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 540 instr->SetImmPCOffsetTarget(assm_->pc()); 541 assm_->dc64(unique_it->first); 542 } 543 unique_entries_.clear(); 544 first_use_ = -1; 545 } 546 547 548 // Assembler 549 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 550 : AssemblerBase(isolate, buffer, buffer_size), 551 constpool_(this), 552 recorded_ast_id_(TypeFeedbackId::None()), 553 unresolved_branches_(), 554 positions_recorder_(this) { 555 const_pool_blocked_nesting_ = 0; 556 veneer_pool_blocked_nesting_ = 0; 557 Reset(); 558 } 559 560 561 Assembler::~Assembler() { 562 DCHECK(constpool_.IsEmpty()); 563 DCHECK(const_pool_blocked_nesting_ == 0); 564 DCHECK(veneer_pool_blocked_nesting_ == 0); 565 } 566 567 568 void Assembler::Reset() { 569 #ifdef DEBUG 570 DCHECK((pc_ >= buffer_) && (pc_ < buffer_ + buffer_size_)); 571 DCHECK(const_pool_blocked_nesting_ == 0); 572 DCHECK(veneer_pool_blocked_nesting_ == 0); 573 DCHECK(unresolved_branches_.empty()); 574 memset(buffer_, 0, pc_ - buffer_); 575 #endif 576 pc_ = buffer_; 577 reloc_info_writer.Reposition(reinterpret_cast<byte*>(buffer_ + buffer_size_), 578 reinterpret_cast<byte*>(pc_)); 579 constpool_.Clear(); 580 next_constant_pool_check_ = 0; 581 next_veneer_pool_check_ = kMaxInt; 582 no_const_pool_before_ = 0; 583 ClearRecordedAstId(); 584 } 585 586 587 void Assembler::GetCode(CodeDesc* desc) { 588 // Emit constant pool if necessary. 589 CheckConstPool(true, false); 590 DCHECK(constpool_.IsEmpty()); 591 592 // Set up code descriptor. 593 if (desc) { 594 desc->buffer = reinterpret_cast<byte*>(buffer_); 595 desc->buffer_size = buffer_size_; 596 desc->instr_size = pc_offset(); 597 desc->reloc_size = (reinterpret_cast<byte*>(buffer_) + buffer_size_) - 598 reloc_info_writer.pos(); 599 desc->origin = this; 600 } 601 } 602 603 604 void Assembler::Align(int m) { 605 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 606 while ((pc_offset() & (m - 1)) != 0) { 607 nop(); 608 } 609 } 610 611 612 void Assembler::CheckLabelLinkChain(Label const * label) { 613 #ifdef DEBUG 614 if (label->is_linked()) { 615 int linkoffset = label->pos(); 616 bool end_of_chain = false; 617 while (!end_of_chain) { 618 Instruction * link = InstructionAt(linkoffset); 619 int linkpcoffset = link->ImmPCOffset(); 620 int prevlinkoffset = linkoffset + linkpcoffset; 621 622 end_of_chain = (linkoffset == prevlinkoffset); 623 linkoffset = linkoffset + linkpcoffset; 624 } 625 } 626 #endif 627 } 628 629 630 void Assembler::RemoveBranchFromLabelLinkChain(Instruction* branch, 631 Label* label, 632 Instruction* label_veneer) { 633 DCHECK(label->is_linked()); 634 635 CheckLabelLinkChain(label); 636 637 Instruction* link = InstructionAt(label->pos()); 638 Instruction* prev_link = link; 639 Instruction* next_link; 640 bool end_of_chain = false; 641 642 while (link != branch && !end_of_chain) { 643 next_link = link->ImmPCOffsetTarget(); 644 end_of_chain = (link == next_link); 645 prev_link = link; 646 link = next_link; 647 } 648 649 DCHECK(branch == link); 650 next_link = branch->ImmPCOffsetTarget(); 651 652 if (branch == prev_link) { 653 // The branch is the first instruction in the chain. 654 if (branch == next_link) { 655 // It is also the last instruction in the chain, so it is the only branch 656 // currently referring to this label. 657 label->Unuse(); 658 } else { 659 label->link_to(reinterpret_cast<byte*>(next_link) - buffer_); 660 } 661 662 } else if (branch == next_link) { 663 // The branch is the last (but not also the first) instruction in the chain. 664 prev_link->SetImmPCOffsetTarget(prev_link); 665 666 } else { 667 // The branch is in the middle of the chain. 668 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { 669 prev_link->SetImmPCOffsetTarget(next_link); 670 } else if (label_veneer != NULL) { 671 // Use the veneer for all previous links in the chain. 672 prev_link->SetImmPCOffsetTarget(prev_link); 673 674 end_of_chain = false; 675 link = next_link; 676 while (!end_of_chain) { 677 next_link = link->ImmPCOffsetTarget(); 678 end_of_chain = (link == next_link); 679 link->SetImmPCOffsetTarget(label_veneer); 680 link = next_link; 681 } 682 } else { 683 // The assert below will fire. 684 // Some other work could be attempted to fix up the chain, but it would be 685 // rather complicated. If we crash here, we may want to consider using an 686 // other mechanism than a chain of branches. 687 // 688 // Note that this situation currently should not happen, as we always call 689 // this function with a veneer to the target label. 690 // However this could happen with a MacroAssembler in the following state: 691 // [previous code] 692 // B(label); 693 // [20KB code] 694 // Tbz(label); // First tbz. Pointing to unconditional branch. 695 // [20KB code] 696 // Tbz(label); // Second tbz. Pointing to the first tbz. 697 // [more code] 698 // and this function is called to remove the first tbz from the label link 699 // chain. Since tbz has a range of +-32KB, the second tbz cannot point to 700 // the unconditional branch. 701 CHECK(prev_link->IsTargetInImmPCOffsetRange(next_link)); 702 UNREACHABLE(); 703 } 704 } 705 706 CheckLabelLinkChain(label); 707 } 708 709 710 void Assembler::bind(Label* label) { 711 // Bind label to the address at pc_. All instructions (most likely branches) 712 // that are linked to this label will be updated to point to the newly-bound 713 // label. 714 715 DCHECK(!label->is_near_linked()); 716 DCHECK(!label->is_bound()); 717 718 DeleteUnresolvedBranchInfoForLabel(label); 719 720 // If the label is linked, the link chain looks something like this: 721 // 722 // |--I----I-------I-------L 723 // |---------------------->| pc_offset 724 // |-------------->| linkoffset = label->pos() 725 // |<------| link->ImmPCOffset() 726 // |------>| prevlinkoffset = linkoffset + link->ImmPCOffset() 727 // 728 // On each iteration, the last link is updated and then removed from the 729 // chain until only one remains. At that point, the label is bound. 730 // 731 // If the label is not linked, no preparation is required before binding. 732 while (label->is_linked()) { 733 int linkoffset = label->pos(); 734 Instruction* link = InstructionAt(linkoffset); 735 int prevlinkoffset = linkoffset + link->ImmPCOffset(); 736 737 CheckLabelLinkChain(label); 738 739 DCHECK(linkoffset >= 0); 740 DCHECK(linkoffset < pc_offset()); 741 DCHECK((linkoffset > prevlinkoffset) || 742 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); 743 DCHECK(prevlinkoffset >= 0); 744 745 // Update the link to point to the label. 746 link->SetImmPCOffsetTarget(reinterpret_cast<Instruction*>(pc_)); 747 748 // Link the label to the previous link in the chain. 749 if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) { 750 // We hit kStartOfLabelLinkChain, so the chain is fully processed. 751 label->Unuse(); 752 } else { 753 // Update the label for the next iteration. 754 label->link_to(prevlinkoffset); 755 } 756 } 757 label->bind_to(pc_offset()); 758 759 DCHECK(label->is_bound()); 760 DCHECK(!label->is_linked()); 761 } 762 763 764 int Assembler::LinkAndGetByteOffsetTo(Label* label) { 765 DCHECK(sizeof(*pc_) == 1); 766 CheckLabelLinkChain(label); 767 768 int offset; 769 if (label->is_bound()) { 770 // The label is bound, so it does not need to be updated. Referring 771 // instructions must link directly to the label as they will not be 772 // updated. 773 // 774 // In this case, label->pos() returns the offset of the label from the 775 // start of the buffer. 776 // 777 // Note that offset can be zero for self-referential instructions. (This 778 // could be useful for ADR, for example.) 779 offset = label->pos() - pc_offset(); 780 DCHECK(offset <= 0); 781 } else { 782 if (label->is_linked()) { 783 // The label is linked, so the referring instruction should be added onto 784 // the end of the label's link chain. 785 // 786 // In this case, label->pos() returns the offset of the last linked 787 // instruction from the start of the buffer. 788 offset = label->pos() - pc_offset(); 789 DCHECK(offset != kStartOfLabelLinkChain); 790 // Note that the offset here needs to be PC-relative only so that the 791 // first instruction in a buffer can link to an unbound label. Otherwise, 792 // the offset would be 0 for this case, and 0 is reserved for 793 // kStartOfLabelLinkChain. 794 } else { 795 // The label is unused, so it now becomes linked and the referring 796 // instruction is at the start of the new link chain. 797 offset = kStartOfLabelLinkChain; 798 } 799 // The instruction at pc is now the last link in the label's chain. 800 label->link_to(pc_offset()); 801 } 802 803 return offset; 804 } 805 806 807 void Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) { 808 DCHECK(label->is_linked()); 809 CheckLabelLinkChain(label); 810 811 int link_offset = label->pos(); 812 int link_pcoffset; 813 bool end_of_chain = false; 814 815 while (!end_of_chain) { 816 Instruction * link = InstructionAt(link_offset); 817 link_pcoffset = link->ImmPCOffset(); 818 819 // ADR instructions are not handled by veneers. 820 if (link->IsImmBranch()) { 821 int max_reachable_pc = InstructionOffset(link) + 822 Instruction::ImmBranchRange(link->BranchType()); 823 typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it; 824 std::pair<unresolved_info_it, unresolved_info_it> range; 825 range = unresolved_branches_.equal_range(max_reachable_pc); 826 unresolved_info_it it; 827 for (it = range.first; it != range.second; ++it) { 828 if (it->second.pc_offset_ == link_offset) { 829 unresolved_branches_.erase(it); 830 break; 831 } 832 } 833 } 834 835 end_of_chain = (link_pcoffset == 0); 836 link_offset = link_offset + link_pcoffset; 837 } 838 } 839 840 841 void Assembler::DeleteUnresolvedBranchInfoForLabel(Label* label) { 842 if (unresolved_branches_.empty()) { 843 DCHECK(next_veneer_pool_check_ == kMaxInt); 844 return; 845 } 846 847 if (label->is_linked()) { 848 // Branches to this label will be resolved when the label is bound, normally 849 // just after all the associated info has been deleted. 850 DeleteUnresolvedBranchInfoForLabelTraverse(label); 851 } 852 if (unresolved_branches_.empty()) { 853 next_veneer_pool_check_ = kMaxInt; 854 } else { 855 next_veneer_pool_check_ = 856 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 857 } 858 } 859 860 861 void Assembler::StartBlockConstPool() { 862 if (const_pool_blocked_nesting_++ == 0) { 863 // Prevent constant pool checks happening by setting the next check to 864 // the biggest possible offset. 865 next_constant_pool_check_ = kMaxInt; 866 } 867 } 868 869 870 void Assembler::EndBlockConstPool() { 871 if (--const_pool_blocked_nesting_ == 0) { 872 // Check the constant pool hasn't been blocked for too long. 873 DCHECK(pc_offset() < constpool_.MaxPcOffset()); 874 // Two cases: 875 // * no_const_pool_before_ >= next_constant_pool_check_ and the emission is 876 // still blocked 877 // * no_const_pool_before_ < next_constant_pool_check_ and the next emit 878 // will trigger a check. 879 next_constant_pool_check_ = no_const_pool_before_; 880 } 881 } 882 883 884 bool Assembler::is_const_pool_blocked() const { 885 return (const_pool_blocked_nesting_ > 0) || 886 (pc_offset() < no_const_pool_before_); 887 } 888 889 890 bool Assembler::IsConstantPoolAt(Instruction* instr) { 891 // The constant pool marker is made of two instructions. These instructions 892 // will never be emitted by the JIT, so checking for the first one is enough: 893 // 0: ldr xzr, #<size of pool> 894 bool result = instr->IsLdrLiteralX() && (instr->Rt() == xzr.code()); 895 896 // It is still worth asserting the marker is complete. 897 // 4: blr xzr 898 DCHECK(!result || (instr->following()->IsBranchAndLinkToRegister() && 899 instr->following()->Rn() == xzr.code())); 900 901 return result; 902 } 903 904 905 int Assembler::ConstantPoolSizeAt(Instruction* instr) { 906 #ifdef USE_SIMULATOR 907 // Assembler::debug() embeds constants directly into the instruction stream. 908 // Although this is not a genuine constant pool, treat it like one to avoid 909 // disassembling the constants. 910 if ((instr->Mask(ExceptionMask) == HLT) && 911 (instr->ImmException() == kImmExceptionIsDebug)) { 912 const char* message = 913 reinterpret_cast<const char*>( 914 instr->InstructionAtOffset(kDebugMessageOffset)); 915 int size = kDebugMessageOffset + strlen(message) + 1; 916 return RoundUp(size, kInstructionSize) / kInstructionSize; 917 } 918 // Same for printf support, see MacroAssembler::CallPrintf(). 919 if ((instr->Mask(ExceptionMask) == HLT) && 920 (instr->ImmException() == kImmExceptionIsPrintf)) { 921 return kPrintfLength / kInstructionSize; 922 } 923 #endif 924 if (IsConstantPoolAt(instr)) { 925 return instr->ImmLLiteral(); 926 } else { 927 return -1; 928 } 929 } 930 931 932 void Assembler::EmitPoolGuard() { 933 // We must generate only one instruction as this is used in scopes that 934 // control the size of the code generated. 935 Emit(BLR | Rn(xzr)); 936 } 937 938 939 void Assembler::StartBlockVeneerPool() { 940 ++veneer_pool_blocked_nesting_; 941 } 942 943 944 void Assembler::EndBlockVeneerPool() { 945 if (--veneer_pool_blocked_nesting_ == 0) { 946 // Check the veneer pool hasn't been blocked for too long. 947 DCHECK(unresolved_branches_.empty() || 948 (pc_offset() < unresolved_branches_first_limit())); 949 } 950 } 951 952 953 void Assembler::br(const Register& xn) { 954 positions_recorder()->WriteRecordedPositions(); 955 DCHECK(xn.Is64Bits()); 956 Emit(BR | Rn(xn)); 957 } 958 959 960 void Assembler::blr(const Register& xn) { 961 positions_recorder()->WriteRecordedPositions(); 962 DCHECK(xn.Is64Bits()); 963 // The pattern 'blr xzr' is used as a guard to detect when execution falls 964 // through the constant pool. It should not be emitted. 965 DCHECK(!xn.Is(xzr)); 966 Emit(BLR | Rn(xn)); 967 } 968 969 970 void Assembler::ret(const Register& xn) { 971 positions_recorder()->WriteRecordedPositions(); 972 DCHECK(xn.Is64Bits()); 973 Emit(RET | Rn(xn)); 974 } 975 976 977 void Assembler::b(int imm26) { 978 Emit(B | ImmUncondBranch(imm26)); 979 } 980 981 982 void Assembler::b(Label* label) { 983 positions_recorder()->WriteRecordedPositions(); 984 b(LinkAndGetInstructionOffsetTo(label)); 985 } 986 987 988 void Assembler::b(int imm19, Condition cond) { 989 Emit(B_cond | ImmCondBranch(imm19) | cond); 990 } 991 992 993 void Assembler::b(Label* label, Condition cond) { 994 positions_recorder()->WriteRecordedPositions(); 995 b(LinkAndGetInstructionOffsetTo(label), cond); 996 } 997 998 999 void Assembler::bl(int imm26) { 1000 positions_recorder()->WriteRecordedPositions(); 1001 Emit(BL | ImmUncondBranch(imm26)); 1002 } 1003 1004 1005 void Assembler::bl(Label* label) { 1006 positions_recorder()->WriteRecordedPositions(); 1007 bl(LinkAndGetInstructionOffsetTo(label)); 1008 } 1009 1010 1011 void Assembler::cbz(const Register& rt, 1012 int imm19) { 1013 positions_recorder()->WriteRecordedPositions(); 1014 Emit(SF(rt) | CBZ | ImmCmpBranch(imm19) | Rt(rt)); 1015 } 1016 1017 1018 void Assembler::cbz(const Register& rt, 1019 Label* label) { 1020 positions_recorder()->WriteRecordedPositions(); 1021 cbz(rt, LinkAndGetInstructionOffsetTo(label)); 1022 } 1023 1024 1025 void Assembler::cbnz(const Register& rt, 1026 int imm19) { 1027 positions_recorder()->WriteRecordedPositions(); 1028 Emit(SF(rt) | CBNZ | ImmCmpBranch(imm19) | Rt(rt)); 1029 } 1030 1031 1032 void Assembler::cbnz(const Register& rt, 1033 Label* label) { 1034 positions_recorder()->WriteRecordedPositions(); 1035 cbnz(rt, LinkAndGetInstructionOffsetTo(label)); 1036 } 1037 1038 1039 void Assembler::tbz(const Register& rt, 1040 unsigned bit_pos, 1041 int imm14) { 1042 positions_recorder()->WriteRecordedPositions(); 1043 DCHECK(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSizeInBits))); 1044 Emit(TBZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt)); 1045 } 1046 1047 1048 void Assembler::tbz(const Register& rt, 1049 unsigned bit_pos, 1050 Label* label) { 1051 positions_recorder()->WriteRecordedPositions(); 1052 tbz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label)); 1053 } 1054 1055 1056 void Assembler::tbnz(const Register& rt, 1057 unsigned bit_pos, 1058 int imm14) { 1059 positions_recorder()->WriteRecordedPositions(); 1060 DCHECK(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSizeInBits))); 1061 Emit(TBNZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt)); 1062 } 1063 1064 1065 void Assembler::tbnz(const Register& rt, 1066 unsigned bit_pos, 1067 Label* label) { 1068 positions_recorder()->WriteRecordedPositions(); 1069 tbnz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label)); 1070 } 1071 1072 1073 void Assembler::adr(const Register& rd, int imm21) { 1074 DCHECK(rd.Is64Bits()); 1075 Emit(ADR | ImmPCRelAddress(imm21) | Rd(rd)); 1076 } 1077 1078 1079 void Assembler::adr(const Register& rd, Label* label) { 1080 adr(rd, LinkAndGetByteOffsetTo(label)); 1081 } 1082 1083 1084 void Assembler::add(const Register& rd, 1085 const Register& rn, 1086 const Operand& operand) { 1087 AddSub(rd, rn, operand, LeaveFlags, ADD); 1088 } 1089 1090 1091 void Assembler::adds(const Register& rd, 1092 const Register& rn, 1093 const Operand& operand) { 1094 AddSub(rd, rn, operand, SetFlags, ADD); 1095 } 1096 1097 1098 void Assembler::cmn(const Register& rn, 1099 const Operand& operand) { 1100 Register zr = AppropriateZeroRegFor(rn); 1101 adds(zr, rn, operand); 1102 } 1103 1104 1105 void Assembler::sub(const Register& rd, 1106 const Register& rn, 1107 const Operand& operand) { 1108 AddSub(rd, rn, operand, LeaveFlags, SUB); 1109 } 1110 1111 1112 void Assembler::subs(const Register& rd, 1113 const Register& rn, 1114 const Operand& operand) { 1115 AddSub(rd, rn, operand, SetFlags, SUB); 1116 } 1117 1118 1119 void Assembler::cmp(const Register& rn, const Operand& operand) { 1120 Register zr = AppropriateZeroRegFor(rn); 1121 subs(zr, rn, operand); 1122 } 1123 1124 1125 void Assembler::neg(const Register& rd, const Operand& operand) { 1126 Register zr = AppropriateZeroRegFor(rd); 1127 sub(rd, zr, operand); 1128 } 1129 1130 1131 void Assembler::negs(const Register& rd, const Operand& operand) { 1132 Register zr = AppropriateZeroRegFor(rd); 1133 subs(rd, zr, operand); 1134 } 1135 1136 1137 void Assembler::adc(const Register& rd, 1138 const Register& rn, 1139 const Operand& operand) { 1140 AddSubWithCarry(rd, rn, operand, LeaveFlags, ADC); 1141 } 1142 1143 1144 void Assembler::adcs(const Register& rd, 1145 const Register& rn, 1146 const Operand& operand) { 1147 AddSubWithCarry(rd, rn, operand, SetFlags, ADC); 1148 } 1149 1150 1151 void Assembler::sbc(const Register& rd, 1152 const Register& rn, 1153 const Operand& operand) { 1154 AddSubWithCarry(rd, rn, operand, LeaveFlags, SBC); 1155 } 1156 1157 1158 void Assembler::sbcs(const Register& rd, 1159 const Register& rn, 1160 const Operand& operand) { 1161 AddSubWithCarry(rd, rn, operand, SetFlags, SBC); 1162 } 1163 1164 1165 void Assembler::ngc(const Register& rd, const Operand& operand) { 1166 Register zr = AppropriateZeroRegFor(rd); 1167 sbc(rd, zr, operand); 1168 } 1169 1170 1171 void Assembler::ngcs(const Register& rd, const Operand& operand) { 1172 Register zr = AppropriateZeroRegFor(rd); 1173 sbcs(rd, zr, operand); 1174 } 1175 1176 1177 // Logical instructions. 1178 void Assembler::and_(const Register& rd, 1179 const Register& rn, 1180 const Operand& operand) { 1181 Logical(rd, rn, operand, AND); 1182 } 1183 1184 1185 void Assembler::ands(const Register& rd, 1186 const Register& rn, 1187 const Operand& operand) { 1188 Logical(rd, rn, operand, ANDS); 1189 } 1190 1191 1192 void Assembler::tst(const Register& rn, 1193 const Operand& operand) { 1194 ands(AppropriateZeroRegFor(rn), rn, operand); 1195 } 1196 1197 1198 void Assembler::bic(const Register& rd, 1199 const Register& rn, 1200 const Operand& operand) { 1201 Logical(rd, rn, operand, BIC); 1202 } 1203 1204 1205 void Assembler::bics(const Register& rd, 1206 const Register& rn, 1207 const Operand& operand) { 1208 Logical(rd, rn, operand, BICS); 1209 } 1210 1211 1212 void Assembler::orr(const Register& rd, 1213 const Register& rn, 1214 const Operand& operand) { 1215 Logical(rd, rn, operand, ORR); 1216 } 1217 1218 1219 void Assembler::orn(const Register& rd, 1220 const Register& rn, 1221 const Operand& operand) { 1222 Logical(rd, rn, operand, ORN); 1223 } 1224 1225 1226 void Assembler::eor(const Register& rd, 1227 const Register& rn, 1228 const Operand& operand) { 1229 Logical(rd, rn, operand, EOR); 1230 } 1231 1232 1233 void Assembler::eon(const Register& rd, 1234 const Register& rn, 1235 const Operand& operand) { 1236 Logical(rd, rn, operand, EON); 1237 } 1238 1239 1240 void Assembler::lslv(const Register& rd, 1241 const Register& rn, 1242 const Register& rm) { 1243 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1244 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1245 Emit(SF(rd) | LSLV | Rm(rm) | Rn(rn) | Rd(rd)); 1246 } 1247 1248 1249 void Assembler::lsrv(const Register& rd, 1250 const Register& rn, 1251 const Register& rm) { 1252 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1253 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1254 Emit(SF(rd) | LSRV | Rm(rm) | Rn(rn) | Rd(rd)); 1255 } 1256 1257 1258 void Assembler::asrv(const Register& rd, 1259 const Register& rn, 1260 const Register& rm) { 1261 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1262 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1263 Emit(SF(rd) | ASRV | Rm(rm) | Rn(rn) | Rd(rd)); 1264 } 1265 1266 1267 void Assembler::rorv(const Register& rd, 1268 const Register& rn, 1269 const Register& rm) { 1270 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1271 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1272 Emit(SF(rd) | RORV | Rm(rm) | Rn(rn) | Rd(rd)); 1273 } 1274 1275 1276 // Bitfield operations. 1277 void Assembler::bfm(const Register& rd, 1278 const Register& rn, 1279 unsigned immr, 1280 unsigned imms) { 1281 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1282 Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1283 Emit(SF(rd) | BFM | N | 1284 ImmR(immr, rd.SizeInBits()) | 1285 ImmS(imms, rn.SizeInBits()) | 1286 Rn(rn) | Rd(rd)); 1287 } 1288 1289 1290 void Assembler::sbfm(const Register& rd, 1291 const Register& rn, 1292 unsigned immr, 1293 unsigned imms) { 1294 DCHECK(rd.Is64Bits() || rn.Is32Bits()); 1295 Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1296 Emit(SF(rd) | SBFM | N | 1297 ImmR(immr, rd.SizeInBits()) | 1298 ImmS(imms, rn.SizeInBits()) | 1299 Rn(rn) | Rd(rd)); 1300 } 1301 1302 1303 void Assembler::ubfm(const Register& rd, 1304 const Register& rn, 1305 unsigned immr, 1306 unsigned imms) { 1307 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1308 Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1309 Emit(SF(rd) | UBFM | N | 1310 ImmR(immr, rd.SizeInBits()) | 1311 ImmS(imms, rn.SizeInBits()) | 1312 Rn(rn) | Rd(rd)); 1313 } 1314 1315 1316 void Assembler::extr(const Register& rd, 1317 const Register& rn, 1318 const Register& rm, 1319 unsigned lsb) { 1320 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1321 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1322 Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1323 Emit(SF(rd) | EXTR | N | Rm(rm) | 1324 ImmS(lsb, rn.SizeInBits()) | Rn(rn) | Rd(rd)); 1325 } 1326 1327 1328 void Assembler::csel(const Register& rd, 1329 const Register& rn, 1330 const Register& rm, 1331 Condition cond) { 1332 ConditionalSelect(rd, rn, rm, cond, CSEL); 1333 } 1334 1335 1336 void Assembler::csinc(const Register& rd, 1337 const Register& rn, 1338 const Register& rm, 1339 Condition cond) { 1340 ConditionalSelect(rd, rn, rm, cond, CSINC); 1341 } 1342 1343 1344 void Assembler::csinv(const Register& rd, 1345 const Register& rn, 1346 const Register& rm, 1347 Condition cond) { 1348 ConditionalSelect(rd, rn, rm, cond, CSINV); 1349 } 1350 1351 1352 void Assembler::csneg(const Register& rd, 1353 const Register& rn, 1354 const Register& rm, 1355 Condition cond) { 1356 ConditionalSelect(rd, rn, rm, cond, CSNEG); 1357 } 1358 1359 1360 void Assembler::cset(const Register &rd, Condition cond) { 1361 DCHECK((cond != al) && (cond != nv)); 1362 Register zr = AppropriateZeroRegFor(rd); 1363 csinc(rd, zr, zr, NegateCondition(cond)); 1364 } 1365 1366 1367 void Assembler::csetm(const Register &rd, Condition cond) { 1368 DCHECK((cond != al) && (cond != nv)); 1369 Register zr = AppropriateZeroRegFor(rd); 1370 csinv(rd, zr, zr, NegateCondition(cond)); 1371 } 1372 1373 1374 void Assembler::cinc(const Register &rd, const Register &rn, Condition cond) { 1375 DCHECK((cond != al) && (cond != nv)); 1376 csinc(rd, rn, rn, NegateCondition(cond)); 1377 } 1378 1379 1380 void Assembler::cinv(const Register &rd, const Register &rn, Condition cond) { 1381 DCHECK((cond != al) && (cond != nv)); 1382 csinv(rd, rn, rn, NegateCondition(cond)); 1383 } 1384 1385 1386 void Assembler::cneg(const Register &rd, const Register &rn, Condition cond) { 1387 DCHECK((cond != al) && (cond != nv)); 1388 csneg(rd, rn, rn, NegateCondition(cond)); 1389 } 1390 1391 1392 void Assembler::ConditionalSelect(const Register& rd, 1393 const Register& rn, 1394 const Register& rm, 1395 Condition cond, 1396 ConditionalSelectOp op) { 1397 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1398 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1399 Emit(SF(rd) | op | Rm(rm) | Cond(cond) | Rn(rn) | Rd(rd)); 1400 } 1401 1402 1403 void Assembler::ccmn(const Register& rn, 1404 const Operand& operand, 1405 StatusFlags nzcv, 1406 Condition cond) { 1407 ConditionalCompare(rn, operand, nzcv, cond, CCMN); 1408 } 1409 1410 1411 void Assembler::ccmp(const Register& rn, 1412 const Operand& operand, 1413 StatusFlags nzcv, 1414 Condition cond) { 1415 ConditionalCompare(rn, operand, nzcv, cond, CCMP); 1416 } 1417 1418 1419 void Assembler::DataProcessing3Source(const Register& rd, 1420 const Register& rn, 1421 const Register& rm, 1422 const Register& ra, 1423 DataProcessing3SourceOp op) { 1424 Emit(SF(rd) | op | Rm(rm) | Ra(ra) | Rn(rn) | Rd(rd)); 1425 } 1426 1427 1428 void Assembler::mul(const Register& rd, 1429 const Register& rn, 1430 const Register& rm) { 1431 DCHECK(AreSameSizeAndType(rd, rn, rm)); 1432 Register zr = AppropriateZeroRegFor(rn); 1433 DataProcessing3Source(rd, rn, rm, zr, MADD); 1434 } 1435 1436 1437 void Assembler::madd(const Register& rd, 1438 const Register& rn, 1439 const Register& rm, 1440 const Register& ra) { 1441 DCHECK(AreSameSizeAndType(rd, rn, rm, ra)); 1442 DataProcessing3Source(rd, rn, rm, ra, MADD); 1443 } 1444 1445 1446 void Assembler::mneg(const Register& rd, 1447 const Register& rn, 1448 const Register& rm) { 1449 DCHECK(AreSameSizeAndType(rd, rn, rm)); 1450 Register zr = AppropriateZeroRegFor(rn); 1451 DataProcessing3Source(rd, rn, rm, zr, MSUB); 1452 } 1453 1454 1455 void Assembler::msub(const Register& rd, 1456 const Register& rn, 1457 const Register& rm, 1458 const Register& ra) { 1459 DCHECK(AreSameSizeAndType(rd, rn, rm, ra)); 1460 DataProcessing3Source(rd, rn, rm, ra, MSUB); 1461 } 1462 1463 1464 void Assembler::smaddl(const Register& rd, 1465 const Register& rn, 1466 const Register& rm, 1467 const Register& ra) { 1468 DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1469 DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1470 DataProcessing3Source(rd, rn, rm, ra, SMADDL_x); 1471 } 1472 1473 1474 void Assembler::smsubl(const Register& rd, 1475 const Register& rn, 1476 const Register& rm, 1477 const Register& ra) { 1478 DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1479 DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1480 DataProcessing3Source(rd, rn, rm, ra, SMSUBL_x); 1481 } 1482 1483 1484 void Assembler::umaddl(const Register& rd, 1485 const Register& rn, 1486 const Register& rm, 1487 const Register& ra) { 1488 DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1489 DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1490 DataProcessing3Source(rd, rn, rm, ra, UMADDL_x); 1491 } 1492 1493 1494 void Assembler::umsubl(const Register& rd, 1495 const Register& rn, 1496 const Register& rm, 1497 const Register& ra) { 1498 DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1499 DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1500 DataProcessing3Source(rd, rn, rm, ra, UMSUBL_x); 1501 } 1502 1503 1504 void Assembler::smull(const Register& rd, 1505 const Register& rn, 1506 const Register& rm) { 1507 DCHECK(rd.Is64Bits()); 1508 DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1509 DataProcessing3Source(rd, rn, rm, xzr, SMADDL_x); 1510 } 1511 1512 1513 void Assembler::smulh(const Register& rd, 1514 const Register& rn, 1515 const Register& rm) { 1516 DCHECK(AreSameSizeAndType(rd, rn, rm)); 1517 DataProcessing3Source(rd, rn, rm, xzr, SMULH_x); 1518 } 1519 1520 1521 void Assembler::sdiv(const Register& rd, 1522 const Register& rn, 1523 const Register& rm) { 1524 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1525 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1526 Emit(SF(rd) | SDIV | Rm(rm) | Rn(rn) | Rd(rd)); 1527 } 1528 1529 1530 void Assembler::udiv(const Register& rd, 1531 const Register& rn, 1532 const Register& rm) { 1533 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1534 DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1535 Emit(SF(rd) | UDIV | Rm(rm) | Rn(rn) | Rd(rd)); 1536 } 1537 1538 1539 void Assembler::rbit(const Register& rd, 1540 const Register& rn) { 1541 DataProcessing1Source(rd, rn, RBIT); 1542 } 1543 1544 1545 void Assembler::rev16(const Register& rd, 1546 const Register& rn) { 1547 DataProcessing1Source(rd, rn, REV16); 1548 } 1549 1550 1551 void Assembler::rev32(const Register& rd, 1552 const Register& rn) { 1553 DCHECK(rd.Is64Bits()); 1554 DataProcessing1Source(rd, rn, REV); 1555 } 1556 1557 1558 void Assembler::rev(const Register& rd, 1559 const Register& rn) { 1560 DataProcessing1Source(rd, rn, rd.Is64Bits() ? REV_x : REV_w); 1561 } 1562 1563 1564 void Assembler::clz(const Register& rd, 1565 const Register& rn) { 1566 DataProcessing1Source(rd, rn, CLZ); 1567 } 1568 1569 1570 void Assembler::cls(const Register& rd, 1571 const Register& rn) { 1572 DataProcessing1Source(rd, rn, CLS); 1573 } 1574 1575 1576 void Assembler::ldp(const CPURegister& rt, 1577 const CPURegister& rt2, 1578 const MemOperand& src) { 1579 LoadStorePair(rt, rt2, src, LoadPairOpFor(rt, rt2)); 1580 } 1581 1582 1583 void Assembler::stp(const CPURegister& rt, 1584 const CPURegister& rt2, 1585 const MemOperand& dst) { 1586 LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2)); 1587 } 1588 1589 1590 void Assembler::ldpsw(const Register& rt, 1591 const Register& rt2, 1592 const MemOperand& src) { 1593 DCHECK(rt.Is64Bits()); 1594 LoadStorePair(rt, rt2, src, LDPSW_x); 1595 } 1596 1597 1598 void Assembler::LoadStorePair(const CPURegister& rt, 1599 const CPURegister& rt2, 1600 const MemOperand& addr, 1601 LoadStorePairOp op) { 1602 // 'rt' and 'rt2' can only be aliased for stores. 1603 DCHECK(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2)); 1604 DCHECK(AreSameSizeAndType(rt, rt2)); 1605 1606 Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | 1607 ImmLSPair(addr.offset(), CalcLSPairDataSize(op)); 1608 1609 Instr addrmodeop; 1610 if (addr.IsImmediateOffset()) { 1611 addrmodeop = LoadStorePairOffsetFixed; 1612 } else { 1613 // Pre-index and post-index modes. 1614 DCHECK(!rt.Is(addr.base())); 1615 DCHECK(!rt2.Is(addr.base())); 1616 DCHECK(addr.offset() != 0); 1617 if (addr.IsPreIndex()) { 1618 addrmodeop = LoadStorePairPreIndexFixed; 1619 } else { 1620 DCHECK(addr.IsPostIndex()); 1621 addrmodeop = LoadStorePairPostIndexFixed; 1622 } 1623 } 1624 Emit(addrmodeop | memop); 1625 } 1626 1627 1628 void Assembler::ldnp(const CPURegister& rt, 1629 const CPURegister& rt2, 1630 const MemOperand& src) { 1631 LoadStorePairNonTemporal(rt, rt2, src, 1632 LoadPairNonTemporalOpFor(rt, rt2)); 1633 } 1634 1635 1636 void Assembler::stnp(const CPURegister& rt, 1637 const CPURegister& rt2, 1638 const MemOperand& dst) { 1639 LoadStorePairNonTemporal(rt, rt2, dst, 1640 StorePairNonTemporalOpFor(rt, rt2)); 1641 } 1642 1643 1644 void Assembler::LoadStorePairNonTemporal(const CPURegister& rt, 1645 const CPURegister& rt2, 1646 const MemOperand& addr, 1647 LoadStorePairNonTemporalOp op) { 1648 DCHECK(!rt.Is(rt2)); 1649 DCHECK(AreSameSizeAndType(rt, rt2)); 1650 DCHECK(addr.IsImmediateOffset()); 1651 1652 LSDataSize size = CalcLSPairDataSize( 1653 static_cast<LoadStorePairOp>(op & LoadStorePairMask)); 1654 Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | 1655 ImmLSPair(addr.offset(), size)); 1656 } 1657 1658 1659 // Memory instructions. 1660 void Assembler::ldrb(const Register& rt, const MemOperand& src) { 1661 LoadStore(rt, src, LDRB_w); 1662 } 1663 1664 1665 void Assembler::strb(const Register& rt, const MemOperand& dst) { 1666 LoadStore(rt, dst, STRB_w); 1667 } 1668 1669 1670 void Assembler::ldrsb(const Register& rt, const MemOperand& src) { 1671 LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w); 1672 } 1673 1674 1675 void Assembler::ldrh(const Register& rt, const MemOperand& src) { 1676 LoadStore(rt, src, LDRH_w); 1677 } 1678 1679 1680 void Assembler::strh(const Register& rt, const MemOperand& dst) { 1681 LoadStore(rt, dst, STRH_w); 1682 } 1683 1684 1685 void Assembler::ldrsh(const Register& rt, const MemOperand& src) { 1686 LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w); 1687 } 1688 1689 1690 void Assembler::ldr(const CPURegister& rt, const MemOperand& src) { 1691 LoadStore(rt, src, LoadOpFor(rt)); 1692 } 1693 1694 1695 void Assembler::str(const CPURegister& rt, const MemOperand& src) { 1696 LoadStore(rt, src, StoreOpFor(rt)); 1697 } 1698 1699 1700 void Assembler::ldrsw(const Register& rt, const MemOperand& src) { 1701 DCHECK(rt.Is64Bits()); 1702 LoadStore(rt, src, LDRSW_x); 1703 } 1704 1705 1706 void Assembler::ldr_pcrel(const CPURegister& rt, int imm19) { 1707 // The pattern 'ldr xzr, #offset' is used to indicate the beginning of a 1708 // constant pool. It should not be emitted. 1709 DCHECK(!rt.IsZero()); 1710 Emit(LoadLiteralOpFor(rt) | ImmLLiteral(imm19) | Rt(rt)); 1711 } 1712 1713 1714 void Assembler::ldr(const CPURegister& rt, const Immediate& imm) { 1715 // Currently we only support 64-bit literals. 1716 DCHECK(rt.Is64Bits()); 1717 1718 RecordRelocInfo(imm.rmode(), imm.value()); 1719 BlockConstPoolFor(1); 1720 // The load will be patched when the constpool is emitted, patching code 1721 // expect a load literal with offset 0. 1722 ldr_pcrel(rt, 0); 1723 } 1724 1725 1726 void Assembler::mov(const Register& rd, const Register& rm) { 1727 // Moves involving the stack pointer are encoded as add immediate with 1728 // second operand of zero. Otherwise, orr with first operand zr is 1729 // used. 1730 if (rd.IsSP() || rm.IsSP()) { 1731 add(rd, rm, 0); 1732 } else { 1733 orr(rd, AppropriateZeroRegFor(rd), rm); 1734 } 1735 } 1736 1737 1738 void Assembler::mvn(const Register& rd, const Operand& operand) { 1739 orn(rd, AppropriateZeroRegFor(rd), operand); 1740 } 1741 1742 1743 void Assembler::mrs(const Register& rt, SystemRegister sysreg) { 1744 DCHECK(rt.Is64Bits()); 1745 Emit(MRS | ImmSystemRegister(sysreg) | Rt(rt)); 1746 } 1747 1748 1749 void Assembler::msr(SystemRegister sysreg, const Register& rt) { 1750 DCHECK(rt.Is64Bits()); 1751 Emit(MSR | Rt(rt) | ImmSystemRegister(sysreg)); 1752 } 1753 1754 1755 void Assembler::hint(SystemHint code) { 1756 Emit(HINT | ImmHint(code) | Rt(xzr)); 1757 } 1758 1759 1760 void Assembler::dmb(BarrierDomain domain, BarrierType type) { 1761 Emit(DMB | ImmBarrierDomain(domain) | ImmBarrierType(type)); 1762 } 1763 1764 1765 void Assembler::dsb(BarrierDomain domain, BarrierType type) { 1766 Emit(DSB | ImmBarrierDomain(domain) | ImmBarrierType(type)); 1767 } 1768 1769 1770 void Assembler::isb() { 1771 Emit(ISB | ImmBarrierDomain(FullSystem) | ImmBarrierType(BarrierAll)); 1772 } 1773 1774 1775 void Assembler::fmov(FPRegister fd, double imm) { 1776 DCHECK(fd.Is64Bits()); 1777 DCHECK(IsImmFP64(imm)); 1778 Emit(FMOV_d_imm | Rd(fd) | ImmFP64(imm)); 1779 } 1780 1781 1782 void Assembler::fmov(FPRegister fd, float imm) { 1783 DCHECK(fd.Is32Bits()); 1784 DCHECK(IsImmFP32(imm)); 1785 Emit(FMOV_s_imm | Rd(fd) | ImmFP32(imm)); 1786 } 1787 1788 1789 void Assembler::fmov(Register rd, FPRegister fn) { 1790 DCHECK(rd.SizeInBits() == fn.SizeInBits()); 1791 FPIntegerConvertOp op = rd.Is32Bits() ? FMOV_ws : FMOV_xd; 1792 Emit(op | Rd(rd) | Rn(fn)); 1793 } 1794 1795 1796 void Assembler::fmov(FPRegister fd, Register rn) { 1797 DCHECK(fd.SizeInBits() == rn.SizeInBits()); 1798 FPIntegerConvertOp op = fd.Is32Bits() ? FMOV_sw : FMOV_dx; 1799 Emit(op | Rd(fd) | Rn(rn)); 1800 } 1801 1802 1803 void Assembler::fmov(FPRegister fd, FPRegister fn) { 1804 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1805 Emit(FPType(fd) | FMOV | Rd(fd) | Rn(fn)); 1806 } 1807 1808 1809 void Assembler::fadd(const FPRegister& fd, 1810 const FPRegister& fn, 1811 const FPRegister& fm) { 1812 FPDataProcessing2Source(fd, fn, fm, FADD); 1813 } 1814 1815 1816 void Assembler::fsub(const FPRegister& fd, 1817 const FPRegister& fn, 1818 const FPRegister& fm) { 1819 FPDataProcessing2Source(fd, fn, fm, FSUB); 1820 } 1821 1822 1823 void Assembler::fmul(const FPRegister& fd, 1824 const FPRegister& fn, 1825 const FPRegister& fm) { 1826 FPDataProcessing2Source(fd, fn, fm, FMUL); 1827 } 1828 1829 1830 void Assembler::fmadd(const FPRegister& fd, 1831 const FPRegister& fn, 1832 const FPRegister& fm, 1833 const FPRegister& fa) { 1834 FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMADD_s : FMADD_d); 1835 } 1836 1837 1838 void Assembler::fmsub(const FPRegister& fd, 1839 const FPRegister& fn, 1840 const FPRegister& fm, 1841 const FPRegister& fa) { 1842 FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMSUB_s : FMSUB_d); 1843 } 1844 1845 1846 void Assembler::fnmadd(const FPRegister& fd, 1847 const FPRegister& fn, 1848 const FPRegister& fm, 1849 const FPRegister& fa) { 1850 FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMADD_s : FNMADD_d); 1851 } 1852 1853 1854 void Assembler::fnmsub(const FPRegister& fd, 1855 const FPRegister& fn, 1856 const FPRegister& fm, 1857 const FPRegister& fa) { 1858 FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMSUB_s : FNMSUB_d); 1859 } 1860 1861 1862 void Assembler::fdiv(const FPRegister& fd, 1863 const FPRegister& fn, 1864 const FPRegister& fm) { 1865 FPDataProcessing2Source(fd, fn, fm, FDIV); 1866 } 1867 1868 1869 void Assembler::fmax(const FPRegister& fd, 1870 const FPRegister& fn, 1871 const FPRegister& fm) { 1872 FPDataProcessing2Source(fd, fn, fm, FMAX); 1873 } 1874 1875 1876 void Assembler::fmaxnm(const FPRegister& fd, 1877 const FPRegister& fn, 1878 const FPRegister& fm) { 1879 FPDataProcessing2Source(fd, fn, fm, FMAXNM); 1880 } 1881 1882 1883 void Assembler::fmin(const FPRegister& fd, 1884 const FPRegister& fn, 1885 const FPRegister& fm) { 1886 FPDataProcessing2Source(fd, fn, fm, FMIN); 1887 } 1888 1889 1890 void Assembler::fminnm(const FPRegister& fd, 1891 const FPRegister& fn, 1892 const FPRegister& fm) { 1893 FPDataProcessing2Source(fd, fn, fm, FMINNM); 1894 } 1895 1896 1897 void Assembler::fabs(const FPRegister& fd, 1898 const FPRegister& fn) { 1899 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1900 FPDataProcessing1Source(fd, fn, FABS); 1901 } 1902 1903 1904 void Assembler::fneg(const FPRegister& fd, 1905 const FPRegister& fn) { 1906 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1907 FPDataProcessing1Source(fd, fn, FNEG); 1908 } 1909 1910 1911 void Assembler::fsqrt(const FPRegister& fd, 1912 const FPRegister& fn) { 1913 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1914 FPDataProcessing1Source(fd, fn, FSQRT); 1915 } 1916 1917 1918 void Assembler::frinta(const FPRegister& fd, 1919 const FPRegister& fn) { 1920 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1921 FPDataProcessing1Source(fd, fn, FRINTA); 1922 } 1923 1924 1925 void Assembler::frintm(const FPRegister& fd, 1926 const FPRegister& fn) { 1927 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1928 FPDataProcessing1Source(fd, fn, FRINTM); 1929 } 1930 1931 1932 void Assembler::frintn(const FPRegister& fd, 1933 const FPRegister& fn) { 1934 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1935 FPDataProcessing1Source(fd, fn, FRINTN); 1936 } 1937 1938 1939 void Assembler::frintz(const FPRegister& fd, 1940 const FPRegister& fn) { 1941 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1942 FPDataProcessing1Source(fd, fn, FRINTZ); 1943 } 1944 1945 1946 void Assembler::fcmp(const FPRegister& fn, 1947 const FPRegister& fm) { 1948 DCHECK(fn.SizeInBits() == fm.SizeInBits()); 1949 Emit(FPType(fn) | FCMP | Rm(fm) | Rn(fn)); 1950 } 1951 1952 1953 void Assembler::fcmp(const FPRegister& fn, 1954 double value) { 1955 USE(value); 1956 // Although the fcmp instruction can strictly only take an immediate value of 1957 // +0.0, we don't need to check for -0.0 because the sign of 0.0 doesn't 1958 // affect the result of the comparison. 1959 DCHECK(value == 0.0); 1960 Emit(FPType(fn) | FCMP_zero | Rn(fn)); 1961 } 1962 1963 1964 void Assembler::fccmp(const FPRegister& fn, 1965 const FPRegister& fm, 1966 StatusFlags nzcv, 1967 Condition cond) { 1968 DCHECK(fn.SizeInBits() == fm.SizeInBits()); 1969 Emit(FPType(fn) | FCCMP | Rm(fm) | Cond(cond) | Rn(fn) | Nzcv(nzcv)); 1970 } 1971 1972 1973 void Assembler::fcsel(const FPRegister& fd, 1974 const FPRegister& fn, 1975 const FPRegister& fm, 1976 Condition cond) { 1977 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1978 DCHECK(fd.SizeInBits() == fm.SizeInBits()); 1979 Emit(FPType(fd) | FCSEL | Rm(fm) | Cond(cond) | Rn(fn) | Rd(fd)); 1980 } 1981 1982 1983 void Assembler::FPConvertToInt(const Register& rd, 1984 const FPRegister& fn, 1985 FPIntegerConvertOp op) { 1986 Emit(SF(rd) | FPType(fn) | op | Rn(fn) | Rd(rd)); 1987 } 1988 1989 1990 void Assembler::fcvt(const FPRegister& fd, 1991 const FPRegister& fn) { 1992 if (fd.Is64Bits()) { 1993 // Convert float to double. 1994 DCHECK(fn.Is32Bits()); 1995 FPDataProcessing1Source(fd, fn, FCVT_ds); 1996 } else { 1997 // Convert double to float. 1998 DCHECK(fn.Is64Bits()); 1999 FPDataProcessing1Source(fd, fn, FCVT_sd); 2000 } 2001 } 2002 2003 2004 void Assembler::fcvtau(const Register& rd, const FPRegister& fn) { 2005 FPConvertToInt(rd, fn, FCVTAU); 2006 } 2007 2008 2009 void Assembler::fcvtas(const Register& rd, const FPRegister& fn) { 2010 FPConvertToInt(rd, fn, FCVTAS); 2011 } 2012 2013 2014 void Assembler::fcvtmu(const Register& rd, const FPRegister& fn) { 2015 FPConvertToInt(rd, fn, FCVTMU); 2016 } 2017 2018 2019 void Assembler::fcvtms(const Register& rd, const FPRegister& fn) { 2020 FPConvertToInt(rd, fn, FCVTMS); 2021 } 2022 2023 2024 void Assembler::fcvtnu(const Register& rd, const FPRegister& fn) { 2025 FPConvertToInt(rd, fn, FCVTNU); 2026 } 2027 2028 2029 void Assembler::fcvtns(const Register& rd, const FPRegister& fn) { 2030 FPConvertToInt(rd, fn, FCVTNS); 2031 } 2032 2033 2034 void Assembler::fcvtzu(const Register& rd, const FPRegister& fn) { 2035 FPConvertToInt(rd, fn, FCVTZU); 2036 } 2037 2038 2039 void Assembler::fcvtzs(const Register& rd, const FPRegister& fn) { 2040 FPConvertToInt(rd, fn, FCVTZS); 2041 } 2042 2043 2044 void Assembler::scvtf(const FPRegister& fd, 2045 const Register& rn, 2046 unsigned fbits) { 2047 if (fbits == 0) { 2048 Emit(SF(rn) | FPType(fd) | SCVTF | Rn(rn) | Rd(fd)); 2049 } else { 2050 Emit(SF(rn) | FPType(fd) | SCVTF_fixed | FPScale(64 - fbits) | Rn(rn) | 2051 Rd(fd)); 2052 } 2053 } 2054 2055 2056 void Assembler::ucvtf(const FPRegister& fd, 2057 const Register& rn, 2058 unsigned fbits) { 2059 if (fbits == 0) { 2060 Emit(SF(rn) | FPType(fd) | UCVTF | Rn(rn) | Rd(fd)); 2061 } else { 2062 Emit(SF(rn) | FPType(fd) | UCVTF_fixed | FPScale(64 - fbits) | Rn(rn) | 2063 Rd(fd)); 2064 } 2065 } 2066 2067 2068 // Note: 2069 // Below, a difference in case for the same letter indicates a 2070 // negated bit. 2071 // If b is 1, then B is 0. 2072 Instr Assembler::ImmFP32(float imm) { 2073 DCHECK(IsImmFP32(imm)); 2074 // bits: aBbb.bbbc.defg.h000.0000.0000.0000.0000 2075 uint32_t bits = float_to_rawbits(imm); 2076 // bit7: a000.0000 2077 uint32_t bit7 = ((bits >> 31) & 0x1) << 7; 2078 // bit6: 0b00.0000 2079 uint32_t bit6 = ((bits >> 29) & 0x1) << 6; 2080 // bit5_to_0: 00cd.efgh 2081 uint32_t bit5_to_0 = (bits >> 19) & 0x3f; 2082 2083 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; 2084 } 2085 2086 2087 Instr Assembler::ImmFP64(double imm) { 2088 DCHECK(IsImmFP64(imm)); 2089 // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 2090 // 0000.0000.0000.0000.0000.0000.0000.0000 2091 uint64_t bits = double_to_rawbits(imm); 2092 // bit7: a000.0000 2093 uint32_t bit7 = ((bits >> 63) & 0x1) << 7; 2094 // bit6: 0b00.0000 2095 uint32_t bit6 = ((bits >> 61) & 0x1) << 6; 2096 // bit5_to_0: 00cd.efgh 2097 uint32_t bit5_to_0 = (bits >> 48) & 0x3f; 2098 2099 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; 2100 } 2101 2102 2103 // Code generation helpers. 2104 void Assembler::MoveWide(const Register& rd, 2105 uint64_t imm, 2106 int shift, 2107 MoveWideImmediateOp mov_op) { 2108 // Ignore the top 32 bits of an immediate if we're moving to a W register. 2109 if (rd.Is32Bits()) { 2110 // Check that the top 32 bits are zero (a positive 32-bit number) or top 2111 // 33 bits are one (a negative 32-bit number, sign extended to 64 bits). 2112 DCHECK(((imm >> kWRegSizeInBits) == 0) || 2113 ((imm >> (kWRegSizeInBits - 1)) == 0x1ffffffff)); 2114 imm &= kWRegMask; 2115 } 2116 2117 if (shift >= 0) { 2118 // Explicit shift specified. 2119 DCHECK((shift == 0) || (shift == 16) || (shift == 32) || (shift == 48)); 2120 DCHECK(rd.Is64Bits() || (shift == 0) || (shift == 16)); 2121 shift /= 16; 2122 } else { 2123 // Calculate a new immediate and shift combination to encode the immediate 2124 // argument. 2125 shift = 0; 2126 if ((imm & ~0xffffUL) == 0) { 2127 // Nothing to do. 2128 } else if ((imm & ~(0xffffUL << 16)) == 0) { 2129 imm >>= 16; 2130 shift = 1; 2131 } else if ((imm & ~(0xffffUL << 32)) == 0) { 2132 DCHECK(rd.Is64Bits()); 2133 imm >>= 32; 2134 shift = 2; 2135 } else if ((imm & ~(0xffffUL << 48)) == 0) { 2136 DCHECK(rd.Is64Bits()); 2137 imm >>= 48; 2138 shift = 3; 2139 } 2140 } 2141 2142 DCHECK(is_uint16(imm)); 2143 2144 Emit(SF(rd) | MoveWideImmediateFixed | mov_op | 2145 Rd(rd) | ImmMoveWide(imm) | ShiftMoveWide(shift)); 2146 } 2147 2148 2149 void Assembler::AddSub(const Register& rd, 2150 const Register& rn, 2151 const Operand& operand, 2152 FlagsUpdate S, 2153 AddSubOp op) { 2154 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2155 DCHECK(!operand.NeedsRelocation(this)); 2156 if (operand.IsImmediate()) { 2157 int64_t immediate = operand.ImmediateValue(); 2158 DCHECK(IsImmAddSub(immediate)); 2159 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 2160 Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) | 2161 ImmAddSub(immediate) | dest_reg | RnSP(rn)); 2162 } else if (operand.IsShiftedRegister()) { 2163 DCHECK(operand.reg().SizeInBits() == rd.SizeInBits()); 2164 DCHECK(operand.shift() != ROR); 2165 2166 // For instructions of the form: 2167 // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ] 2168 // add/sub <Wd>, wsp, <Wm> [, LSL #0-3 ] 2169 // add/sub wsp, wsp, <Wm> [, LSL #0-3 ] 2170 // adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ] 2171 // or their 64-bit register equivalents, convert the operand from shifted to 2172 // extended register mode, and emit an add/sub extended instruction. 2173 if (rn.IsSP() || rd.IsSP()) { 2174 DCHECK(!(rd.IsSP() && (S == SetFlags))); 2175 DataProcExtendedRegister(rd, rn, operand.ToExtendedRegister(), S, 2176 AddSubExtendedFixed | op); 2177 } else { 2178 DataProcShiftedRegister(rd, rn, operand, S, AddSubShiftedFixed | op); 2179 } 2180 } else { 2181 DCHECK(operand.IsExtendedRegister()); 2182 DataProcExtendedRegister(rd, rn, operand, S, AddSubExtendedFixed | op); 2183 } 2184 } 2185 2186 2187 void Assembler::AddSubWithCarry(const Register& rd, 2188 const Register& rn, 2189 const Operand& operand, 2190 FlagsUpdate S, 2191 AddSubWithCarryOp op) { 2192 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2193 DCHECK(rd.SizeInBits() == operand.reg().SizeInBits()); 2194 DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2195 DCHECK(!operand.NeedsRelocation(this)); 2196 Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | Rn(rn) | Rd(rd)); 2197 } 2198 2199 2200 void Assembler::hlt(int code) { 2201 DCHECK(is_uint16(code)); 2202 Emit(HLT | ImmException(code)); 2203 } 2204 2205 2206 void Assembler::brk(int code) { 2207 DCHECK(is_uint16(code)); 2208 Emit(BRK | ImmException(code)); 2209 } 2210 2211 2212 void Assembler::EmitStringData(const char* string) { 2213 size_t len = strlen(string) + 1; 2214 DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap)); 2215 EmitData(string, len); 2216 // Pad with NULL characters until pc_ is aligned. 2217 const char pad[] = {'\0', '\0', '\0', '\0'}; 2218 STATIC_ASSERT(sizeof(pad) == kInstructionSize); 2219 EmitData(pad, RoundUp(pc_offset(), kInstructionSize) - pc_offset()); 2220 } 2221 2222 2223 void Assembler::debug(const char* message, uint32_t code, Instr params) { 2224 #ifdef USE_SIMULATOR 2225 // Don't generate simulator specific code if we are building a snapshot, which 2226 // might be run on real hardware. 2227 if (!serializer_enabled()) { 2228 // The arguments to the debug marker need to be contiguous in memory, so 2229 // make sure we don't try to emit pools. 2230 BlockPoolsScope scope(this); 2231 2232 Label start; 2233 bind(&start); 2234 2235 // Refer to instructions-arm64.h for a description of the marker and its 2236 // arguments. 2237 hlt(kImmExceptionIsDebug); 2238 DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugCodeOffset); 2239 dc32(code); 2240 DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugParamsOffset); 2241 dc32(params); 2242 DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugMessageOffset); 2243 EmitStringData(message); 2244 hlt(kImmExceptionIsUnreachable); 2245 2246 return; 2247 } 2248 // Fall through if Serializer is enabled. 2249 #endif 2250 2251 if (params & BREAK) { 2252 hlt(kImmExceptionIsDebug); 2253 } 2254 } 2255 2256 2257 void Assembler::Logical(const Register& rd, 2258 const Register& rn, 2259 const Operand& operand, 2260 LogicalOp op) { 2261 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2262 DCHECK(!operand.NeedsRelocation(this)); 2263 if (operand.IsImmediate()) { 2264 int64_t immediate = operand.ImmediateValue(); 2265 unsigned reg_size = rd.SizeInBits(); 2266 2267 DCHECK(immediate != 0); 2268 DCHECK(immediate != -1); 2269 DCHECK(rd.Is64Bits() || is_uint32(immediate)); 2270 2271 // If the operation is NOT, invert the operation and immediate. 2272 if ((op & NOT) == NOT) { 2273 op = static_cast<LogicalOp>(op & ~NOT); 2274 immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask); 2275 } 2276 2277 unsigned n, imm_s, imm_r; 2278 if (IsImmLogical(immediate, reg_size, &n, &imm_s, &imm_r)) { 2279 // Immediate can be encoded in the instruction. 2280 LogicalImmediate(rd, rn, n, imm_s, imm_r, op); 2281 } else { 2282 // This case is handled in the macro assembler. 2283 UNREACHABLE(); 2284 } 2285 } else { 2286 DCHECK(operand.IsShiftedRegister()); 2287 DCHECK(operand.reg().SizeInBits() == rd.SizeInBits()); 2288 Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed); 2289 DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op); 2290 } 2291 } 2292 2293 2294 void Assembler::LogicalImmediate(const Register& rd, 2295 const Register& rn, 2296 unsigned n, 2297 unsigned imm_s, 2298 unsigned imm_r, 2299 LogicalOp op) { 2300 unsigned reg_size = rd.SizeInBits(); 2301 Instr dest_reg = (op == ANDS) ? Rd(rd) : RdSP(rd); 2302 Emit(SF(rd) | LogicalImmediateFixed | op | BitN(n, reg_size) | 2303 ImmSetBits(imm_s, reg_size) | ImmRotate(imm_r, reg_size) | dest_reg | 2304 Rn(rn)); 2305 } 2306 2307 2308 void Assembler::ConditionalCompare(const Register& rn, 2309 const Operand& operand, 2310 StatusFlags nzcv, 2311 Condition cond, 2312 ConditionalCompareOp op) { 2313 Instr ccmpop; 2314 DCHECK(!operand.NeedsRelocation(this)); 2315 if (operand.IsImmediate()) { 2316 int64_t immediate = operand.ImmediateValue(); 2317 DCHECK(IsImmConditionalCompare(immediate)); 2318 ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate); 2319 } else { 2320 DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2321 ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg()); 2322 } 2323 Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv)); 2324 } 2325 2326 2327 void Assembler::DataProcessing1Source(const Register& rd, 2328 const Register& rn, 2329 DataProcessing1SourceOp op) { 2330 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2331 Emit(SF(rn) | op | Rn(rn) | Rd(rd)); 2332 } 2333 2334 2335 void Assembler::FPDataProcessing1Source(const FPRegister& fd, 2336 const FPRegister& fn, 2337 FPDataProcessing1SourceOp op) { 2338 Emit(FPType(fn) | op | Rn(fn) | Rd(fd)); 2339 } 2340 2341 2342 void Assembler::FPDataProcessing2Source(const FPRegister& fd, 2343 const FPRegister& fn, 2344 const FPRegister& fm, 2345 FPDataProcessing2SourceOp op) { 2346 DCHECK(fd.SizeInBits() == fn.SizeInBits()); 2347 DCHECK(fd.SizeInBits() == fm.SizeInBits()); 2348 Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd)); 2349 } 2350 2351 2352 void Assembler::FPDataProcessing3Source(const FPRegister& fd, 2353 const FPRegister& fn, 2354 const FPRegister& fm, 2355 const FPRegister& fa, 2356 FPDataProcessing3SourceOp op) { 2357 DCHECK(AreSameSizeAndType(fd, fn, fm, fa)); 2358 Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd) | Ra(fa)); 2359 } 2360 2361 2362 void Assembler::EmitShift(const Register& rd, 2363 const Register& rn, 2364 Shift shift, 2365 unsigned shift_amount) { 2366 switch (shift) { 2367 case LSL: 2368 lsl(rd, rn, shift_amount); 2369 break; 2370 case LSR: 2371 lsr(rd, rn, shift_amount); 2372 break; 2373 case ASR: 2374 asr(rd, rn, shift_amount); 2375 break; 2376 case ROR: 2377 ror(rd, rn, shift_amount); 2378 break; 2379 default: 2380 UNREACHABLE(); 2381 } 2382 } 2383 2384 2385 void Assembler::EmitExtendShift(const Register& rd, 2386 const Register& rn, 2387 Extend extend, 2388 unsigned left_shift) { 2389 DCHECK(rd.SizeInBits() >= rn.SizeInBits()); 2390 unsigned reg_size = rd.SizeInBits(); 2391 // Use the correct size of register. 2392 Register rn_ = Register::Create(rn.code(), rd.SizeInBits()); 2393 // Bits extracted are high_bit:0. 2394 unsigned high_bit = (8 << (extend & 0x3)) - 1; 2395 // Number of bits left in the result that are not introduced by the shift. 2396 unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1); 2397 2398 if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) { 2399 switch (extend) { 2400 case UXTB: 2401 case UXTH: 2402 case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break; 2403 case SXTB: 2404 case SXTH: 2405 case SXTW: sbfm(rd, rn_, non_shift_bits, high_bit); break; 2406 case UXTX: 2407 case SXTX: { 2408 DCHECK(rn.SizeInBits() == kXRegSizeInBits); 2409 // Nothing to extend. Just shift. 2410 lsl(rd, rn_, left_shift); 2411 break; 2412 } 2413 default: UNREACHABLE(); 2414 } 2415 } else { 2416 // No need to extend as the extended bits would be shifted away. 2417 lsl(rd, rn_, left_shift); 2418 } 2419 } 2420 2421 2422 void Assembler::DataProcShiftedRegister(const Register& rd, 2423 const Register& rn, 2424 const Operand& operand, 2425 FlagsUpdate S, 2426 Instr op) { 2427 DCHECK(operand.IsShiftedRegister()); 2428 DCHECK(rn.Is64Bits() || (rn.Is32Bits() && is_uint5(operand.shift_amount()))); 2429 DCHECK(!operand.NeedsRelocation(this)); 2430 Emit(SF(rd) | op | Flags(S) | 2431 ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) | 2432 Rm(operand.reg()) | Rn(rn) | Rd(rd)); 2433 } 2434 2435 2436 void Assembler::DataProcExtendedRegister(const Register& rd, 2437 const Register& rn, 2438 const Operand& operand, 2439 FlagsUpdate S, 2440 Instr op) { 2441 DCHECK(!operand.NeedsRelocation(this)); 2442 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 2443 Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | 2444 ExtendMode(operand.extend()) | ImmExtendShift(operand.shift_amount()) | 2445 dest_reg | RnSP(rn)); 2446 } 2447 2448 2449 bool Assembler::IsImmAddSub(int64_t immediate) { 2450 return is_uint12(immediate) || 2451 (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0)); 2452 } 2453 2454 void Assembler::LoadStore(const CPURegister& rt, 2455 const MemOperand& addr, 2456 LoadStoreOp op) { 2457 Instr memop = op | Rt(rt) | RnSP(addr.base()); 2458 int64_t offset = addr.offset(); 2459 2460 if (addr.IsImmediateOffset()) { 2461 LSDataSize size = CalcLSDataSize(op); 2462 if (IsImmLSScaled(offset, size)) { 2463 // Use the scaled addressing mode. 2464 Emit(LoadStoreUnsignedOffsetFixed | memop | 2465 ImmLSUnsigned(offset >> size)); 2466 } else if (IsImmLSUnscaled(offset)) { 2467 // Use the unscaled addressing mode. 2468 Emit(LoadStoreUnscaledOffsetFixed | memop | ImmLS(offset)); 2469 } else { 2470 // This case is handled in the macro assembler. 2471 UNREACHABLE(); 2472 } 2473 } else if (addr.IsRegisterOffset()) { 2474 Extend ext = addr.extend(); 2475 Shift shift = addr.shift(); 2476 unsigned shift_amount = addr.shift_amount(); 2477 2478 // LSL is encoded in the option field as UXTX. 2479 if (shift == LSL) { 2480 ext = UXTX; 2481 } 2482 2483 // Shifts are encoded in one bit, indicating a left shift by the memory 2484 // access size. 2485 DCHECK((shift_amount == 0) || 2486 (shift_amount == static_cast<unsigned>(CalcLSDataSize(op)))); 2487 Emit(LoadStoreRegisterOffsetFixed | memop | Rm(addr.regoffset()) | 2488 ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0)); 2489 } else { 2490 // Pre-index and post-index modes. 2491 DCHECK(!rt.Is(addr.base())); 2492 if (IsImmLSUnscaled(offset)) { 2493 if (addr.IsPreIndex()) { 2494 Emit(LoadStorePreIndexFixed | memop | ImmLS(offset)); 2495 } else { 2496 DCHECK(addr.IsPostIndex()); 2497 Emit(LoadStorePostIndexFixed | memop | ImmLS(offset)); 2498 } 2499 } else { 2500 // This case is handled in the macro assembler. 2501 UNREACHABLE(); 2502 } 2503 } 2504 } 2505 2506 2507 bool Assembler::IsImmLSUnscaled(int64_t offset) { 2508 return is_int9(offset); 2509 } 2510 2511 2512 bool Assembler::IsImmLSScaled(int64_t offset, LSDataSize size) { 2513 bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2514 return offset_is_size_multiple && is_uint12(offset >> size); 2515 } 2516 2517 2518 bool Assembler::IsImmLSPair(int64_t offset, LSDataSize size) { 2519 bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2520 return offset_is_size_multiple && is_int7(offset >> size); 2521 } 2522 2523 2524 // Test if a given value can be encoded in the immediate field of a logical 2525 // instruction. 2526 // If it can be encoded, the function returns true, and values pointed to by n, 2527 // imm_s and imm_r are updated with immediates encoded in the format required 2528 // by the corresponding fields in the logical instruction. 2529 // If it can not be encoded, the function returns false, and the values pointed 2530 // to by n, imm_s and imm_r are undefined. 2531 bool Assembler::IsImmLogical(uint64_t value, 2532 unsigned width, 2533 unsigned* n, 2534 unsigned* imm_s, 2535 unsigned* imm_r) { 2536 DCHECK((n != NULL) && (imm_s != NULL) && (imm_r != NULL)); 2537 DCHECK((width == kWRegSizeInBits) || (width == kXRegSizeInBits)); 2538 2539 bool negate = false; 2540 2541 // Logical immediates are encoded using parameters n, imm_s and imm_r using 2542 // the following table: 2543 // 2544 // N imms immr size S R 2545 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) 2546 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) 2547 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) 2548 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) 2549 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) 2550 // 0 11110s xxxxxr 2 UInt(s) UInt(r) 2551 // (s bits must not be all set) 2552 // 2553 // A pattern is constructed of size bits, where the least significant S+1 bits 2554 // are set. The pattern is rotated right by R, and repeated across a 32 or 2555 // 64-bit value, depending on destination register width. 2556 // 2557 // Put another way: the basic format of a logical immediate is a single 2558 // contiguous stretch of 1 bits, repeated across the whole word at intervals 2559 // given by a power of 2. To identify them quickly, we first locate the 2560 // lowest stretch of 1 bits, then the next 1 bit above that; that combination 2561 // is different for every logical immediate, so it gives us all the 2562 // information we need to identify the only logical immediate that our input 2563 // could be, and then we simply check if that's the value we actually have. 2564 // 2565 // (The rotation parameter does give the possibility of the stretch of 1 bits 2566 // going 'round the end' of the word. To deal with that, we observe that in 2567 // any situation where that happens the bitwise NOT of the value is also a 2568 // valid logical immediate. So we simply invert the input whenever its low bit 2569 // is set, and then we know that the rotated case can't arise.) 2570 2571 if (value & 1) { 2572 // If the low bit is 1, negate the value, and set a flag to remember that we 2573 // did (so that we can adjust the return values appropriately). 2574 negate = true; 2575 value = ~value; 2576 } 2577 2578 if (width == kWRegSizeInBits) { 2579 // To handle 32-bit logical immediates, the very easiest thing is to repeat 2580 // the input value twice to make a 64-bit word. The correct encoding of that 2581 // as a logical immediate will also be the correct encoding of the 32-bit 2582 // value. 2583 2584 // The most-significant 32 bits may not be zero (ie. negate is true) so 2585 // shift the value left before duplicating it. 2586 value <<= kWRegSizeInBits; 2587 value |= value >> kWRegSizeInBits; 2588 } 2589 2590 // The basic analysis idea: imagine our input word looks like this. 2591 // 2592 // 0011111000111110001111100011111000111110001111100011111000111110 2593 // c b a 2594 // |<--d-->| 2595 // 2596 // We find the lowest set bit (as an actual power-of-2 value, not its index) 2597 // and call it a. Then we add a to our original number, which wipes out the 2598 // bottommost stretch of set bits and replaces it with a 1 carried into the 2599 // next zero bit. Then we look for the new lowest set bit, which is in 2600 // position b, and subtract it, so now our number is just like the original 2601 // but with the lowest stretch of set bits completely gone. Now we find the 2602 // lowest set bit again, which is position c in the diagram above. Then we'll 2603 // measure the distance d between bit positions a and c (using CLZ), and that 2604 // tells us that the only valid logical immediate that could possibly be equal 2605 // to this number is the one in which a stretch of bits running from a to just 2606 // below b is replicated every d bits. 2607 uint64_t a = LargestPowerOf2Divisor(value); 2608 uint64_t value_plus_a = value + a; 2609 uint64_t b = LargestPowerOf2Divisor(value_plus_a); 2610 uint64_t value_plus_a_minus_b = value_plus_a - b; 2611 uint64_t c = LargestPowerOf2Divisor(value_plus_a_minus_b); 2612 2613 int d, clz_a, out_n; 2614 uint64_t mask; 2615 2616 if (c != 0) { 2617 // The general case, in which there is more than one stretch of set bits. 2618 // Compute the repeat distance d, and set up a bitmask covering the basic 2619 // unit of repetition (i.e. a word with the bottom d bits set). Also, in all 2620 // of these cases the N bit of the output will be zero. 2621 clz_a = CountLeadingZeros(a, kXRegSizeInBits); 2622 int clz_c = CountLeadingZeros(c, kXRegSizeInBits); 2623 d = clz_a - clz_c; 2624 mask = ((V8_UINT64_C(1) << d) - 1); 2625 out_n = 0; 2626 } else { 2627 // Handle degenerate cases. 2628 // 2629 // If any of those 'find lowest set bit' operations didn't find a set bit at 2630 // all, then the word will have been zero thereafter, so in particular the 2631 // last lowest_set_bit operation will have returned zero. So we can test for 2632 // all the special case conditions in one go by seeing if c is zero. 2633 if (a == 0) { 2634 // The input was zero (or all 1 bits, which will come to here too after we 2635 // inverted it at the start of the function), for which we just return 2636 // false. 2637 return false; 2638 } else { 2639 // Otherwise, if c was zero but a was not, then there's just one stretch 2640 // of set bits in our word, meaning that we have the trivial case of 2641 // d == 64 and only one 'repetition'. Set up all the same variables as in 2642 // the general case above, and set the N bit in the output. 2643 clz_a = CountLeadingZeros(a, kXRegSizeInBits); 2644 d = 64; 2645 mask = ~V8_UINT64_C(0); 2646 out_n = 1; 2647 } 2648 } 2649 2650 // If the repeat period d is not a power of two, it can't be encoded. 2651 if (!IS_POWER_OF_TWO(d)) { 2652 return false; 2653 } 2654 2655 if (((b - a) & ~mask) != 0) { 2656 // If the bit stretch (b - a) does not fit within the mask derived from the 2657 // repeat period, then fail. 2658 return false; 2659 } 2660 2661 // The only possible option is b - a repeated every d bits. Now we're going to 2662 // actually construct the valid logical immediate derived from that 2663 // specification, and see if it equals our original input. 2664 // 2665 // To repeat a value every d bits, we multiply it by a number of the form 2666 // (1 + 2^d + 2^(2d) + ...), i.e. 0x0001000100010001 or similar. These can 2667 // be derived using a table lookup on CLZ(d). 2668 static const uint64_t multipliers[] = { 2669 0x0000000000000001UL, 2670 0x0000000100000001UL, 2671 0x0001000100010001UL, 2672 0x0101010101010101UL, 2673 0x1111111111111111UL, 2674 0x5555555555555555UL, 2675 }; 2676 int multiplier_idx = CountLeadingZeros(d, kXRegSizeInBits) - 57; 2677 // Ensure that the index to the multipliers array is within bounds. 2678 DCHECK((multiplier_idx >= 0) && 2679 (static_cast<size_t>(multiplier_idx) < arraysize(multipliers))); 2680 uint64_t multiplier = multipliers[multiplier_idx]; 2681 uint64_t candidate = (b - a) * multiplier; 2682 2683 if (value != candidate) { 2684 // The candidate pattern doesn't match our input value, so fail. 2685 return false; 2686 } 2687 2688 // We have a match! This is a valid logical immediate, so now we have to 2689 // construct the bits and pieces of the instruction encoding that generates 2690 // it. 2691 2692 // Count the set bits in our basic stretch. The special case of clz(0) == -1 2693 // makes the answer come out right for stretches that reach the very top of 2694 // the word (e.g. numbers like 0xffffc00000000000). 2695 int clz_b = (b == 0) ? -1 : CountLeadingZeros(b, kXRegSizeInBits); 2696 int s = clz_a - clz_b; 2697 2698 // Decide how many bits to rotate right by, to put the low bit of that basic 2699 // stretch in position a. 2700 int r; 2701 if (negate) { 2702 // If we inverted the input right at the start of this function, here's 2703 // where we compensate: the number of set bits becomes the number of clear 2704 // bits, and the rotation count is based on position b rather than position 2705 // a (since b is the location of the 'lowest' 1 bit after inversion). 2706 s = d - s; 2707 r = (clz_b + 1) & (d - 1); 2708 } else { 2709 r = (clz_a + 1) & (d - 1); 2710 } 2711 2712 // Now we're done, except for having to encode the S output in such a way that 2713 // it gives both the number of set bits and the length of the repeated 2714 // segment. The s field is encoded like this: 2715 // 2716 // imms size S 2717 // ssssss 64 UInt(ssssss) 2718 // 0sssss 32 UInt(sssss) 2719 // 10ssss 16 UInt(ssss) 2720 // 110sss 8 UInt(sss) 2721 // 1110ss 4 UInt(ss) 2722 // 11110s 2 UInt(s) 2723 // 2724 // So we 'or' (-d << 1) with our computed s to form imms. 2725 *n = out_n; 2726 *imm_s = ((-d << 1) | (s - 1)) & 0x3f; 2727 *imm_r = r; 2728 2729 return true; 2730 } 2731 2732 2733 bool Assembler::IsImmConditionalCompare(int64_t immediate) { 2734 return is_uint5(immediate); 2735 } 2736 2737 2738 bool Assembler::IsImmFP32(float imm) { 2739 // Valid values will have the form: 2740 // aBbb.bbbc.defg.h000.0000.0000.0000.0000 2741 uint32_t bits = float_to_rawbits(imm); 2742 // bits[19..0] are cleared. 2743 if ((bits & 0x7ffff) != 0) { 2744 return false; 2745 } 2746 2747 // bits[29..25] are all set or all cleared. 2748 uint32_t b_pattern = (bits >> 16) & 0x3e00; 2749 if (b_pattern != 0 && b_pattern != 0x3e00) { 2750 return false; 2751 } 2752 2753 // bit[30] and bit[29] are opposite. 2754 if (((bits ^ (bits << 1)) & 0x40000000) == 0) { 2755 return false; 2756 } 2757 2758 return true; 2759 } 2760 2761 2762 bool Assembler::IsImmFP64(double imm) { 2763 // Valid values will have the form: 2764 // aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 2765 // 0000.0000.0000.0000.0000.0000.0000.0000 2766 uint64_t bits = double_to_rawbits(imm); 2767 // bits[47..0] are cleared. 2768 if ((bits & 0xffffffffffffL) != 0) { 2769 return false; 2770 } 2771 2772 // bits[61..54] are all set or all cleared. 2773 uint32_t b_pattern = (bits >> 48) & 0x3fc0; 2774 if (b_pattern != 0 && b_pattern != 0x3fc0) { 2775 return false; 2776 } 2777 2778 // bit[62] and bit[61] are opposite. 2779 if (((bits ^ (bits << 1)) & 0x4000000000000000L) == 0) { 2780 return false; 2781 } 2782 2783 return true; 2784 } 2785 2786 2787 void Assembler::GrowBuffer() { 2788 if (!own_buffer_) FATAL("external code buffer is too small"); 2789 2790 // Compute new buffer size. 2791 CodeDesc desc; // the new buffer 2792 if (buffer_size_ < 1 * MB) { 2793 desc.buffer_size = 2 * buffer_size_; 2794 } else { 2795 desc.buffer_size = buffer_size_ + 1 * MB; 2796 } 2797 CHECK_GT(desc.buffer_size, 0); // No overflow. 2798 2799 byte* buffer = reinterpret_cast<byte*>(buffer_); 2800 2801 // Set up new buffer. 2802 desc.buffer = NewArray<byte>(desc.buffer_size); 2803 2804 desc.instr_size = pc_offset(); 2805 desc.reloc_size = (buffer + buffer_size_) - reloc_info_writer.pos(); 2806 2807 // Copy the data. 2808 intptr_t pc_delta = desc.buffer - buffer; 2809 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - 2810 (buffer + buffer_size_); 2811 memmove(desc.buffer, buffer, desc.instr_size); 2812 memmove(reloc_info_writer.pos() + rc_delta, 2813 reloc_info_writer.pos(), desc.reloc_size); 2814 2815 // Switch buffers. 2816 DeleteArray(buffer_); 2817 buffer_ = desc.buffer; 2818 buffer_size_ = desc.buffer_size; 2819 pc_ = reinterpret_cast<byte*>(pc_) + pc_delta; 2820 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2821 reloc_info_writer.last_pc() + pc_delta); 2822 2823 // None of our relocation types are pc relative pointing outside the code 2824 // buffer nor pc absolute pointing inside the code buffer, so there is no need 2825 // to relocate any emitted relocation entries. 2826 2827 // Pending relocation entries are also relative, no need to relocate. 2828 } 2829 2830 2831 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2832 // We do not try to reuse pool constants. 2833 RelocInfo rinfo(reinterpret_cast<byte*>(pc_), rmode, data, NULL); 2834 if (((rmode >= RelocInfo::JS_RETURN) && 2835 (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) || 2836 (rmode == RelocInfo::CONST_POOL) || 2837 (rmode == RelocInfo::VENEER_POOL)) { 2838 // Adjust code for new modes. 2839 DCHECK(RelocInfo::IsDebugBreakSlot(rmode) 2840 || RelocInfo::IsJSReturn(rmode) 2841 || RelocInfo::IsComment(rmode) 2842 || RelocInfo::IsPosition(rmode) 2843 || RelocInfo::IsConstPool(rmode) 2844 || RelocInfo::IsVeneerPool(rmode)); 2845 // These modes do not need an entry in the constant pool. 2846 } else { 2847 constpool_.RecordEntry(data, rmode); 2848 // Make sure the constant pool is not emitted in place of the next 2849 // instruction for which we just recorded relocation info. 2850 BlockConstPoolFor(1); 2851 } 2852 2853 if (!RelocInfo::IsNone(rmode)) { 2854 // Don't record external references unless the heap will be serialized. 2855 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 2856 !serializer_enabled() && !emit_debug_code()) { 2857 return; 2858 } 2859 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here 2860 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2861 RelocInfo reloc_info_with_ast_id( 2862 reinterpret_cast<byte*>(pc_), rmode, RecordedAstId().ToInt(), NULL); 2863 ClearRecordedAstId(); 2864 reloc_info_writer.Write(&reloc_info_with_ast_id); 2865 } else { 2866 reloc_info_writer.Write(&rinfo); 2867 } 2868 } 2869 } 2870 2871 2872 void Assembler::BlockConstPoolFor(int instructions) { 2873 int pc_limit = pc_offset() + instructions * kInstructionSize; 2874 if (no_const_pool_before_ < pc_limit) { 2875 no_const_pool_before_ = pc_limit; 2876 // Make sure the pool won't be blocked for too long. 2877 DCHECK(pc_limit < constpool_.MaxPcOffset()); 2878 } 2879 2880 if (next_constant_pool_check_ < no_const_pool_before_) { 2881 next_constant_pool_check_ = no_const_pool_before_; 2882 } 2883 } 2884 2885 2886 void Assembler::CheckConstPool(bool force_emit, bool require_jump) { 2887 // Some short sequence of instruction mustn't be broken up by constant pool 2888 // emission, such sequences are protected by calls to BlockConstPoolFor and 2889 // BlockConstPoolScope. 2890 if (is_const_pool_blocked()) { 2891 // Something is wrong if emission is forced and blocked at the same time. 2892 DCHECK(!force_emit); 2893 return; 2894 } 2895 2896 // There is nothing to do if there are no pending constant pool entries. 2897 if (constpool_.IsEmpty()) { 2898 // Calculate the offset of the next check. 2899 SetNextConstPoolCheckIn(kCheckConstPoolInterval); 2900 return; 2901 } 2902 2903 // We emit a constant pool when: 2904 // * requested to do so by parameter force_emit (e.g. after each function). 2905 // * the distance to the first instruction accessing the constant pool is 2906 // kApproxMaxDistToConstPool or more. 2907 // * the number of entries in the pool is kApproxMaxPoolEntryCount or more. 2908 int dist = constpool_.DistanceToFirstUse(); 2909 int count = constpool_.EntryCount(); 2910 if (!force_emit && 2911 (dist < kApproxMaxDistToConstPool) && 2912 (count < kApproxMaxPoolEntryCount)) { 2913 return; 2914 } 2915 2916 2917 // Emit veneers for branches that would go out of range during emission of the 2918 // constant pool. 2919 int worst_case_size = constpool_.WorstCaseSize(); 2920 CheckVeneerPool(false, require_jump, 2921 kVeneerDistanceMargin + worst_case_size); 2922 2923 // Check that the code buffer is large enough before emitting the constant 2924 // pool (this includes the gap to the relocation information). 2925 int needed_space = worst_case_size + kGap + 1 * kInstructionSize; 2926 while (buffer_space() <= needed_space) { 2927 GrowBuffer(); 2928 } 2929 2930 Label size_check; 2931 bind(&size_check); 2932 constpool_.Emit(require_jump); 2933 DCHECK(SizeOfCodeGeneratedSince(&size_check) <= 2934 static_cast<unsigned>(worst_case_size)); 2935 2936 // Since a constant pool was just emitted, move the check offset forward by 2937 // the standard interval. 2938 SetNextConstPoolCheckIn(kCheckConstPoolInterval); 2939 } 2940 2941 2942 bool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) { 2943 // Account for the branch around the veneers and the guard. 2944 int protection_offset = 2 * kInstructionSize; 2945 return pc_offset() > max_reachable_pc - margin - protection_offset - 2946 static_cast<int>(unresolved_branches_.size() * kMaxVeneerCodeSize); 2947 } 2948 2949 2950 void Assembler::RecordVeneerPool(int location_offset, int size) { 2951 RelocInfo rinfo(buffer_ + location_offset, 2952 RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), 2953 NULL); 2954 reloc_info_writer.Write(&rinfo); 2955 } 2956 2957 2958 void Assembler::EmitVeneers(bool force_emit, bool need_protection, int margin) { 2959 BlockPoolsScope scope(this); 2960 RecordComment("[ Veneers"); 2961 2962 // The exact size of the veneer pool must be recorded (see the comment at the 2963 // declaration site of RecordConstPool()), but computing the number of 2964 // veneers that will be generated is not obvious. So instead we remember the 2965 // current position and will record the size after the pool has been 2966 // generated. 2967 Label size_check; 2968 bind(&size_check); 2969 int veneer_pool_relocinfo_loc = pc_offset(); 2970 2971 Label end; 2972 if (need_protection) { 2973 b(&end); 2974 } 2975 2976 EmitVeneersGuard(); 2977 2978 Label veneer_size_check; 2979 2980 std::multimap<int, FarBranchInfo>::iterator it, it_to_delete; 2981 2982 it = unresolved_branches_.begin(); 2983 while (it != unresolved_branches_.end()) { 2984 if (force_emit || ShouldEmitVeneer(it->first, margin)) { 2985 Instruction* branch = InstructionAt(it->second.pc_offset_); 2986 Label* label = it->second.label_; 2987 2988 #ifdef DEBUG 2989 bind(&veneer_size_check); 2990 #endif 2991 // Patch the branch to point to the current position, and emit a branch 2992 // to the label. 2993 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); 2994 RemoveBranchFromLabelLinkChain(branch, label, veneer); 2995 branch->SetImmPCOffsetTarget(veneer); 2996 b(label); 2997 #ifdef DEBUG 2998 DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <= 2999 static_cast<uint64_t>(kMaxVeneerCodeSize)); 3000 veneer_size_check.Unuse(); 3001 #endif 3002 3003 it_to_delete = it++; 3004 unresolved_branches_.erase(it_to_delete); 3005 } else { 3006 ++it; 3007 } 3008 } 3009 3010 // Record the veneer pool size. 3011 int pool_size = SizeOfCodeGeneratedSince(&size_check); 3012 RecordVeneerPool(veneer_pool_relocinfo_loc, pool_size); 3013 3014 if (unresolved_branches_.empty()) { 3015 next_veneer_pool_check_ = kMaxInt; 3016 } else { 3017 next_veneer_pool_check_ = 3018 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3019 } 3020 3021 bind(&end); 3022 3023 RecordComment("]"); 3024 } 3025 3026 3027 void Assembler::CheckVeneerPool(bool force_emit, bool require_jump, 3028 int margin) { 3029 // There is nothing to do if there are no pending veneer pool entries. 3030 if (unresolved_branches_.empty()) { 3031 DCHECK(next_veneer_pool_check_ == kMaxInt); 3032 return; 3033 } 3034 3035 DCHECK(pc_offset() < unresolved_branches_first_limit()); 3036 3037 // Some short sequence of instruction mustn't be broken up by veneer pool 3038 // emission, such sequences are protected by calls to BlockVeneerPoolFor and 3039 // BlockVeneerPoolScope. 3040 if (is_veneer_pool_blocked()) { 3041 DCHECK(!force_emit); 3042 return; 3043 } 3044 3045 if (!require_jump) { 3046 // Prefer emitting veneers protected by an existing instruction. 3047 margin *= kVeneerNoProtectionFactor; 3048 } 3049 if (force_emit || ShouldEmitVeneers(margin)) { 3050 EmitVeneers(force_emit, require_jump, margin); 3051 } else { 3052 next_veneer_pool_check_ = 3053 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3054 } 3055 } 3056 3057 3058 void Assembler::RecordComment(const char* msg) { 3059 if (FLAG_code_comments) { 3060 CheckBuffer(); 3061 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); 3062 } 3063 } 3064 3065 3066 int Assembler::buffer_space() const { 3067 return reloc_info_writer.pos() - reinterpret_cast<byte*>(pc_); 3068 } 3069 3070 3071 void Assembler::RecordJSReturn() { 3072 positions_recorder()->WriteRecordedPositions(); 3073 CheckBuffer(); 3074 RecordRelocInfo(RelocInfo::JS_RETURN); 3075 } 3076 3077 3078 void Assembler::RecordDebugBreakSlot() { 3079 positions_recorder()->WriteRecordedPositions(); 3080 CheckBuffer(); 3081 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 3082 } 3083 3084 3085 void Assembler::RecordConstPool(int size) { 3086 // We only need this for debugger support, to correctly compute offsets in the 3087 // code. 3088 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); 3089 } 3090 3091 3092 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) { 3093 // No out-of-line constant pool support. 3094 DCHECK(!FLAG_enable_ool_constant_pool); 3095 return isolate->factory()->empty_constant_pool_array(); 3096 } 3097 3098 3099 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 3100 // No out-of-line constant pool support. 3101 DCHECK(!FLAG_enable_ool_constant_pool); 3102 return; 3103 } 3104 3105 3106 void PatchingAssembler::PatchAdrFar(int64_t target_offset) { 3107 // The code at the current instruction should be: 3108 // adr rd, 0 3109 // nop (adr_far) 3110 // nop (adr_far) 3111 // movz scratch, 0 3112 3113 // Verify the expected code. 3114 Instruction* expected_adr = InstructionAt(0); 3115 CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0)); 3116 int rd_code = expected_adr->Rd(); 3117 for (int i = 0; i < kAdrFarPatchableNNops; ++i) { 3118 CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP)); 3119 } 3120 Instruction* expected_movz = 3121 InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize); 3122 CHECK(expected_movz->IsMovz() && 3123 (expected_movz->ImmMoveWide() == 0) && 3124 (expected_movz->ShiftMoveWide() == 0)); 3125 int scratch_code = expected_movz->Rd(); 3126 3127 // Patch to load the correct address. 3128 Register rd = Register::XRegFromCode(rd_code); 3129 Register scratch = Register::XRegFromCode(scratch_code); 3130 // Addresses are only 48 bits. 3131 adr(rd, target_offset & 0xFFFF); 3132 movz(scratch, (target_offset >> 16) & 0xFFFF, 16); 3133 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); 3134 DCHECK((target_offset >> 48) == 0); 3135 add(rd, rd, scratch); 3136 } 3137 3138 3139 } } // namespace v8::internal 3140 3141 #endif // V8_TARGET_ARCH_ARM64 3142