5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ 13 #include "src/arm64/constants-arm64.h" 14 #include "src/arm64/instructions-arm64.h" 15 #include "src/assembler.h" 16 #include "src/base/optional.h" 17 #include "src/constant-pool.h" 18 #include "src/globals.h" 19 #include "src/utils.h" 23 #if defined(V8_OS_WIN) && defined(mvn) 33 #define GENERAL_REGISTER_CODE_LIST(R) \ 34 R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 35 R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 36 R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 37 R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 39 #define GENERAL_REGISTERS(R) \ 40 R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ 41 R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ 42 R(x16) R(x17) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) \ 43 R(x24) R(x25) R(x26) R(x27) R(x28) R(x29) R(x30) R(x31) 45 #if defined(V8_OS_WIN) 47 #define ALLOCATABLE_GENERAL_REGISTERS(R) \ 48 R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ 49 R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ 50 R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x25) \ 53 #define ALLOCATABLE_GENERAL_REGISTERS(R) \ 54 R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \ 55 R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \ 56 R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x25) \ 60 #define FLOAT_REGISTERS(V) \ 61 V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \ 62 V(s8) V(s9) V(s10) V(s11) V(s12) V(s13) V(s14) V(s15) \ 63 V(s16) V(s17) V(s18) V(s19) V(s20) V(s21) V(s22) V(s23) \ 64 V(s24) V(s25) V(s26) V(s27) V(s28) V(s29) V(s30) V(s31) 66 #define DOUBLE_REGISTERS(R) \ 67 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ 68 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \ 69 R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \ 70 R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31) 72 #define SIMD128_REGISTERS(V) \ 73 V(q0) V(q1) V(q2) V(q3) V(q4) V(q5) V(q6) V(q7) \ 74 V(q8) V(q9) V(q10) V(q11) V(q12) V(q13) V(q14) V(q15) \ 75 V(q16) V(q17) V(q18) V(q19) V(q20) V(q21) V(q22) V(q23) \ 76 V(q24) V(q25) V(q26) V(q27) V(q28) V(q29) V(q30) V(q31) 80 #define ALLOCATABLE_DOUBLE_REGISTERS(R) \ 81 R(d0) R(d1) R(d2) R(d3) R(d4) R(d5) R(d6) R(d7) \ 82 R(d8) R(d9) R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \ 83 R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \ 84 R(d25) R(d26) R(d27) R(d28) 87 constexpr
int kRegListSizeInBits =
sizeof(RegList) * kBitsPerByte;
89 const int kNumRegs = kNumberOfRegisters;
91 const int kNumJSCallerSaved = 18;
92 const RegList kJSCallerSaved = 0x3ffff;
97 const int kNumSafepointRegisters = 32;
102 #define kSafepointSavedRegisters CPURegList::GetSafepointSavedRegisters().list() 103 #define kNumSafepointSavedRegisters \ 104 CPURegList::GetSafepointSavedRegisters().Count() 112 #define REGISTER_CODE(R) kRegCode_##R, 113 GENERAL_REGISTERS(REGISTER_CODE)
130 template <
int code,
int size, RegisterType type>
132 static_assert(IsValid(code, size,
type),
"Cannot create invalid registers");
137 DCHECK(IsValid(code, size,
type));
141 RegisterType
type()
const {
return reg_type_; }
142 int SizeInBits()
const {
146 int SizeInBytes()
const {
148 DCHECK_EQ(SizeInBits() % 8, 0);
149 return reg_size_ / 8;
151 bool Is8Bits()
const {
153 return reg_size_ == 8;
155 bool Is16Bits()
const {
157 return reg_size_ == 16;
159 bool Is32Bits()
const {
161 return reg_size_ == 32;
163 bool Is64Bits()
const {
165 return reg_size_ == 64;
167 bool Is128Bits()
const {
169 return reg_size_ == 128;
171 bool IsValid()
const {
return reg_type_ != kNoRegister; }
172 bool IsNone()
const {
return reg_type_ == kNoRegister; }
174 return Aliases(other) && (reg_size_ == other.reg_size_);
177 return (reg_code_ == other.reg_code_) && (reg_type_ == other.reg_type_);
183 bool IsRegister()
const {
return reg_type_ == kRegister; }
184 bool IsVRegister()
const {
return reg_type_ == kVRegister; }
186 bool IsFPRegister()
const {
return IsS() || IsD(); }
188 bool IsW()
const {
return IsRegister() && Is32Bits(); }
189 bool IsX()
const {
return IsRegister() && Is64Bits(); }
197 bool IsV()
const {
return IsVRegister(); }
198 bool IsB()
const {
return IsV() && Is8Bits(); }
199 bool IsH()
const {
return IsV() && Is16Bits(); }
200 bool IsS()
const {
return IsV() && Is32Bits(); }
201 bool IsD()
const {
return IsV() && Is64Bits(); }
202 bool IsQ()
const {
return IsV() && Is128Bits(); }
216 bool IsSameSizeAndType(
const CPURegister& other)
const;
218 bool is(
const CPURegister& other)
const {
return Is(other); }
219 bool is_valid()
const {
return IsValid(); }
223 RegisterType reg_type_;
225 #if defined(V8_OS_WIN) && !defined(__clang__) 235 static constexpr
bool IsValidRegister(
int code,
int size) {
236 return (size == kWRegSizeInBits || size == kXRegSizeInBits) &&
237 (code < kNumberOfRegisters || code == kSPRegInternalCode);
240 static constexpr
bool IsValidVRegister(
int code,
int size) {
241 return (size == kBRegSizeInBits || size == kHRegSizeInBits ||
242 size == kSRegSizeInBits || size == kDRegSizeInBits ||
243 size == kQRegSizeInBits) &&
244 code < kNumberOfVRegisters;
247 static constexpr
bool IsValid(
int code,
int size, RegisterType
type) {
248 return (
type == kRegister && IsValidRegister(code, size)) ||
249 (
type == kVRegister && IsValidVRegister(code, size));
252 static constexpr
bool IsNone(
int code,
int size, RegisterType
type) {
253 return type == kNoRegister && code == 0 && size == 0;
261 static constexpr
Register no_reg() {
return Register(CPURegister::no_reg()); }
263 template <
int code,
int size>
264 static constexpr Register Create() {
265 return Register(CPURegister::Create<code, size, CPURegister::kRegister>());
268 static Register Create(
int code,
int size) {
269 return Register(CPURegister::Create(code, size, CPURegister::kRegister));
272 static Register XRegFromCode(
unsigned code);
273 static Register WRegFromCode(
unsigned code);
275 static Register from_code(
int code) {
277 return Register::Create(code, kXRegSizeInBits);
281 static Register from_code() {
283 return Register::Create<code, kXRegSizeInBits>();
287 constexpr
explicit Register(
const CPURegister& r) : CPURegister(r) {}
290 ASSERT_TRIVIALLY_COPYABLE(Register);
292 constexpr
bool kPadArguments =
true;
293 constexpr
bool kSimpleFPAliasing =
true;
294 constexpr
bool kSimdMaskRegisters =
false;
296 enum DoubleRegisterCode {
297 #define REGISTER_CODE(R) kDoubleCode_##R, 298 DOUBLE_REGISTERS(REGISTER_CODE)
306 return VRegister(CPURegister::no_reg(), 0);
309 template <
int code,
int size,
int lane_count = 1>
311 static_assert(IsValidLaneCount(lane_count),
"Invalid lane count");
312 return VRegister(CPURegister::Create<code, size, kVRegister>(), lane_count);
315 static VRegister Create(
int code,
int size,
int lane_count = 1) {
316 DCHECK(IsValidLaneCount(lane_count));
317 return VRegister(CPURegister::Create(code, size, CPURegister::kVRegister),
321 static VRegister Create(
int reg_code, VectorFormat format) {
322 int reg_size = RegisterSizeInBitsFromFormat(format);
323 int reg_count = IsVectorFormat(format) ? LaneCountFromFormat(format) : 1;
324 return VRegister::Create(reg_code, reg_size, reg_count);
327 static VRegister BRegFromCode(
unsigned code);
328 static VRegister HRegFromCode(
unsigned code);
329 static VRegister SRegFromCode(
unsigned code);
330 static VRegister DRegFromCode(
unsigned code);
331 static VRegister QRegFromCode(
unsigned code);
332 static VRegister VRegFromCode(
unsigned code);
335 return VRegister::Create(code(), kDRegSizeInBits, 8);
338 return VRegister::Create(code(), kQRegSizeInBits, 16);
341 return VRegister::Create(code(), kDRegSizeInBits, 4);
344 return VRegister::Create(code(), kQRegSizeInBits, 8);
347 return VRegister::Create(code(), kDRegSizeInBits, 2);
350 return VRegister::Create(code(), kQRegSizeInBits, 4);
353 return VRegister::Create(code(), kQRegSizeInBits, 2);
356 return VRegister::Create(code(), kDRegSizeInBits, 1);
359 bool Is8B()
const {
return (Is64Bits() && (lane_count_ == 8)); }
360 bool Is16B()
const {
return (Is128Bits() && (lane_count_ == 16)); }
361 bool Is4H()
const {
return (Is64Bits() && (lane_count_ == 4)); }
362 bool Is8H()
const {
return (Is128Bits() && (lane_count_ == 8)); }
363 bool Is2S()
const {
return (Is64Bits() && (lane_count_ == 2)); }
364 bool Is4S()
const {
return (Is128Bits() && (lane_count_ == 4)); }
365 bool Is1D()
const {
return (Is64Bits() && (lane_count_ == 1)); }
366 bool Is2D()
const {
return (Is128Bits() && (lane_count_ == 2)); }
372 DCHECK(!(Is8Bits() && IsVector()));
376 DCHECK(!(Is16Bits() && IsVector()));
380 DCHECK(!(Is32Bits() && IsVector()));
384 bool IsLaneSizeB()
const {
return LaneSizeInBits() == kBRegSizeInBits; }
385 bool IsLaneSizeH()
const {
return LaneSizeInBits() == kHRegSizeInBits; }
386 bool IsLaneSizeS()
const {
return LaneSizeInBits() == kSRegSizeInBits; }
387 bool IsLaneSizeD()
const {
return LaneSizeInBits() == kDRegSizeInBits; }
389 bool IsScalar()
const {
return lane_count_ == 1; }
390 bool IsVector()
const {
return lane_count_ > 1; }
392 bool IsSameFormat(
const VRegister& other)
const {
393 return (reg_size_ == other.reg_size_) && (lane_count_ == other.lane_count_);
396 int LaneCount()
const {
return lane_count_; }
398 unsigned LaneSizeInBytes()
const {
return SizeInBytes() / lane_count_; }
400 unsigned LaneSizeInBits()
const {
return LaneSizeInBytes() * 8; }
402 static constexpr
int kMaxNumRegisters = kNumberOfVRegisters;
403 STATIC_ASSERT(kMaxNumRegisters == kDoubleAfterLast);
407 return VRegister::Create(code, kDRegSizeInBits);
416 static constexpr
bool IsValidLaneCount(
int lane_count) {
417 return base::bits::IsPowerOfTwo(lane_count) && lane_count <= 16;
426 constexpr
Register NoReg = Register::no_reg();
427 constexpr
VRegister NoVReg = VRegister::no_reg();
428 constexpr
CPURegister NoCPUReg = CPURegister::no_reg();
432 #define DEFINE_REGISTER(register_class, name, ...) \ 433 constexpr register_class name = register_class::Create<__VA_ARGS__>() 434 #define ALIAS_REGISTER(register_class, alias, name) \ 435 constexpr register_class alias = name 437 #define DEFINE_REGISTERS(N) \ 438 DEFINE_REGISTER(Register, w##N, N, kWRegSizeInBits); \ 439 DEFINE_REGISTER(Register, x##N, N, kXRegSizeInBits); 440 GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
441 #undef DEFINE_REGISTERS 443 DEFINE_REGISTER(
Register, wsp, kSPRegInternalCode, kWRegSizeInBits);
444 DEFINE_REGISTER(
Register, sp, kSPRegInternalCode, kXRegSizeInBits);
446 #define DEFINE_VREGISTERS(N) \ 447 DEFINE_REGISTER(VRegister, b##N, N, kBRegSizeInBits); \ 448 DEFINE_REGISTER(VRegister, h##N, N, kHRegSizeInBits); \ 449 DEFINE_REGISTER(VRegister, s##N, N, kSRegSizeInBits); \ 450 DEFINE_REGISTER(VRegister, d##N, N, kDRegSizeInBits); \ 451 DEFINE_REGISTER(VRegister, q##N, N, kQRegSizeInBits); \ 452 DEFINE_REGISTER(VRegister, v##N, N, kQRegSizeInBits); 453 GENERAL_REGISTER_CODE_LIST(DEFINE_VREGISTERS)
454 #undef DEFINE_VREGISTERS 456 #undef DEFINE_REGISTER 462 ALIAS_REGISTER(
Register, wip0, w16);
463 ALIAS_REGISTER(
Register, wip1, w17);
465 ALIAS_REGISTER(
Register, kRootRegister, x26);
475 ALIAS_REGISTER(
Register, padreg, x31);
480 ALIAS_REGISTER(
VRegister, fp_fixed1, d28);
481 ALIAS_REGISTER(
VRegister, fp_fixed2, d29);
484 ALIAS_REGISTER(
VRegister, fp_scratch, d30);
485 ALIAS_REGISTER(
VRegister, fp_scratch1, d30);
486 ALIAS_REGISTER(
VRegister, fp_scratch2, d31);
488 #undef ALIAS_REGISTER 505 bool AreSameSizeAndType(
534 template <
typename... CPURegisters>
536 : list_(CPURegister::ListOf(reg0, regs...)),
537 size_(reg0.SizeInBits()),
539 DCHECK(AreSameSizeAndType(reg0, regs...));
544 : list_(list), size_(size), type_(
type) {
548 CPURegList(CPURegister::RegisterType
type,
int size,
int first_reg,
550 : size_(size), type_(
type) {
552 ((
type == CPURegister::kRegister) && (last_reg < kNumberOfRegisters)) ||
553 ((
type == CPURegister::kVRegister) &&
554 (last_reg < kNumberOfVRegisters)));
555 DCHECK(last_reg >= first_reg);
556 list_ = (1ULL << (last_reg + 1)) - 1;
557 list_ &= ~((1ULL << first_reg) - 1);
561 CPURegister::RegisterType
type()
const {
571 inline void set_list(
RegList new_list) {
595 void Combine(
int code);
596 void Remove(
int code);
600 void RemoveCalleeSaved();
606 static CPURegList GetCalleeSaved(
int size = kXRegSizeInBits);
607 static CPURegList GetCalleeSavedV(
int size = kDRegSizeInBits);
612 static CPURegList GetCallerSaved(
int size = kXRegSizeInBits);
613 static CPURegList GetCallerSavedV(
int size = kDRegSizeInBits);
616 static CPURegList GetSafepointSavedRegisters();
618 bool IsEmpty()
const {
629 if (!other1.IsNone() && (other1.type() == type_)) list |= other1.bit();
630 if (!other2.IsNone() && (other2.type() == type_)) list |= other2.bit();
631 if (!other3.IsNone() && (other3.type() == type_)) list |= other3.bit();
632 if (!other4.IsNone() && (other4.type() == type_)) list |= other4.bit();
633 return (list_ & list) != 0;
638 return CountSetBits(list_, kRegListSizeInBits);
641 int RegisterSizeInBits()
const {
646 int RegisterSizeInBytes()
const {
647 int size_in_bits = RegisterSizeInBits();
648 DCHECK_EQ(size_in_bits % kBitsPerByte, 0);
649 return size_in_bits / kBitsPerByte;
652 int TotalSizeInBytes()
const {
654 return RegisterSizeInBytes() * Count();
660 CPURegister::RegisterType type_;
662 bool IsValid()
const {
663 constexpr
RegList kValidRegisters{0x8000000ffffffff};
664 constexpr
RegList kValidVRegisters{0x0000000ffffffff};
666 case CPURegister::kRegister:
667 return (list_ & kValidRegisters) == list_;
668 case CPURegister::kVRegister:
669 return (list_ & kValidVRegisters) == list_;
670 case CPURegister::kNoRegister:
680 #define kCalleeSaved CPURegList::GetCalleeSaved() 681 #define kCalleeSavedV CPURegList::GetCalleeSavedV() 684 #define kCallerSaved CPURegList::GetCallerSaved() 685 #define kCallerSavedV CPURegList::GetCallerSavedV() 700 inline Immediate(
T value, RelocInfo::Mode rmode);
702 int64_t value()
const {
return value_; }
703 RelocInfo::Mode rmode()
const {
return rmode_; }
709 RelocInfo::Mode rmode_;
715 constexpr
int kSmiShift = kSmiTagSize + kSmiShiftSize;
716 constexpr uint64_t kSmiShiftMask = (1ULL << kSmiShift) - 1;
730 unsigned shift_amount = 0);
737 unsigned shift_amount = 0);
739 static Operand EmbeddedNumber(
double number);
743 inline bool IsHeapObjectRequest()
const;
745 inline Immediate immediate_for_heap_object_request()
const;
756 inline Operand(
T t, RelocInfo::Mode rmode);
758 inline bool IsImmediate()
const;
759 inline bool IsShiftedRegister()
const;
760 inline bool IsExtendedRegister()
const;
761 inline bool IsZero()
const;
765 inline Operand ToExtendedRegister()
const;
768 inline int64_t ImmediateValue()
const;
769 inline RelocInfo::Mode ImmediateRMode()
const;
771 inline Shift shift()
const;
772 inline Extend extend()
const;
773 inline unsigned shift_amount()
const;
776 bool NeedsRelocation(
const Assembler* assembler)
const;
788 unsigned shift_amount_;
796 inline explicit MemOperand(Register base,
798 AddrMode addrmode = Offset);
799 inline explicit MemOperand(Register base,
802 unsigned shift_amount = 0);
803 inline explicit MemOperand(Register base,
806 unsigned shift_amount = 0);
807 inline explicit MemOperand(Register base,
808 const Operand& offset,
809 AddrMode addrmode = Offset);
811 const Register& base()
const {
return base_; }
812 const Register& regoffset()
const {
return regoffset_; }
813 int64_t offset()
const {
return offset_; }
814 AddrMode addrmode()
const {
return addrmode_; }
815 Shift shift()
const {
return shift_; }
816 Extend extend()
const {
return extend_; }
817 unsigned shift_amount()
const {
return shift_amount_; }
818 inline bool IsImmediateOffset()
const;
819 inline bool IsRegisterOffset()
const;
820 inline bool IsPreIndex()
const;
821 inline bool IsPostIndex()
const;
825 inline Operand OffsetAsOperand()
const;
833 static PairResult AreConsistentForPair(
const MemOperand& operandA,
834 const MemOperand& operandB,
835 int access_size_log2 = kXRegSizeLog2);
844 unsigned shift_amount_;
852 bool RecordEntry(intptr_t data, RelocInfo::Mode mode);
853 int EntryCount()
const {
return static_cast<int>(entries_.size()); }
854 bool IsEmpty()
const {
return entries_.empty(); }
857 int DistanceToFirstUse();
865 int SizeIfEmittedAtCurrentPc(
bool require_jump);
868 void Emit(
bool require_jump);
877 typedef std::map<uint64_t, int> SharedEntryMap;
881 bool AddSharedEntry(SharedEntryMap& entry_map, uint64_t data,
int offset);
889 SharedEntryMap shared_entries_;
894 SharedEntryMap handle_to_index_map_;
899 std::vector<std::pair<uint64_t, std::vector<int> > > entries_;
926 virtual void AbortedCodeGeneration() {
944 void GetCode(Isolate* isolate, CodeDesc* desc);
952 void DataAlign(
int m);
954 inline void Unreachable();
960 void bind(Label* label);
966 enum ConstantPoolMode { NEEDS_POOL_ENTRY, NO_POOL_ENTRY };
967 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
968 ConstantPoolMode constant_pool_mode = NEEDS_POOL_ENTRY);
974 void near_jump(
int offset, RelocInfo::Mode rmode);
978 void near_call(
int offset, RelocInfo::Mode rmode);
981 void near_call(HeapObjectRequest request);
985 inline static Address target_pointer_address_at(Address pc);
989 inline static Address target_address_at(Address pc, Address constant_pool);
990 inline static void set_target_address_at(
991 Address pc, Address constant_pool, Address target,
992 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
996 inline Handle<Code> code_target_object_handle_at(Address pc);
1004 inline Address runtime_entry_at(Address pc);
1008 inline static Address target_address_from_return_address(Address pc);
1013 inline static void deserialization_set_special_target_at(Address location,
1018 inline static int deserialization_special_target_size(Address location);
1021 inline static void deserialization_set_target_internal_reference_at(
1022 Address pc, Address target,
1023 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
1029 static constexpr
int kSpecialTargetSize = 0;
1032 uint64_t SizeOfGeneratedCode()
const {
1033 DCHECK((pc_ >= buffer_) && (pc_ < (buffer_ + buffer_size_)));
1034 return pc_ - buffer_;
1038 uint64_t SizeOfCodeGeneratedSince(
const Label* label) {
1039 DCHECK(label->is_bound());
1040 DCHECK(pc_offset() >= label->pos());
1041 DCHECK(pc_offset() < buffer_size_);
1042 return pc_offset() - label->pos();
1047 uint64_t InstructionsGeneratedSince(
const Label* label) {
1048 return SizeOfCodeGeneratedSince(label) / kInstrSize;
1054 void StartBlockConstPool();
1058 void EndBlockConstPool();
1060 bool is_const_pool_blocked()
const;
1061 static bool IsConstantPoolAt(Instruction* instr);
1062 static int ConstantPoolSizeAt(Instruction* instr);
1064 void EmitPoolGuard();
1069 void StartBlockVeneerPool();
1073 void EndBlockVeneerPool();
1075 bool is_veneer_pool_blocked()
const {
1076 return veneer_pool_blocked_nesting_ > 0;
1080 void StartBlockPools() {
1081 StartBlockConstPool();
1082 StartBlockVeneerPool();
1084 void EndBlockPools() {
1085 EndBlockConstPool();
1086 EndBlockVeneerPool();
1090 void RecordComment(
const char* msg);
1094 void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1097 int buffer_space()
const;
1116 void RecordConstPool(
int size);
1123 void br(
const Register& xn);
1126 void blr(
const Register& xn);
1129 void ret(
const Register& xn = lr);
1132 void b(Label* label);
1135 void b(Label* label, Condition cond);
1141 void b(
int imm19, Condition cond);
1144 void bl(Label* label);
1148 void cbz(
const Register& rt, Label* label);
1149 void cbz(
const Register& rt,
int imm19);
1152 void cbnz(
const Register& rt, Label* label);
1153 void cbnz(
const Register& rt,
int imm19);
1156 void tbz(
const Register& rt,
unsigned bit_pos, Label* label);
1157 void tbz(
const Register& rt,
unsigned bit_pos,
int imm14);
1160 void tbnz(
const Register& rt,
unsigned bit_pos, Label* label);
1161 void tbnz(
const Register& rt,
unsigned bit_pos,
int imm14);
1166 void adr(
const Register& rd, Label* label);
1167 void adr(
const Register& rd,
int imm21);
1171 void add(
const Register& rd,
1173 const Operand& operand);
1176 void adds(
const Register& rd,
1178 const Operand& operand);
1181 void cmn(
const Register& rn,
const Operand& operand);
1184 void sub(
const Register& rd,
1186 const Operand& operand);
1189 void subs(
const Register& rd,
1191 const Operand& operand);
1194 void cmp(
const Register& rn,
const Operand& operand);
1197 void neg(
const Register& rd,
1198 const Operand& operand);
1201 void negs(
const Register& rd,
1202 const Operand& operand);
1205 void adc(
const Register& rd,
1207 const Operand& operand);
1210 void adcs(
const Register& rd,
1212 const Operand& operand);
1215 void sbc(
const Register& rd,
1217 const Operand& operand);
1220 void sbcs(
const Register& rd,
1222 const Operand& operand);
1225 void ngc(
const Register& rd,
1226 const Operand& operand);
1229 void ngcs(
const Register& rd,
1230 const Operand& operand);
1234 void and_(
const Register& rd,
1236 const Operand& operand);
1239 void ands(
const Register& rd,
1241 const Operand& operand);
1244 void tst(
const Register& rn,
const Operand& operand);
1247 void bic(
const Register& rd,
1249 const Operand& operand);
1252 void bics(
const Register& rd,
1254 const Operand& operand);
1257 void and_(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1260 void bic(
const VRegister& vd,
const int imm8,
const int left_shift = 0);
1263 void bic(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1266 void bif(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1269 void bit(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1272 void bsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1275 void pmul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1278 void movi(
const VRegister& vd,
const uint64_t imm, Shift shift = LSL,
1279 const int shift_amount = 0);
1282 void mvn(
const VRegister& vd,
const VRegister& vn);
1285 void mvni(
const VRegister& vd,
const int imm8, Shift shift = LSL,
1286 const int shift_amount = 0);
1289 void suqadd(
const VRegister& vd,
const VRegister& vn);
1292 void usqadd(
const VRegister& vd,
const VRegister& vn);
1295 void abs(
const VRegister& vd,
const VRegister& vn);
1298 void sqabs(
const VRegister& vd,
const VRegister& vn);
1301 void neg(
const VRegister& vd,
const VRegister& vn);
1304 void sqneg(
const VRegister& vd,
const VRegister& vn);
1307 void not_(
const VRegister& vd,
const VRegister& vn);
1310 void xtn(
const VRegister& vd,
const VRegister& vn);
1313 void xtn2(
const VRegister& vd,
const VRegister& vn);
1316 void sqxtn(
const VRegister& vd,
const VRegister& vn);
1319 void sqxtn2(
const VRegister& vd,
const VRegister& vn);
1322 void uqxtn(
const VRegister& vd,
const VRegister& vn);
1325 void uqxtn2(
const VRegister& vd,
const VRegister& vn);
1328 void sqxtun(
const VRegister& vd,
const VRegister& vn);
1331 void sqxtun2(
const VRegister& vd,
const VRegister& vn);
1334 void mov(
const VRegister& vd,
const VRegister& vn);
1337 void orn(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1340 void eor(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1343 void orr(
const Register& rd,
const Register& rn,
const Operand& operand);
1346 void orr(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1349 void orr(
const VRegister& vd,
const int imm8,
const int left_shift = 0);
1352 void orn(
const Register& rd,
const Register& rn,
const Operand& operand);
1355 void eor(
const Register& rd,
const Register& rn,
const Operand& operand);
1358 void eon(
const Register& rd,
const Register& rn,
const Operand& operand);
1361 void lslv(
const Register& rd,
const Register& rn,
const Register& rm);
1364 void lsrv(
const Register& rd,
const Register& rn,
const Register& rm);
1367 void asrv(
const Register& rd,
const Register& rn,
const Register& rm);
1370 void rorv(
const Register& rd,
const Register& rn,
const Register& rm);
1374 void bfm(
const Register& rd,
const Register& rn,
int immr,
int imms);
1377 void sbfm(
const Register& rd,
const Register& rn,
int immr,
int imms);
1380 void ubfm(
const Register& rd,
const Register& rn,
int immr,
int imms);
1384 void bfi(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1385 DCHECK_GE(width, 1);
1386 DCHECK(lsb + width <= rn.SizeInBits());
1387 bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1391 void bfxil(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1392 DCHECK_GE(width, 1);
1393 DCHECK(lsb + width <= rn.SizeInBits());
1394 bfm(rd, rn, lsb, lsb + width - 1);
1399 void asr(
const Register& rd,
const Register& rn,
int shift) {
1400 DCHECK(shift < rd.SizeInBits());
1401 sbfm(rd, rn, shift, rd.SizeInBits() - 1);
1405 void sbfiz(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1406 DCHECK_GE(width, 1);
1407 DCHECK(lsb + width <= rn.SizeInBits());
1408 sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1412 void sbfx(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1413 DCHECK_GE(width, 1);
1414 DCHECK(lsb + width <= rn.SizeInBits());
1415 sbfm(rd, rn, lsb, lsb + width - 1);
1419 void sxtb(
const Register& rd,
const Register& rn) {
1424 void sxth(
const Register& rd,
const Register& rn) {
1425 sbfm(rd, rn, 0, 15);
1429 void sxtw(
const Register& rd,
const Register& rn) {
1430 sbfm(rd, rn, 0, 31);
1435 void lsl(
const Register& rd,
const Register& rn,
int shift) {
1436 int reg_size = rd.SizeInBits();
1437 DCHECK(shift < reg_size);
1438 ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1);
1442 void lsr(
const Register& rd,
const Register& rn,
int shift) {
1443 DCHECK(shift < rd.SizeInBits());
1444 ubfm(rd, rn, shift, rd.SizeInBits() - 1);
1448 void ubfiz(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1449 DCHECK_GE(width, 1);
1450 DCHECK(lsb + width <= rn.SizeInBits());
1451 ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
1455 void ubfx(
const Register& rd,
const Register& rn,
int lsb,
int width) {
1456 DCHECK_GE(width, 1);
1457 DCHECK(lsb + width <= rn.SizeInBits());
1458 ubfm(rd, rn, lsb, lsb + width - 1);
1462 void uxtb(
const Register& rd,
const Register& rn) {
1467 void uxth(
const Register& rd,
const Register& rn) {
1468 ubfm(rd, rn, 0, 15);
1472 void uxtw(
const Register& rd,
const Register& rn) {
1473 ubfm(rd, rn, 0, 31);
1477 void extr(
const Register& rd,
const Register& rn,
const Register& rm,
1481 void csel(
const Register& rd,
1487 void csinc(
const Register& rd,
1493 void csinv(
const Register& rd,
1499 void csneg(
const Register& rd,
1505 void cset(
const Register& rd, Condition cond);
1508 void csetm(
const Register& rd, Condition cond);
1511 void cinc(
const Register& rd,
const Register& rn, Condition cond);
1514 void cinv(
const Register& rd,
const Register& rn, Condition cond);
1517 void cneg(
const Register& rd,
const Register& rn, Condition cond);
1520 void ror(
const Register& rd,
const Register& rs,
unsigned shift) {
1521 extr(rd, rs, rs, shift);
1526 void ccmn(
const Register& rn,
1527 const Operand& operand,
1532 void ccmp(
const Register& rn,
1533 const Operand& operand,
1539 void mul(
const Register& rd,
const Register& rn,
const Register& rm);
1542 void madd(
const Register& rd,
1545 const Register& ra);
1548 void mneg(
const Register& rd,
const Register& rn,
const Register& rm);
1551 void msub(
const Register& rd,
1554 const Register& ra);
1557 void smull(
const Register& rd,
const Register& rn,
const Register& rm);
1560 void smulh(
const Register& rd,
const Register& rn,
const Register& rm);
1563 void smaddl(
const Register& rd,
1566 const Register& ra);
1569 void umaddl(
const Register& rd,
1572 const Register& ra);
1575 void smsubl(
const Register& rd,
1578 const Register& ra);
1581 void umsubl(
const Register& rd,
1584 const Register& ra);
1587 void sdiv(
const Register& rd,
const Register& rn,
const Register& rm);
1590 void udiv(
const Register& rd,
const Register& rn,
const Register& rm);
1593 void rbit(
const Register& rd,
const Register& rn);
1594 void rev16(
const Register& rd,
const Register& rn);
1595 void rev32(
const Register& rd,
const Register& rn);
1596 void rev(
const Register& rd,
const Register& rn);
1597 void clz(
const Register& rd,
const Register& rn);
1598 void cls(
const Register& rd,
const Register& rn);
1603 void ldr(
const CPURegister& rt,
const MemOperand& src);
1606 void str(
const CPURegister& rt,
const MemOperand& dst);
1609 void ldrsw(
const Register& rt,
const MemOperand& src);
1612 void ldrb(
const Register& rt,
const MemOperand& src);
1615 void strb(
const Register& rt,
const MemOperand& dst);
1618 void ldrsb(
const Register& rt,
const MemOperand& src);
1621 void ldrh(
const Register& rt,
const MemOperand& src);
1624 void strh(
const Register& rt,
const MemOperand& dst);
1627 void ldrsh(
const Register& rt,
const MemOperand& src);
1630 void ldp(
const CPURegister& rt,
const CPURegister& rt2,
1631 const MemOperand& src);
1634 void stp(
const CPURegister& rt,
const CPURegister& rt2,
1635 const MemOperand& dst);
1638 void ldpsw(
const Register& rt,
const Register& rt2,
const MemOperand& src);
1641 void ldr_pcrel(
const CPURegister& rt,
int imm19);
1644 void ldr(
const CPURegister& rt,
const Immediate& imm);
1645 void ldr(
const CPURegister& rt,
const Operand& operand);
1648 void ldar(
const Register& rt,
const Register& rn);
1651 void ldaxr(
const Register& rt,
const Register& rn);
1654 void stlr(
const Register& rt,
const Register& rn);
1657 void stlxr(
const Register& rs,
const Register& rt,
const Register& rn);
1660 void ldarb(
const Register& rt,
const Register& rn);
1663 void ldaxrb(
const Register& rt,
const Register& rn);
1666 void stlrb(
const Register& rt,
const Register& rn);
1669 void stlxrb(
const Register& rs,
const Register& rt,
const Register& rn);
1672 void ldarh(
const Register& rt,
const Register& rn);
1675 void ldaxrh(
const Register& rt,
const Register& rn);
1678 void stlrh(
const Register& rt,
const Register& rn);
1681 void stlxrh(
const Register& rs,
const Register& rt,
const Register& rn);
1694 void movk(
const Register& rd, uint64_t imm,
int shift = -1) {
1695 MoveWide(rd, imm, shift, MOVK);
1699 void movn(
const Register& rd, uint64_t imm,
int shift = -1) {
1700 MoveWide(rd, imm, shift, MOVN);
1704 void movz(
const Register& rd, uint64_t imm,
int shift = -1) {
1705 MoveWide(rd, imm, shift, MOVZ);
1716 void mov(
const Register& rd,
const Register& rn);
1719 void mvn(
const Register& rd,
const Operand& operand);
1723 void mrs(
const Register& rt, SystemRegister sysreg);
1726 void msr(SystemRegister sysreg,
const Register& rt);
1729 void hint(SystemHint code);
1732 void dmb(BarrierDomain domain, BarrierType type);
1735 void dsb(BarrierDomain domain, BarrierType type);
1744 void nop() { hint(NOP); }
1748 enum NopMarkerTypes {
1752 FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
1753 LAST_NOP_MARKER = ADR_FAR_NOP
1756 void nop(NopMarkerTypes n) {
1757 DCHECK((FIRST_NOP_MARKER <= n) && (n <= LAST_NOP_MARKER));
1758 mov(Register::XRegFromCode(n), Register::XRegFromCode(n));
1762 void add(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1765 void uhadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1768 void sub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1771 void shadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1774 void mul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1778 void mla(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1782 void mls(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1786 void smlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1790 void smlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1794 void umlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1798 void umlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1802 void smlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1806 void smlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1810 void umlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1814 void umlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1818 void smull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1822 void smull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1826 void umull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1830 void umull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1834 void addhn(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1837 void addhn2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1840 void sqdmull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1844 void sqdmull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1848 void sqdmlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1852 void sqdmlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1856 void sqdmlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1860 void sqdmlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1864 void cmeq(
const VRegister& vd,
const VRegister& vn,
int value);
1867 void cmge(
const VRegister& vd,
const VRegister& vn,
int value);
1870 void cmgt(
const VRegister& vd,
const VRegister& vn,
int value);
1873 void cmle(
const VRegister& vd,
const VRegister& vn,
int value);
1876 void cmlt(
const VRegister& vd,
const VRegister& vn,
int value);
1879 void urhadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1882 void cmeq(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1885 void cmge(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1888 void cmgt(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1891 void cmhi(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1894 void cmhs(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1897 void cmtst(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1900 void sshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1903 void ushl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1906 void sqdmlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1909 void sqdmlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1912 void sqdmull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1915 void sqdmull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1918 void sqdmulh(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1921 void sqrdmulh(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1924 void sqdmulh(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1928 void sqrdmulh(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
1932 void umull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1935 void umull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1938 void raddhn(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1941 void subhn(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1944 void subhn2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1947 void raddhn2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1950 void rsubhn(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1953 void rsubhn2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1956 void sqshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1959 void uqshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1962 void srshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1965 void urshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1968 void sqrshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1971 void uqrshl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1974 void sabd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1977 void uaba(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1980 void sli(
const VRegister& vd,
const VRegister& vn,
int shift);
1983 void sri(
const VRegister& vd,
const VRegister& vn,
int shift);
1986 void smax(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1989 void smaxp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
1992 void addv(
const VRegister& vd,
const VRegister& vn);
1995 void saddlv(
const VRegister& vd,
const VRegister& vn);
1998 void uaddlv(
const VRegister& vd,
const VRegister& vn);
2001 void fmaxnmv(
const VRegister& vd,
const VRegister& vn);
2004 void fmaxv(
const VRegister& vd,
const VRegister& vn);
2007 void fminnmv(
const VRegister& vd,
const VRegister& vn);
2010 void fminv(
const VRegister& vd,
const VRegister& vn);
2013 void smaxv(
const VRegister& vd,
const VRegister& vn);
2016 void smin(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2019 void sminp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2022 void sminv(
const VRegister& vd,
const VRegister& vn);
2025 void st1(
const VRegister& vt,
const MemOperand& src);
2028 void st1(
const VRegister& vt,
const VRegister& vt2,
const MemOperand& src);
2031 void st1(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2032 const MemOperand& src);
2035 void st1(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2036 const VRegister& vt4,
const MemOperand& src);
2039 void st1(
const VRegister& vt,
int lane,
const MemOperand& src);
2042 void st2(
const VRegister& vt,
const VRegister& vt2,
const MemOperand& src);
2045 void st2(
const VRegister& vt,
const VRegister& vt2,
int lane,
2046 const MemOperand& src);
2049 void st3(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2050 const MemOperand& src);
2053 void st3(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2054 int lane,
const MemOperand& src);
2057 void st4(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2058 const VRegister& vt4,
const MemOperand& src);
2061 void st4(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2062 const VRegister& vt4,
int lane,
const MemOperand& src);
2065 void uaddl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2068 void uaddl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2071 void uaddw(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2074 void uaddw2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2077 void saddl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2080 void saddl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2083 void saddw(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2086 void saddw2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2089 void usubl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2092 void usubl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2095 void usubw(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2098 void ssubl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2101 void ssubl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2104 void ssubw(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2107 void ssubw2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2110 void usubw2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2113 void umax(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2116 void umaxp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2119 void umaxv(
const VRegister& vd,
const VRegister& vn);
2122 void umin(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2125 void uminp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2128 void uminv(
const VRegister& vd,
const VRegister& vn);
2131 void trn1(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2134 void trn2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2137 void uzp1(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2140 void uzp2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2143 void zip1(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2146 void zip2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2149 void sshr(
const VRegister& vd,
const VRegister& vn,
int shift);
2152 void ushr(
const VRegister& vd,
const VRegister& vn,
int shift);
2155 void srshr(
const VRegister& vd,
const VRegister& vn,
int shift);
2158 void urshr(
const VRegister& vd,
const VRegister& vn,
int shift);
2161 void ssra(
const VRegister& vd,
const VRegister& vn,
int shift);
2164 void usra(
const VRegister& vd,
const VRegister& vn,
int shift);
2167 void srsra(
const VRegister& vd,
const VRegister& vn,
int shift);
2170 void ursra(
const VRegister& vd,
const VRegister& vn,
int shift);
2173 void shrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2176 void shrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2179 void rshrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2182 void rshrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2185 void uqshrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2188 void uqshrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2191 void uqrshrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2194 void uqrshrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2197 void sqshrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2200 void sqshrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2203 void sqrshrn(
const VRegister& vd,
const VRegister& vn,
int shift);
2206 void sqrshrn2(
const VRegister& vd,
const VRegister& vn,
int shift);
2209 void sqshrun(
const VRegister& vd,
const VRegister& vn,
int shift);
2212 void sqshrun2(
const VRegister& vd,
const VRegister& vn,
int shift);
2215 void sqrshrun(
const VRegister& vd,
const VRegister& vn,
int shift);
2218 void sqrshrun2(
const VRegister& vd,
const VRegister& vn,
int shift);
2221 void frecps(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2224 void frecpe(
const VRegister& vd,
const VRegister& vn);
2227 void frsqrte(
const VRegister& vd,
const VRegister& vn);
2230 void frsqrts(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2233 void sabal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2236 void sabal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2239 void uabal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2242 void uabal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2245 void sabdl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2248 void sabdl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2251 void uabdl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2254 void uabdl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2257 void pmull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2260 void pmull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2263 void smlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2266 void smlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2269 void umlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2272 void umlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2275 void smlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2278 void smlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2281 void umlsl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2284 void umlsl2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2287 void smull(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2290 void smull2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2293 void sqdmlal(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2296 void sqdmlal2(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2299 void uabd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2302 void saba(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2306 void fmov(
const VRegister& fd,
double imm);
2307 void fmov(
const VRegister& fd,
float imm);
2310 void fmov(
const Register& rd,
const VRegister& fn);
2313 void fmov(
const VRegister& fd,
const Register& rn);
2316 void fmov(
const VRegister& fd,
const VRegister& fn);
2319 void fmov(
const VRegister& vd,
int index,
const Register& rn);
2322 void fmov(
const Register& rd,
const VRegister& vn,
int index);
2325 void fadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2328 void fsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2331 void fmul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2334 void fcmeq(
const VRegister& vd,
const VRegister& vn,
double imm);
2337 void fcmgt(
const VRegister& vd,
const VRegister& vn,
double imm);
2340 void fcmge(
const VRegister& vd,
const VRegister& vn,
double imm);
2343 void fcmle(
const VRegister& vd,
const VRegister& vn,
double imm);
2346 void fcmlt(
const VRegister& vd,
const VRegister& vn,
double imm);
2349 void fabd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2352 void faddp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2355 void faddp(
const VRegister& vd,
const VRegister& vn);
2358 void fmaxp(
const VRegister& vd,
const VRegister& vn);
2361 void fmaxnmp(
const VRegister& vd,
const VRegister& vn);
2364 void fminnmp(
const VRegister& vd,
const VRegister& vn);
2367 void fmla(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2370 void fmls(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2373 void fmulx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2376 void facge(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2379 void facgt(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2382 void fmul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2386 void fmla(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2390 void fmls(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2394 void fmulx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2398 void fcmeq(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2401 void fcmgt(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2404 void fcmge(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2407 void fmaxp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2410 void fminp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2413 void fminp(
const VRegister& vd,
const VRegister& vn);
2416 void fmaxnmp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2419 void fminnmp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2422 void fmadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2423 const VRegister& va);
2426 void fmsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2427 const VRegister& va);
2430 void fnmadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2431 const VRegister& va);
2434 void fnmsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2435 const VRegister& va);
2438 void fnmul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2441 void frecpx(
const VRegister& vd,
const VRegister& vn);
2444 void fdiv(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2447 void fmax(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2450 void fmin(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2453 void fmaxnm(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2456 void fminnm(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2459 void fabs(
const VRegister& vd,
const VRegister& vn);
2462 void fneg(
const VRegister& vd,
const VRegister& vn);
2465 void fsqrt(
const VRegister& vd,
const VRegister& vn);
2468 void frinta(
const VRegister& vd,
const VRegister& vn);
2471 void frinti(
const VRegister& vd,
const VRegister& vn);
2474 void frintm(
const VRegister& vd,
const VRegister& vn);
2477 void frintn(
const VRegister& vd,
const VRegister& vn);
2480 void frintp(
const VRegister& vd,
const VRegister& vn);
2483 void frintx(
const VRegister& vd,
const VRegister& vn);
2486 void frintz(
const VRegister& vd,
const VRegister& vn);
2489 void fcmp(
const VRegister& vn,
const VRegister& vm);
2492 void fcmp(
const VRegister& vn,
double value);
2495 void fccmp(
const VRegister& vn,
const VRegister& vm, StatusFlags nzcv,
2499 void fcsel(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2503 void NEONFPConvertToInt(
const Register& rd,
const VRegister& vn, Instr op);
2504 void NEONFPConvertToInt(
const VRegister& vd,
const VRegister& vn, Instr op);
2507 void fcvt(
const VRegister& vd,
const VRegister& vn);
2510 void fcvtl(
const VRegister& vd,
const VRegister& vn);
2513 void fcvtl2(
const VRegister& vd,
const VRegister& vn);
2516 void fcvtn(
const VRegister& vd,
const VRegister& vn);
2519 void fcvtn2(
const VRegister& vd,
const VRegister& vn);
2522 void fcvtxn(
const VRegister& vd,
const VRegister& vn);
2525 void fcvtxn2(
const VRegister& vd,
const VRegister& vn);
2528 void fcvtas(
const Register& rd,
const VRegister& vn);
2531 void fcvtau(
const Register& rd,
const VRegister& vn);
2534 void fcvtas(
const VRegister& vd,
const VRegister& vn);
2537 void fcvtau(
const VRegister& vd,
const VRegister& vn);
2540 void fcvtms(
const Register& rd,
const VRegister& vn);
2543 void fcvtmu(
const Register& rd,
const VRegister& vn);
2546 void fcvtms(
const VRegister& vd,
const VRegister& vn);
2549 void fcvtmu(
const VRegister& vd,
const VRegister& vn);
2552 void fcvtns(
const Register& rd,
const VRegister& vn);
2555 void fcvtnu(
const Register& rd,
const VRegister& vn);
2558 void fcvtns(
const VRegister& rd,
const VRegister& vn);
2561 void fcvtnu(
const VRegister& rd,
const VRegister& vn);
2564 void fcvtzs(
const Register& rd,
const VRegister& vn,
int fbits = 0);
2567 void fcvtzu(
const Register& rd,
const VRegister& vn,
int fbits = 0);
2570 void fcvtzs(
const VRegister& vd,
const VRegister& vn,
int fbits = 0);
2573 void fcvtzu(
const VRegister& vd,
const VRegister& vn,
int fbits = 0);
2576 void fcvtps(
const Register& rd,
const VRegister& vn);
2579 void fcvtpu(
const Register& rd,
const VRegister& vn);
2582 void fcvtps(
const VRegister& vd,
const VRegister& vn);
2585 void fcvtpu(
const VRegister& vd,
const VRegister& vn);
2588 void scvtf(
const VRegister& fd,
const Register& rn,
int fbits = 0);
2591 void ucvtf(
const VRegister& fd,
const Register& rn,
int fbits = 0);
2594 void scvtf(
const VRegister& fd,
const VRegister& vn,
int fbits = 0);
2597 void ucvtf(
const VRegister& fd,
const VRegister& vn,
int fbits = 0);
2600 void ext(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm,
2604 void dup(
const VRegister& vd,
const VRegister& vn,
int vn_index);
2607 void dup(
const VRegister& vd,
const Register& rn);
2610 void ins(
const VRegister& vd,
int vd_index,
const Register& rn);
2613 void mov(
const VRegister& vd,
int vd_index,
const Register& rn);
2616 void umov(
const Register& rd,
const VRegister& vn,
int vn_index);
2619 void mov(
const Register& rd,
const VRegister& vn,
int vn_index);
2622 void mov(
const VRegister& vd,
const VRegister& vn,
int vn_index);
2625 void ins(
const VRegister& vd,
int vd_index,
const VRegister& vn,
2629 void mov(
const VRegister& vd,
int vd_index,
const VRegister& vn,
2633 void smov(
const Register& rd,
const VRegister& vn,
int vn_index);
2636 void ld1(
const VRegister& vt,
const MemOperand& src);
2639 void ld1(
const VRegister& vt,
const VRegister& vt2,
const MemOperand& src);
2642 void ld1(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2643 const MemOperand& src);
2646 void ld1(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2647 const VRegister& vt4,
const MemOperand& src);
2650 void ld1(
const VRegister& vt,
int lane,
const MemOperand& src);
2653 void ld1r(
const VRegister& vt,
const MemOperand& src);
2656 void ld2(
const VRegister& vt,
const VRegister& vt2,
const MemOperand& src);
2659 void ld2(
const VRegister& vt,
const VRegister& vt2,
int lane,
2660 const MemOperand& src);
2663 void ld2r(
const VRegister& vt,
const VRegister& vt2,
const MemOperand& src);
2666 void ld3(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2667 const MemOperand& src);
2670 void ld3(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2671 int lane,
const MemOperand& src);
2674 void ld3r(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2675 const MemOperand& src);
2678 void ld4(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2679 const VRegister& vt4,
const MemOperand& src);
2682 void ld4(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2683 const VRegister& vt4,
int lane,
const MemOperand& src);
2686 void ld4r(
const VRegister& vt,
const VRegister& vt2,
const VRegister& vt3,
2687 const VRegister& vt4,
const MemOperand& src);
2690 void cls(
const VRegister& vd,
const VRegister& vn);
2693 void clz(
const VRegister& vd,
const VRegister& vn);
2696 void cnt(
const VRegister& vd,
const VRegister& vn);
2699 void rbit(
const VRegister& vd,
const VRegister& vn);
2702 void rev16(
const VRegister& vd,
const VRegister& vn);
2705 void rev32(
const VRegister& vd,
const VRegister& vn);
2708 void rev64(
const VRegister& vd,
const VRegister& vn);
2711 void ursqrte(
const VRegister& vd,
const VRegister& vn);
2714 void urecpe(
const VRegister& vd,
const VRegister& vn);
2717 void sadalp(
const VRegister& vd,
const VRegister& vn);
2720 void saddlp(
const VRegister& vd,
const VRegister& vn);
2723 void uaddlp(
const VRegister& vd,
const VRegister& vn);
2726 void uadalp(
const VRegister& vd,
const VRegister& vn);
2729 void shl(
const VRegister& vd,
const VRegister& vn,
int shift);
2732 void sqshl(
const VRegister& vd,
const VRegister& vn,
int shift);
2735 void sqshlu(
const VRegister& vd,
const VRegister& vn,
int shift);
2738 void uqshl(
const VRegister& vd,
const VRegister& vn,
int shift);
2741 void sshll(
const VRegister& vd,
const VRegister& vn,
int shift);
2744 void sshll2(
const VRegister& vd,
const VRegister& vn,
int shift);
2747 void sxtl(
const VRegister& vd,
const VRegister& vn);
2750 void sxtl2(
const VRegister& vd,
const VRegister& vn);
2753 void ushll(
const VRegister& vd,
const VRegister& vn,
int shift);
2756 void ushll2(
const VRegister& vd,
const VRegister& vn,
int shift);
2759 void shll(
const VRegister& vd,
const VRegister& vn,
int shift);
2762 void shll2(
const VRegister& vd,
const VRegister& vn,
int shift);
2765 void uxtl(
const VRegister& vd,
const VRegister& vn);
2768 void uxtl2(
const VRegister& vd,
const VRegister& vn);
2771 void srhadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2774 void uhsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2777 void shsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2780 void uqadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2783 void sqadd(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2786 void uqsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2789 void sqsub(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2792 void addp(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2795 void addp(
const VRegister& vd,
const VRegister& vn);
2798 void mla(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2801 void mls(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2804 void mul(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2807 void tbl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2810 void tbl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2811 const VRegister& vm);
2814 void tbl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2815 const VRegister& vn3,
const VRegister& vm);
2818 void tbl(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2819 const VRegister& vn3,
const VRegister& vn4,
const VRegister& vm);
2822 void tbx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vm);
2825 void tbx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2826 const VRegister& vm);
2829 void tbx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2830 const VRegister& vn3,
const VRegister& vm);
2833 void tbx(
const VRegister& vd,
const VRegister& vn,
const VRegister& vn2,
2834 const VRegister& vn3,
const VRegister& vn4,
const VRegister& vm);
2838 void dci(Instr raw_inst) { Emit(raw_inst); }
2841 void dc8(uint8_t data) { EmitData(&data,
sizeof(data)); }
2844 void dc32(
uint32_t data) { EmitData(&data,
sizeof(data)); }
2847 void dc64(uint64_t data) { EmitData(&data,
sizeof(data)); }
2850 void dcptr(Label* label);
2855 void EmitStringData(
const char*
string);
2860 void debug(
const char* message,
uint32_t code, Instr params = BREAK);
2863 void dd(
uint32_t data) { dc32(data); }
2864 void db(uint8_t data) { dc8(data); }
2865 void dq(uint64_t data) { dc64(data); }
2870 bool IsConstPoolEmpty()
const {
return constpool_.IsEmpty(); }
2872 Instruction* pc()
const {
return Instruction::Cast(pc_); }
2874 Instruction* InstructionAt(ptrdiff_t offset)
const {
2875 return reinterpret_cast<Instruction*
>(buffer_ + offset);
2878 ptrdiff_t InstructionOffset(Instruction* instr)
const {
2879 return reinterpret_cast<byte*
>(instr) - buffer_;
2882 static const char* GetSpecialRegisterName(
int code) {
2883 return (code == kSPRegInternalCode) ?
"sp" :
"UNKNOWN";
2887 static Instr Rd(CPURegister rd) {
2888 DCHECK_NE(rd.code(), kSPRegInternalCode);
2889 return rd.code() << Rd_offset;
2892 static Instr Rn(CPURegister rn) {
2893 DCHECK_NE(rn.code(), kSPRegInternalCode);
2894 return rn.code() << Rn_offset;
2897 static Instr Rm(CPURegister rm) {
2898 DCHECK_NE(rm.code(), kSPRegInternalCode);
2899 return rm.code() << Rm_offset;
2902 static Instr RmNot31(CPURegister rm) {
2903 DCHECK_NE(rm.code(), kSPRegInternalCode);
2904 DCHECK(!rm.IsZero());
2908 static Instr Ra(CPURegister ra) {
2909 DCHECK_NE(ra.code(), kSPRegInternalCode);
2910 return ra.code() << Ra_offset;
2913 static Instr Rt(CPURegister rt) {
2914 DCHECK_NE(rt.code(), kSPRegInternalCode);
2915 return rt.code() << Rt_offset;
2918 static Instr Rt2(CPURegister rt2) {
2919 DCHECK_NE(rt2.code(), kSPRegInternalCode);
2920 return rt2.code() << Rt2_offset;
2923 static Instr Rs(CPURegister rs) {
2924 DCHECK_NE(rs.code(), kSPRegInternalCode);
2925 return rs.code() << Rs_offset;
2930 static Instr RdSP(Register rd) {
2931 DCHECK(!rd.IsZero());
2932 return (rd.code() & kRegCodeMask) << Rd_offset;
2935 static Instr RnSP(Register rn) {
2936 DCHECK(!rn.IsZero());
2937 return (rn.code() & kRegCodeMask) << Rn_offset;
2941 inline static Instr Flags(FlagsUpdate S);
2942 inline static Instr Cond(Condition cond);
2945 inline static Instr ImmPCRelAddress(
int imm21);
2948 inline static Instr ImmUncondBranch(
int imm26);
2949 inline static Instr ImmCondBranch(
int imm19);
2950 inline static Instr ImmCmpBranch(
int imm19);
2951 inline static Instr ImmTestBranch(
int imm14);
2952 inline static Instr ImmTestBranchBit(
unsigned bit_pos);
2955 inline static Instr SF(Register rd);
2956 inline static Instr ImmAddSub(
int imm);
2957 inline static Instr ImmS(
unsigned imms,
unsigned reg_size);
2958 inline static Instr ImmR(
unsigned immr,
unsigned reg_size);
2959 inline static Instr ImmSetBits(
unsigned imms,
unsigned reg_size);
2960 inline static Instr ImmRotate(
unsigned immr,
unsigned reg_size);
2961 inline static Instr ImmLLiteral(
int imm19);
2962 inline static Instr BitN(
unsigned bitn,
unsigned reg_size);
2963 inline static Instr ShiftDP(Shift shift);
2964 inline static Instr ImmDPShift(
unsigned amount);
2965 inline static Instr ExtendMode(Extend extend);
2966 inline static Instr ImmExtendShift(
unsigned left_shift);
2967 inline static Instr ImmCondCmp(
unsigned imm);
2968 inline static Instr Nzcv(StatusFlags nzcv);
2970 static bool IsImmAddSub(
int64_t immediate);
2971 static bool IsImmLogical(uint64_t value,
2978 inline static Instr ImmLSUnsigned(
int imm12);
2979 inline static Instr ImmLS(
int imm9);
2980 inline static Instr ImmLSPair(
int imm7,
unsigned size);
2981 inline static Instr ImmShiftLS(
unsigned shift_amount);
2982 inline static Instr ImmException(
int imm16);
2983 inline static Instr ImmSystemRegister(
int imm15);
2984 inline static Instr ImmHint(
int imm7);
2985 inline static Instr ImmBarrierDomain(
int imm2);
2986 inline static Instr ImmBarrierType(
int imm2);
2987 inline static unsigned CalcLSDataSize(LoadStoreOp op);
2990 static Instr VFormat(VRegister vd) {
2991 if (vd.Is64Bits()) {
2992 switch (vd.LaneCount()) {
3003 DCHECK(vd.Is128Bits());
3004 switch (vd.LaneCount()) {
3021 static Instr FPFormat(VRegister vd) {
3022 if (vd.LaneCount() == 1) {
3024 DCHECK(vd.Is32Bits() || vd.Is64Bits());
3025 return vd.Is64Bits() ? FP64 : FP32;
3029 if (vd.LaneCount() == 2) {
3030 DCHECK(vd.Is64Bits() || vd.Is128Bits());
3031 return vd.Is128Bits() ? NEON_FP_2D : NEON_FP_2S;
3035 DCHECK((vd.LaneCount() == 4) && vd.Is128Bits());
3040 static Instr LSVFormat(VRegister vd) {
3041 if (vd.Is64Bits()) {
3042 switch (vd.LaneCount()) {
3055 DCHECK(vd.Is128Bits());
3056 switch (vd.LaneCount()) {
3072 static Instr SFormat(VRegister vd) {
3073 DCHECK(vd.IsScalar());
3074 switch (vd.SizeInBytes()) {
3088 static Instr ImmNEONHLM(
int index,
int num_bits) {
3090 if (num_bits == 3) {
3091 DCHECK(is_uint3(index));
3092 h = (index >> 2) & 1;
3093 l = (index >> 1) & 1;
3094 m = (index >> 0) & 1;
3095 }
else if (num_bits == 2) {
3096 DCHECK(is_uint2(index));
3097 h = (index >> 1) & 1;
3098 l = (index >> 0) & 1;
3101 DCHECK(is_uint1(index) && (num_bits == 1));
3102 h = (index >> 0) & 1;
3106 return (h << NEONH_offset) | (l << NEONL_offset) | (m << NEONM_offset);
3109 static Instr ImmNEONExt(
int imm4) {
3110 DCHECK(is_uint4(imm4));
3111 return imm4 << ImmNEONExt_offset;
3114 static Instr ImmNEON5(Instr format,
int index) {
3115 DCHECK(is_uint4(index));
3116 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3117 int imm5 = (index << (s + 1)) | (1 << s);
3118 return imm5 << ImmNEON5_offset;
3121 static Instr ImmNEON4(Instr format,
int index) {
3122 DCHECK(is_uint4(index));
3123 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3124 int imm4 = index << s;
3125 return imm4 << ImmNEON4_offset;
3128 static Instr ImmNEONabcdefgh(
int imm8) {
3129 DCHECK(is_uint8(imm8));
3131 instr = ((imm8 >> 5) & 7) << ImmNEONabc_offset;
3132 instr |= (imm8 & 0x1f) << ImmNEONdefgh_offset;
3136 static Instr NEONCmode(
int cmode) {
3137 DCHECK(is_uint4(cmode));
3138 return cmode << NEONCmode_offset;
3141 static Instr NEONModImmOp(
int op) {
3142 DCHECK(is_uint1(op));
3143 return op << NEONModImmOp_offset;
3146 static bool IsImmLSUnscaled(
int64_t offset);
3147 static bool IsImmLSScaled(
int64_t offset,
unsigned size);
3148 static bool IsImmLLiteral(
int64_t offset);
3151 inline static Instr ImmMoveWide(
int imm);
3152 inline static Instr ShiftMoveWide(
int shift);
3155 static Instr ImmFP(
double imm);
3156 static Instr ImmNEONFP(
double imm);
3157 inline static Instr FPScale(
unsigned scale);
3160 inline static Instr FPType(VRegister fd);
3163 class BlockConstPoolScope {
3165 explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) {
3166 assem_->StartBlockConstPool();
3168 ~BlockConstPoolScope() {
3169 assem_->EndBlockConstPool();
3175 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
3179 void CheckConstPool(
bool force_emit,
bool require_jump);
3183 bool ShouldEmitVeneer(
int max_reachable_pc,
3184 int margin = kVeneerDistanceMargin);
3185 bool ShouldEmitVeneers(
int margin = kVeneerDistanceMargin) {
3186 return ShouldEmitVeneer(unresolved_branches_first_limit(), margin);
3192 static constexpr
int kMaxVeneerCodeSize = 1 * kInstrSize;
3194 void RecordVeneerPool(
int location_offset,
int size);
3198 void EmitVeneers(
bool force_emit,
bool need_protection,
3199 int margin = kVeneerDistanceMargin);
3200 void EmitVeneersGuard() { EmitPoolGuard(); }
3203 void CheckVeneerPool(
bool force_emit,
bool require_jump,
3204 int margin = kVeneerDistanceMargin);
3209 assem_->StartBlockPools();
3212 assem_->EndBlockPools();
3230 NEONLoadStoreMultiStructOp op);
3231 void LoadStoreStruct1(
const VRegister& vt,
int reg_count,
3235 NEONLoadStoreSingleStructOp op);
3236 void LoadStoreStructSingleAllLanes(
const VRegister& vt,
3238 NEONLoadStoreSingleStructOp op);
3242 static bool IsImmLSPair(
int64_t offset,
unsigned size);
3248 void LogicalImmediate(
const Register& rd,
3255 void ConditionalCompare(
const Register& rn,
3259 ConditionalCompareOp op);
3260 static bool IsImmConditionalCompare(
int64_t immediate);
3262 void AddSubWithCarry(
const Register& rd,
3266 AddSubWithCarryOp op);
3274 void EmitExtendShift(
const Register& rd,
3277 unsigned left_shift);
3285 static bool IsImmFP32(
float imm);
3286 static bool IsImmFP64(
double imm);
3291 static inline LoadStoreOp LoadOpFor(
const CPURegister& rt);
3292 static inline LoadStorePairOp LoadPairOpFor(
const CPURegister& rt,
3294 static inline LoadStoreOp StoreOpFor(
const CPURegister& rt);
3295 static inline LoadStorePairOp StorePairOpFor(
const CPURegister& rt,
3297 static inline LoadLiteralOp LoadLiteralOpFor(
const CPURegister& rt);
3306 static uint32_t FPToImm8(
double imm);
3312 MoveWideImmediateOp mov_op);
3313 void DataProcShiftedRegister(
const Register& rd,
3318 void DataProcExtendedRegister(
const Register& rd,
3323 void ConditionalSelect(
const Register& rd,
3327 ConditionalSelectOp op);
3328 void DataProcessing1Source(
const Register& rd,
3330 DataProcessing1SourceOp op);
3331 void DataProcessing3Source(
const Register& rd,
3335 DataProcessing3SourceOp op);
3337 FPDataProcessing1SourceOp op);
3340 FPDataProcessing2SourceOp op);
3343 FPDataProcessing3SourceOp op);
3345 NEONAcrossLanesOp op);
3347 NEONAcrossLanesOp op);
3348 void NEONModifiedImmShiftLsl(
const VRegister& vd,
const int imm8,
3349 const int left_shift,
3350 NEONModifiedImmediateOp op);
3351 void NEONModifiedImmShiftMsl(
const VRegister& vd,
const int imm8,
3352 const int shift_amount,
3353 NEONModifiedImmediateOp op);
3359 const VRegister& vm, NEON3DifferentOp vop);
3361 const VRegister& vm, NEON3DifferentOp vop);
3363 const VRegister& vm, NEON3DifferentOp vop);
3365 NEON2RegMiscOp vop,
double value = 0.0);
3367 NEON2RegMiscOp vop,
int value = 0);
3374 NEONByIndexedElementOp op);
3377 NEONByIndexedElementOp op);
3380 NEONByIndexedElementOp op);
3382 NEONShiftImmediateOp op,
int immh_immb);
3384 int shift, NEONShiftImmediateOp op);
3386 int shift, NEONShiftImmediateOp op);
3388 NEONShiftImmediateOp op);
3390 NEONShiftImmediateOp op);
3395 Instr LoadStoreStructAddrModeField(
const MemOperand& addr);
3400 int LinkAndGetByteOffsetTo(
Label* label);
3404 inline int LinkAndGetInstructionOffsetTo(
Label* label);
3406 static constexpr
int kStartOfLabelLinkChain = 0;
3409 void CheckLabelLinkChain(
Label const * label);
3413 void BlockConstPoolFor(
int instructions);
3416 void SetNextConstPoolCheckIn(
int instructions) {
3417 next_constant_pool_check_ = pc_offset() + instructions * kInstrSize;
3421 void Emit(Instr instruction) {
3422 STATIC_ASSERT(
sizeof(*pc_) == 1);
3423 STATIC_ASSERT(
sizeof(instruction) == kInstrSize);
3424 DCHECK((pc_ +
sizeof(instruction)) <= (buffer_ + buffer_size_));
3426 memcpy(pc_, &instruction,
sizeof(instruction));
3427 pc_ +=
sizeof(instruction);
3432 void EmitData(
void const * data,
unsigned size) {
3433 DCHECK_EQ(
sizeof(*pc_), 1);
3434 DCHECK((pc_ + size) <= (buffer_ + buffer_size_));
3438 memcpy(pc_, data, size);
3444 void CheckBufferSpace();
3448 int next_constant_pool_check_;
3465 static constexpr
int kCheckConstPoolInterval = 128;
3471 static constexpr
int kApproxMaxDistToConstPool = 64 * KB;
3475 static constexpr
int kApproxMaxPoolEntryCount = 512;
3478 int const_pool_blocked_nesting_;
3479 int no_const_pool_before_;
3482 int veneer_pool_blocked_nesting_;
3486 static constexpr
int kMaxRelocSize = RelocInfoWriter::kMaxSize;
3487 RelocInfoWriter reloc_info_writer;
3492 std::deque<int> internal_reference_positions_;
3502 ConstPool constpool_;
3511 static constexpr
int kGap = 128;
3516 int GetConstantPoolEntriesSizeForTesting()
const {
3518 return constpool_.EntryCount() * kPointerSize;
3521 static constexpr
int GetCheckConstPoolIntervalForTesting() {
3522 return kCheckConstPoolInterval;
3525 static constexpr
int GetApproxMaxDistToConstPoolForTesting() {
3526 return kApproxMaxDistToConstPool;
3533 : pc_offset_(offset), label_(label) {}
3553 std::multimap<int, FarBranchInfo> unresolved_branches_;
3557 static constexpr
int kVeneerDistanceMargin = 1 * KB;
3561 static constexpr
int kVeneerNoProtectionFactor = 2;
3562 static constexpr
int kVeneerDistanceCheckMargin =
3563 kVeneerNoProtectionFactor * kVeneerDistanceMargin;
3564 int unresolved_branches_first_limit()
const {
3565 DCHECK(!unresolved_branches_.empty());
3566 return unresolved_branches_.begin()->first;
3572 int next_veneer_pool_check_;
3576 static const int kMaximalBufferSize = 512 * MB;
3582 void DeleteUnresolvedBranchInfoForLabel(
Label* label);
3587 void DeleteUnresolvedBranchInfoForLabelTraverse(
Label* label);
3589 void AllocateAndInstallRequestedHeapObjects(
Isolate* isolate);
3595 class PatchingAssembler :
public Assembler {
3606 PatchingAssembler(
const AssemblerOptions& options, byte* start,
3608 : Assembler(options, start, count * kInstrSize + kGap) {
3613 ~PatchingAssembler() {
3615 DCHECK(is_const_pool_blocked());
3618 DCHECK((pc_offset() + kGap) == buffer_size_);
3620 DCHECK(IsConstPoolEmpty());
3624 static constexpr
int kAdrFarPatchableNNops = 2;
3625 static constexpr
int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2;
3626 void PatchAdrFar(
int64_t target_offset);
3627 void PatchSubSp(
uint32_t immediate);
3632 explicit EnsureSpace(Assembler* assembler) {
3633 assembler->CheckBufferSpace();
3638 DEFINE_REGISTER_NAMES(CPURegister, GENERAL_REGISTERS);
3643 #endif // V8_ARM64_ASSEMBLER_ARM64_H_