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
39namespace v8 {
40namespace internal {
41
42
43// -----------------------------------------------------------------------------
44// CpuFeatures implementation.
45
46void 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
61void CpuFeatures::PrintTarget() { }
62void CpuFeatures::PrintFeatures() { }
63
64
65// -----------------------------------------------------------------------------
66// CPURegList utilities.
67
68CPURegister 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
80CPURegister 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
93void 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
106CPURegList CPURegList::GetCalleeSaved(unsigned size) {
107  return CPURegList(CPURegister::kRegister, size, 19, 29);
108}
109
110
111CPURegList CPURegList::GetCalleeSavedFP(unsigned size) {
112  return CPURegList(CPURegister::kFPRegister, size, 8, 15);
113}
114
115
116CPURegList 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
124CPURegList 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.
137CPURegList 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
169const int RelocInfo::kApplyMask = 0;
170
171
172bool 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
180bool RelocInfo::IsInConstantPool() {
181  Instruction* instr = reinterpret_cast<Instruction*>(pc_);
182  return instr->IsLdrLiteralX();
183}
184
185
186void 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.
201void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
202  UNIMPLEMENTED();
203}
204
205
206Register 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
219bool 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
256bool 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
273void 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
290bool 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.
302void 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
334int ConstPool::DistanceToFirstUse() {
335  DCHECK(first_use_ >= 0);
336  return assm_->pc_offset() - first_use_;
337}
338
339
340int 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
351int 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
364int 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
382void 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
437void ConstPool::Clear() {
438  shared_entries_.clear();
439  shared_entries_count = 0;
440  unique_entries_.clear();
441  first_use_ = -1;
442}
443
444
445bool 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
454void 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
467MemOperand::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
495void 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
505void 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
549Assembler::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
561Assembler::~Assembler() {
562  DCHECK(constpool_.IsEmpty());
563  DCHECK(const_pool_blocked_nesting_ == 0);
564  DCHECK(veneer_pool_blocked_nesting_ == 0);
565}
566
567
568void 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
587void 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
604void 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
612void 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
630void 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
710void 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
764int 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
807void 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
841void 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
861void 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
870void 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
884bool Assembler::is_const_pool_blocked() const {
885  return (const_pool_blocked_nesting_ > 0) ||
886         (pc_offset() < no_const_pool_before_);
887}
888
889
890bool 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
905int 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
932void 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
939void Assembler::StartBlockVeneerPool() {
940  ++veneer_pool_blocked_nesting_;
941}
942
943
944void 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
953void Assembler::br(const Register& xn) {
954  positions_recorder()->WriteRecordedPositions();
955  DCHECK(xn.Is64Bits());
956  Emit(BR | Rn(xn));
957}
958
959
960void 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
970void Assembler::ret(const Register& xn) {
971  positions_recorder()->WriteRecordedPositions();
972  DCHECK(xn.Is64Bits());
973  Emit(RET | Rn(xn));
974}
975
976
977void Assembler::b(int imm26) {
978  Emit(B | ImmUncondBranch(imm26));
979}
980
981
982void Assembler::b(Label* label) {
983  positions_recorder()->WriteRecordedPositions();
984  b(LinkAndGetInstructionOffsetTo(label));
985}
986
987
988void Assembler::b(int imm19, Condition cond) {
989  Emit(B_cond | ImmCondBranch(imm19) | cond);
990}
991
992
993void Assembler::b(Label* label, Condition cond) {
994  positions_recorder()->WriteRecordedPositions();
995  b(LinkAndGetInstructionOffsetTo(label), cond);
996}
997
998
999void Assembler::bl(int imm26) {
1000  positions_recorder()->WriteRecordedPositions();
1001  Emit(BL | ImmUncondBranch(imm26));
1002}
1003
1004
1005void Assembler::bl(Label* label) {
1006  positions_recorder()->WriteRecordedPositions();
1007  bl(LinkAndGetInstructionOffsetTo(label));
1008}
1009
1010
1011void Assembler::cbz(const Register& rt,
1012                    int imm19) {
1013  positions_recorder()->WriteRecordedPositions();
1014  Emit(SF(rt) | CBZ | ImmCmpBranch(imm19) | Rt(rt));
1015}
1016
1017
1018void Assembler::cbz(const Register& rt,
1019                    Label* label) {
1020  positions_recorder()->WriteRecordedPositions();
1021  cbz(rt, LinkAndGetInstructionOffsetTo(label));
1022}
1023
1024
1025void Assembler::cbnz(const Register& rt,
1026                     int imm19) {
1027  positions_recorder()->WriteRecordedPositions();
1028  Emit(SF(rt) | CBNZ | ImmCmpBranch(imm19) | Rt(rt));
1029}
1030
1031
1032void Assembler::cbnz(const Register& rt,
1033                     Label* label) {
1034  positions_recorder()->WriteRecordedPositions();
1035  cbnz(rt, LinkAndGetInstructionOffsetTo(label));
1036}
1037
1038
1039void 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
1048void 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
1056void 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
1065void 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
1073void Assembler::adr(const Register& rd, int imm21) {
1074  DCHECK(rd.Is64Bits());
1075  Emit(ADR | ImmPCRelAddress(imm21) | Rd(rd));
1076}
1077
1078
1079void Assembler::adr(const Register& rd, Label* label) {
1080  adr(rd, LinkAndGetByteOffsetTo(label));
1081}
1082
1083
1084void Assembler::add(const Register& rd,
1085                    const Register& rn,
1086                    const Operand& operand) {
1087  AddSub(rd, rn, operand, LeaveFlags, ADD);
1088}
1089
1090
1091void Assembler::adds(const Register& rd,
1092                     const Register& rn,
1093                     const Operand& operand) {
1094  AddSub(rd, rn, operand, SetFlags, ADD);
1095}
1096
1097
1098void Assembler::cmn(const Register& rn,
1099                    const Operand& operand) {
1100  Register zr = AppropriateZeroRegFor(rn);
1101  adds(zr, rn, operand);
1102}
1103
1104
1105void Assembler::sub(const Register& rd,
1106                    const Register& rn,
1107                    const Operand& operand) {
1108  AddSub(rd, rn, operand, LeaveFlags, SUB);
1109}
1110
1111
1112void Assembler::subs(const Register& rd,
1113                     const Register& rn,
1114                     const Operand& operand) {
1115  AddSub(rd, rn, operand, SetFlags, SUB);
1116}
1117
1118
1119void Assembler::cmp(const Register& rn, const Operand& operand) {
1120  Register zr = AppropriateZeroRegFor(rn);
1121  subs(zr, rn, operand);
1122}
1123
1124
1125void Assembler::neg(const Register& rd, const Operand& operand) {
1126  Register zr = AppropriateZeroRegFor(rd);
1127  sub(rd, zr, operand);
1128}
1129
1130
1131void Assembler::negs(const Register& rd, const Operand& operand) {
1132  Register zr = AppropriateZeroRegFor(rd);
1133  subs(rd, zr, operand);
1134}
1135
1136
1137void Assembler::adc(const Register& rd,
1138                    const Register& rn,
1139                    const Operand& operand) {
1140  AddSubWithCarry(rd, rn, operand, LeaveFlags, ADC);
1141}
1142
1143
1144void Assembler::adcs(const Register& rd,
1145                     const Register& rn,
1146                     const Operand& operand) {
1147  AddSubWithCarry(rd, rn, operand, SetFlags, ADC);
1148}
1149
1150
1151void Assembler::sbc(const Register& rd,
1152                    const Register& rn,
1153                    const Operand& operand) {
1154  AddSubWithCarry(rd, rn, operand, LeaveFlags, SBC);
1155}
1156
1157
1158void Assembler::sbcs(const Register& rd,
1159                     const Register& rn,
1160                     const Operand& operand) {
1161  AddSubWithCarry(rd, rn, operand, SetFlags, SBC);
1162}
1163
1164
1165void Assembler::ngc(const Register& rd, const Operand& operand) {
1166  Register zr = AppropriateZeroRegFor(rd);
1167  sbc(rd, zr, operand);
1168}
1169
1170
1171void Assembler::ngcs(const Register& rd, const Operand& operand) {
1172  Register zr = AppropriateZeroRegFor(rd);
1173  sbcs(rd, zr, operand);
1174}
1175
1176
1177// Logical instructions.
1178void Assembler::and_(const Register& rd,
1179                     const Register& rn,
1180                     const Operand& operand) {
1181  Logical(rd, rn, operand, AND);
1182}
1183
1184
1185void Assembler::ands(const Register& rd,
1186                     const Register& rn,
1187                     const Operand& operand) {
1188  Logical(rd, rn, operand, ANDS);
1189}
1190
1191
1192void Assembler::tst(const Register& rn,
1193                    const Operand& operand) {
1194  ands(AppropriateZeroRegFor(rn), rn, operand);
1195}
1196
1197
1198void Assembler::bic(const Register& rd,
1199                    const Register& rn,
1200                    const Operand& operand) {
1201  Logical(rd, rn, operand, BIC);
1202}
1203
1204
1205void Assembler::bics(const Register& rd,
1206                     const Register& rn,
1207                     const Operand& operand) {
1208  Logical(rd, rn, operand, BICS);
1209}
1210
1211
1212void Assembler::orr(const Register& rd,
1213                    const Register& rn,
1214                    const Operand& operand) {
1215  Logical(rd, rn, operand, ORR);
1216}
1217
1218
1219void Assembler::orn(const Register& rd,
1220                    const Register& rn,
1221                    const Operand& operand) {
1222  Logical(rd, rn, operand, ORN);
1223}
1224
1225
1226void Assembler::eor(const Register& rd,
1227                    const Register& rn,
1228                    const Operand& operand) {
1229  Logical(rd, rn, operand, EOR);
1230}
1231
1232
1233void Assembler::eon(const Register& rd,
1234                    const Register& rn,
1235                    const Operand& operand) {
1236  Logical(rd, rn, operand, EON);
1237}
1238
1239
1240void 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
1249void 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
1258void 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
1267void 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.
1277void 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
1290void 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
1303void 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
1316void 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
1328void 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
1336void 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
1344void 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
1352void 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
1360void 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
1367void 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
1374void 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
1380void 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
1386void 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
1392void 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
1403void 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
1411void 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
1419void 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
1428void 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
1437void 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
1446void 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
1455void 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
1464void 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
1474void 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
1484void 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
1494void 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
1504void 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
1513void 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
1521void 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
1530void 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
1539void Assembler::rbit(const Register& rd,
1540                     const Register& rn) {
1541  DataProcessing1Source(rd, rn, RBIT);
1542}
1543
1544
1545void Assembler::rev16(const Register& rd,
1546                      const Register& rn) {
1547  DataProcessing1Source(rd, rn, REV16);
1548}
1549
1550
1551void Assembler::rev32(const Register& rd,
1552                      const Register& rn) {
1553  DCHECK(rd.Is64Bits());
1554  DataProcessing1Source(rd, rn, REV);
1555}
1556
1557
1558void Assembler::rev(const Register& rd,
1559                    const Register& rn) {
1560  DataProcessing1Source(rd, rn, rd.Is64Bits() ? REV_x : REV_w);
1561}
1562
1563
1564void Assembler::clz(const Register& rd,
1565                    const Register& rn) {
1566  DataProcessing1Source(rd, rn, CLZ);
1567}
1568
1569
1570void Assembler::cls(const Register& rd,
1571                    const Register& rn) {
1572  DataProcessing1Source(rd, rn, CLS);
1573}
1574
1575
1576void Assembler::ldp(const CPURegister& rt,
1577                    const CPURegister& rt2,
1578                    const MemOperand& src) {
1579  LoadStorePair(rt, rt2, src, LoadPairOpFor(rt, rt2));
1580}
1581
1582
1583void Assembler::stp(const CPURegister& rt,
1584                    const CPURegister& rt2,
1585                    const MemOperand& dst) {
1586  LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2));
1587}
1588
1589
1590void 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
1598void 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
1628void 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
1636void 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
1644void 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.
1660void Assembler::ldrb(const Register& rt, const MemOperand& src) {
1661  LoadStore(rt, src, LDRB_w);
1662}
1663
1664
1665void Assembler::strb(const Register& rt, const MemOperand& dst) {
1666  LoadStore(rt, dst, STRB_w);
1667}
1668
1669
1670void Assembler::ldrsb(const Register& rt, const MemOperand& src) {
1671  LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w);
1672}
1673
1674
1675void Assembler::ldrh(const Register& rt, const MemOperand& src) {
1676  LoadStore(rt, src, LDRH_w);
1677}
1678
1679
1680void Assembler::strh(const Register& rt, const MemOperand& dst) {
1681  LoadStore(rt, dst, STRH_w);
1682}
1683
1684
1685void Assembler::ldrsh(const Register& rt, const MemOperand& src) {
1686  LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w);
1687}
1688
1689
1690void Assembler::ldr(const CPURegister& rt, const MemOperand& src) {
1691  LoadStore(rt, src, LoadOpFor(rt));
1692}
1693
1694
1695void Assembler::str(const CPURegister& rt, const MemOperand& src) {
1696  LoadStore(rt, src, StoreOpFor(rt));
1697}
1698
1699
1700void Assembler::ldrsw(const Register& rt, const MemOperand& src) {
1701  DCHECK(rt.Is64Bits());
1702  LoadStore(rt, src, LDRSW_x);
1703}
1704
1705
1706void 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
1714void 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
1726void 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
1738void Assembler::mvn(const Register& rd, const Operand& operand) {
1739  orn(rd, AppropriateZeroRegFor(rd), operand);
1740}
1741
1742
1743void Assembler::mrs(const Register& rt, SystemRegister sysreg) {
1744  DCHECK(rt.Is64Bits());
1745  Emit(MRS | ImmSystemRegister(sysreg) | Rt(rt));
1746}
1747
1748
1749void Assembler::msr(SystemRegister sysreg, const Register& rt) {
1750  DCHECK(rt.Is64Bits());
1751  Emit(MSR | Rt(rt) | ImmSystemRegister(sysreg));
1752}
1753
1754
1755void Assembler::hint(SystemHint code) {
1756  Emit(HINT | ImmHint(code) | Rt(xzr));
1757}
1758
1759
1760void Assembler::dmb(BarrierDomain domain, BarrierType type) {
1761  Emit(DMB | ImmBarrierDomain(domain) | ImmBarrierType(type));
1762}
1763
1764
1765void Assembler::dsb(BarrierDomain domain, BarrierType type) {
1766  Emit(DSB | ImmBarrierDomain(domain) | ImmBarrierType(type));
1767}
1768
1769
1770void Assembler::isb() {
1771  Emit(ISB | ImmBarrierDomain(FullSystem) | ImmBarrierType(BarrierAll));
1772}
1773
1774
1775void 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
1782void 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
1789void 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
1796void 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
1803void Assembler::fmov(FPRegister fd, FPRegister fn) {
1804  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1805  Emit(FPType(fd) | FMOV | Rd(fd) | Rn(fn));
1806}
1807
1808
1809void Assembler::fadd(const FPRegister& fd,
1810                     const FPRegister& fn,
1811                     const FPRegister& fm) {
1812  FPDataProcessing2Source(fd, fn, fm, FADD);
1813}
1814
1815
1816void Assembler::fsub(const FPRegister& fd,
1817                     const FPRegister& fn,
1818                     const FPRegister& fm) {
1819  FPDataProcessing2Source(fd, fn, fm, FSUB);
1820}
1821
1822
1823void Assembler::fmul(const FPRegister& fd,
1824                     const FPRegister& fn,
1825                     const FPRegister& fm) {
1826  FPDataProcessing2Source(fd, fn, fm, FMUL);
1827}
1828
1829
1830void 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
1838void 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
1846void 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
1854void 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
1862void Assembler::fdiv(const FPRegister& fd,
1863                     const FPRegister& fn,
1864                     const FPRegister& fm) {
1865  FPDataProcessing2Source(fd, fn, fm, FDIV);
1866}
1867
1868
1869void Assembler::fmax(const FPRegister& fd,
1870                     const FPRegister& fn,
1871                     const FPRegister& fm) {
1872  FPDataProcessing2Source(fd, fn, fm, FMAX);
1873}
1874
1875
1876void Assembler::fmaxnm(const FPRegister& fd,
1877                       const FPRegister& fn,
1878                       const FPRegister& fm) {
1879  FPDataProcessing2Source(fd, fn, fm, FMAXNM);
1880}
1881
1882
1883void Assembler::fmin(const FPRegister& fd,
1884                     const FPRegister& fn,
1885                     const FPRegister& fm) {
1886  FPDataProcessing2Source(fd, fn, fm, FMIN);
1887}
1888
1889
1890void Assembler::fminnm(const FPRegister& fd,
1891                       const FPRegister& fn,
1892                       const FPRegister& fm) {
1893  FPDataProcessing2Source(fd, fn, fm, FMINNM);
1894}
1895
1896
1897void Assembler::fabs(const FPRegister& fd,
1898                     const FPRegister& fn) {
1899  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1900  FPDataProcessing1Source(fd, fn, FABS);
1901}
1902
1903
1904void Assembler::fneg(const FPRegister& fd,
1905                     const FPRegister& fn) {
1906  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1907  FPDataProcessing1Source(fd, fn, FNEG);
1908}
1909
1910
1911void Assembler::fsqrt(const FPRegister& fd,
1912                      const FPRegister& fn) {
1913  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1914  FPDataProcessing1Source(fd, fn, FSQRT);
1915}
1916
1917
1918void Assembler::frinta(const FPRegister& fd,
1919                       const FPRegister& fn) {
1920  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1921  FPDataProcessing1Source(fd, fn, FRINTA);
1922}
1923
1924
1925void Assembler::frintm(const FPRegister& fd,
1926                       const FPRegister& fn) {
1927  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1928  FPDataProcessing1Source(fd, fn, FRINTM);
1929}
1930
1931
1932void Assembler::frintn(const FPRegister& fd,
1933                       const FPRegister& fn) {
1934  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1935  FPDataProcessing1Source(fd, fn, FRINTN);
1936}
1937
1938
1939void Assembler::frintz(const FPRegister& fd,
1940                       const FPRegister& fn) {
1941  DCHECK(fd.SizeInBits() == fn.SizeInBits());
1942  FPDataProcessing1Source(fd, fn, FRINTZ);
1943}
1944
1945
1946void 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
1953void 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
1964void 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
1973void 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
1983void 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
1990void 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
2004void Assembler::fcvtau(const Register& rd, const FPRegister& fn) {
2005  FPConvertToInt(rd, fn, FCVTAU);
2006}
2007
2008
2009void Assembler::fcvtas(const Register& rd, const FPRegister& fn) {
2010  FPConvertToInt(rd, fn, FCVTAS);
2011}
2012
2013
2014void Assembler::fcvtmu(const Register& rd, const FPRegister& fn) {
2015  FPConvertToInt(rd, fn, FCVTMU);
2016}
2017
2018
2019void Assembler::fcvtms(const Register& rd, const FPRegister& fn) {
2020  FPConvertToInt(rd, fn, FCVTMS);
2021}
2022
2023
2024void Assembler::fcvtnu(const Register& rd, const FPRegister& fn) {
2025  FPConvertToInt(rd, fn, FCVTNU);
2026}
2027
2028
2029void Assembler::fcvtns(const Register& rd, const FPRegister& fn) {
2030  FPConvertToInt(rd, fn, FCVTNS);
2031}
2032
2033
2034void Assembler::fcvtzu(const Register& rd, const FPRegister& fn) {
2035  FPConvertToInt(rd, fn, FCVTZU);
2036}
2037
2038
2039void Assembler::fcvtzs(const Register& rd, const FPRegister& fn) {
2040  FPConvertToInt(rd, fn, FCVTZS);
2041}
2042
2043
2044void 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
2056void 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.
2072Instr 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
2087Instr 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.
2104void 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
2149void 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
2187void 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
2200void Assembler::hlt(int code) {
2201  DCHECK(is_uint16(code));
2202  Emit(HLT | ImmException(code));
2203}
2204
2205
2206void Assembler::brk(int code) {
2207  DCHECK(is_uint16(code));
2208  Emit(BRK | ImmException(code));
2209}
2210
2211
2212void 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
2223void 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
2257void 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
2294void 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
2308void 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
2327void 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
2335void Assembler::FPDataProcessing1Source(const FPRegister& fd,
2336                                        const FPRegister& fn,
2337                                        FPDataProcessing1SourceOp op) {
2338  Emit(FPType(fn) | op | Rn(fn) | Rd(fd));
2339}
2340
2341
2342void 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
2352void 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
2362void 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
2385void 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
2422void 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
2436void 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
2449bool Assembler::IsImmAddSub(int64_t immediate) {
2450  return is_uint12(immediate) ||
2451         (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0));
2452}
2453
2454void 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
2507bool Assembler::IsImmLSUnscaled(int64_t offset) {
2508  return is_int9(offset);
2509}
2510
2511
2512bool 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
2518bool 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.
2531bool 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
2733bool Assembler::IsImmConditionalCompare(int64_t immediate) {
2734  return is_uint5(immediate);
2735}
2736
2737
2738bool 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
2762bool 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
2787void 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
2831void 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
2872void 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
2886void 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
2942bool 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
2950void 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
2958void 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
3027void 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
3058void 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
3066int Assembler::buffer_space() const {
3067  return reloc_info_writer.pos() - reinterpret_cast<byte*>(pc_);
3068}
3069
3070
3071void Assembler::RecordJSReturn() {
3072  positions_recorder()->WriteRecordedPositions();
3073  CheckBuffer();
3074  RecordRelocInfo(RelocInfo::JS_RETURN);
3075}
3076
3077
3078void Assembler::RecordDebugBreakSlot() {
3079  positions_recorder()->WriteRecordedPositions();
3080  CheckBuffer();
3081  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3082}
3083
3084
3085void 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
3092Handle<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
3099void 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
3106void 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