v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assembler-arm64.h
Go to the documentation of this file.
1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_CODEGEN_ARM64_ASSEMBLER_ARM64_H_
6#define V8_CODEGEN_ARM64_ASSEMBLER_ARM64_H_
7
8#include <deque>
9#include <map>
10#include <memory>
11#include <optional>
12
13#include "absl/container/flat_hash_map.h"
19#include "src/common/globals.h"
20#include "src/utils/utils.h"
22
23// Windows arm64 SDK defines mvn to NEON intrinsic neon_not which will not
24// be used here.
25#if defined(V8_OS_WIN) && defined(mvn)
26#undef mvn
27#endif
28
29#if defined(V8_OS_WIN)
31#endif // V8_OS_WIN
32
33namespace v8 {
34namespace internal {
35
36class SafepointTableBuilder;
37
38// -----------------------------------------------------------------------------
39// Immediates.
40class Immediate {
41 public:
42 template <typename T>
43 inline explicit Immediate(
45
46 // This is allowed to be an implicit constructor because Immediate is
47 // a wrapper class that doesn't normally perform any type conversion.
48 template <typename T>
49 inline Immediate(T value); // NOLINT(runtime/explicit)
50
51 template <typename T>
52 inline Immediate(T value, RelocInfo::Mode rmode);
53
54 int64_t value() const { return value_; }
55 RelocInfo::Mode rmode() const { return rmode_; }
56
57 private:
58 int64_t value_;
60};
61
62// -----------------------------------------------------------------------------
63// Operands.
65constexpr uint64_t kSmiShiftMask = (1ULL << kSmiShift) - 1;
66
67// Represents an operand in a machine instruction.
68class Operand {
69 // TODO(all): If necessary, study more in details which methods
70 // TODO(all): should be inlined or not.
71 public:
72 // rm, {<shift> {#<shift_amount>}}
73 // where <shift> is one of {LSL, LSR, ASR, ROR}.
74 // <shift_amount> is uint6_t.
75 // This is allowed to be an implicit constructor because Operand is
76 // a wrapper class that doesn't normally perform any type conversion.
78 unsigned shift_amount = 0); // NOLINT(runtime/explicit)
79
80 // rm, <extend> {#<shift_amount>}
81 // where <extend> is one of {UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX}.
82 // <shift_amount> is uint2_t.
83 inline Operand(Register reg, Extend extend, unsigned shift_amount = 0);
84
85 static Operand EmbeddedNumber(double number); // Smi or HeapNumber.
86 static Operand EmbeddedHeapNumber(double number);
87
88 inline bool IsHeapNumberRequest() const;
91
92 // Implicit constructor for all int types, ExternalReference, and Smi.
93 template <typename T>
94 inline Operand(T t); // NOLINT(runtime/explicit)
95
96 // Implicit constructor for int types.
97 template <typename T>
98 inline Operand(T t, RelocInfo::Mode rmode);
99
100 inline bool IsImmediate() const;
101 inline bool IsShiftedRegister() const;
102 inline bool IsExtendedRegister() const;
103 inline bool IsZero() const;
104
105 // This returns an LSL shift (<= 4) operand as an equivalent extend operand,
106 // which helps in the encoding of instructions that use the stack pointer.
107 inline Operand ToExtendedRegister() const;
108
109 // Returns new Operand adapted for using with W registers.
110 inline Operand ToW() const;
111
112 inline Immediate immediate() const;
113 inline int64_t ImmediateValue() const;
114 inline RelocInfo::Mode ImmediateRMode() const;
115 inline Register reg() const;
116 inline Shift shift() const;
117 inline Extend extend() const;
118 inline unsigned shift_amount() const;
119
120 // Relocation information.
121 bool NeedsRelocation(const Assembler* assembler) const;
122
123 private:
124 std::optional<HeapNumberRequest> heap_number_request_;
130};
131
132// MemOperand represents a memory operand in a load or store instruction.
133class MemOperand {
134 public:
135 inline MemOperand();
136 inline explicit MemOperand(Register base, int64_t offset = 0,
138 inline explicit MemOperand(Register base, Register regoffset,
139 Shift shift = LSL, unsigned shift_amount = 0);
140 inline explicit MemOperand(Register base, Register regoffset, Extend extend,
141 unsigned shift_amount = 0);
142 inline explicit MemOperand(Register base, const Operand& offset,
144
145 const Register& base() const { return base_; }
146 const Register& regoffset() const { return regoffset_; }
147 int64_t offset() const { return offset_; }
148 AddrMode addrmode() const { return addrmode_; }
149 Shift shift() const { return shift_; }
150 Extend extend() const { return extend_; }
151 unsigned shift_amount() const { return shift_amount_; }
152 inline bool IsImmediateOffset() const;
153 inline bool IsRegisterOffset() const;
154 inline bool IsPreIndex() const;
155 inline bool IsPostIndex() const;
156
157 private:
160 int64_t offset_;
165};
166
168 public:
169 explicit AssemblerZone(const MaybeAssemblerZone& zone)
170 // Create a fresh Zone unless one is already provided.
172 std::holds_alternative<Zone*>(zone)
173 ? std::nullopt
174 : std::make_optional<Zone>(std::get<AccountingAllocator*>(zone),
175 ZONE_NAME)),
176 zone_(std::holds_alternative<Zone*>(zone)
177 ? std::get<Zone*>(zone)
178 : &maybe_local_zone_.value()) {}
179
180 Zone* get() const { return zone_; }
181
182 private:
183 std::optional<Zone> maybe_local_zone_ = std::nullopt;
185};
186
187// -----------------------------------------------------------------------------
188// Assembler.
189
191 public:
192 // Create an assembler. Instructions and relocation information are emitted
193 // into a buffer, with the instructions starting from the beginning and the
194 // relocation information starting from the end of the buffer. See CodeDesc
195 // for a detailed comment on the layout (globals.h).
196 //
197 // When available, a zone should be provided for the assembler to manage
198 // temporary state, as long as the assembler does not outlive it. An
199 // AccountingAllocator can be provided instead.
200 //
201 // If the provided buffer is nullptr, the assembler allocates and grows its
202 // own buffer. Otherwise it takes ownership of the provided buffer.
204 std::unique_ptr<AssemblerBuffer> = {});
205
206 ~Assembler() override;
207
208 Zone* zone() const { return zone_.get(); }
209
210 void AbortedCodeGeneration() override;
211
212 // System functions ---------------------------------------------------------
213 // Start generating code from the beginning of the buffer, discarding any code
214 // and data that has already been emitted into the buffer.
215 //
216 // In order to avoid any accidental transfer of state, Reset DCHECKs that the
217 // constant pool is not blocked.
218 void Reset();
219
220 // GetCode emits any pending (non-emitted) code and fills the descriptor desc.
221 static constexpr int kNoHandlerTable = 0;
222 static constexpr SafepointTableBuilderBase* kNoSafepointTable = nullptr;
223 void GetCode(LocalIsolate* isolate, CodeDesc* desc,
224 SafepointTableBuilderBase* safepoint_table_builder,
225 int handler_table_offset);
226
227 // Convenience wrapper for allocating with an Isolate.
228 void GetCode(Isolate* isolate, CodeDesc* desc);
229 // Convenience wrapper for code without safepoint or handler tables.
230 void GetCode(LocalIsolate* isolate, CodeDesc* desc) {
231 GetCode(isolate, desc, kNoSafepointTable, kNoHandlerTable);
232 }
233
234 // Insert the smallest number of nop instructions
235 // possible to align the pc offset to a multiple
236 // of m. m must be a power of 2 (>= 4).
237 void Align(int m);
238 // Insert the smallest number of zero bytes possible to align the pc offset
239 // to a mulitple of m. m must be a power of 2 (>= 2).
240 void DataAlign(int m);
241
242 // Aligns code to something that's optimal for a jump target for the platform.
244 void LoopHeaderAlign() { CodeTargetAlign(); }
245
246 inline void Unreachable();
247
248 // Label --------------------------------------------------------------------
249 // Bind a label to the current pc. Note that labels can only be bound once,
250 // and if labels are linked to other instructions, they _must_ be bound
251 // before they go out of scope.
253
254 // RelocInfo and pools ------------------------------------------------------
255
256 // Record relocation information for current pc_.
257 enum ConstantPoolMode { NEEDS_POOL_ENTRY, NO_POOL_ENTRY };
258 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0,
259 ConstantPoolMode constant_pool_mode = NEEDS_POOL_ENTRY);
260
261 // Generate a B immediate instruction with the corresponding relocation info.
262 // 'offset' is the immediate to encode in the B instruction (so it is the
263 // difference between the target and the PC of the instruction, divided by
264 // the instruction size).
266 // Generate a BL immediate instruction with the corresponding relocation info.
267 // As for near_jump, 'offset' is the immediate to encode in the BL
268 // instruction.
270 // Generate a BL immediate instruction with the corresponding relocation info
271 // for the input HeapNumberRequest.
273
274 // Return the address in the constant pool of the code target address used by
275 // the branch/call instruction at pc.
276 inline static Address target_pointer_address_at(Address pc);
277
278 // Read/Modify the code target address in the branch/call instruction at pc.
279 // The isolate argument is unused (and may be nullptr) when skipping flushing.
280 inline static Address target_address_at(Address pc, Address constant_pool);
281
282 // Read/Modify the code target address in the branch/call instruction at pc.
283 inline static Tagged_t target_compressed_address_at(Address pc,
284 Address constant_pool);
285 inline static void set_target_address_at(
286 Address pc, Address constant_pool, Address target,
287 WritableJitAllocation* jit_allocation,
288 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
289
290 inline static void set_target_compressed_address_at(
291 Address pc, Address constant_pool, Tagged_t target,
292 WritableJitAllocation* jit_allocation,
293 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
294
295 // Returns the handle for the code object called at 'pc'.
296 // This might need to be temporarily encoded as an offset into code_targets_.
297 inline Handle<Code> code_target_object_handle_at(Address pc);
298 inline EmbeddedObjectIndex embedded_object_index_referenced_from(Address pc);
299 inline void set_embedded_object_index_referenced_from(
300 Address p, EmbeddedObjectIndex index);
301 // Returns the handle for the heap object referenced at 'pc'.
302 inline Handle<HeapObject> target_object_handle_at(Address pc);
303
304 // During code generation builtin targets in PC-relative call/jump
305 // instructions are temporarily encoded as builtin ID until the generated
306 // code is moved into the code space.
307 static inline Builtin target_builtin_at(Address pc);
308
309 // Get the size of the special target encoded at 'location'.
310 inline static int deserialization_special_target_size(Address location);
311
312 // This sets the internal reference at the pc.
314 Address pc, Address target, WritableJitAllocation& jit_allocation,
315 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
316
317 // Read/modify the uint32 constant used at pc.
318 static inline uint32_t uint32_constant_at(Address pc, Address constant_pool);
319 static inline void set_uint32_constant_at(
320 Address pc, Address constant_pool, uint32_t new_constant,
321 WritableJitAllocation* jit_allocation = nullptr,
322 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
323
324 // This value is used in the serialization process and must be zero for
325 // ARM64, as the code target is split across multiple instructions and does
326 // not exist separately in the code, so the serializer should not step
327 // forwards in memory after a target is resolved and written.
328 static constexpr int kSpecialTargetSize = 0;
329
330 // Size of the generated code in bytes
331 uint64_t SizeOfGeneratedCode() const {
332 DCHECK((pc_ >= buffer_start_) && (pc_ < (buffer_start_ + buffer_->size())));
333 return pc_ - buffer_start_;
334 }
335
336 // Return the code size generated from label to the current position.
338 DCHECK(label->is_bound());
339 DCHECK_GE(pc_offset(), label->pos());
340 DCHECK_LT(pc_offset(), buffer_->size());
341 return pc_offset() - label->pos();
342 }
343
344 // Return the number of instructions generated from label to the
345 // current position.
347 return SizeOfCodeGeneratedSince(label) / kInstrSize;
348 }
349
352 // See Assembler::CheckConstPool for more info.
354
355 // Prevent veneer pool emission until EndBlockVeneerPool is called.
356 // Call to this function can be nested but must be followed by an equal
357 // number of calls to EndBlockConstpool.
359
360 // Resume constant pool emission. Need to be called as many time as
361 // StartBlockVeneerPool to have an effect.
363
365 return veneer_pool_blocked_nesting_ > 0;
366 }
367
368 // Record a deoptimization reason that can be used by a log or cpu profiler.
369 // Use --trace-deopt to enable.
370 void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id,
371 SourcePosition position, int id);
372
373 int buffer_space() const;
374
375 // Record the emission of a constant pool.
376 //
377 // The emission of constant and veneer pools depends on the size of the code
378 // generated and the number of RelocInfo recorded.
379 // The Debug mechanism needs to map code offsets between two versions of a
380 // function, compiled with and without debugger support (see for example
381 // Debug::PrepareForBreakPoints()).
382 // Compiling functions with debugger support generates additional code
383 // (DebugCodegen::GenerateSlot()). This may affect the emission of the pools
384 // and cause the version of the code with debugger support to have pools
385 // generated in different places.
386 // Recording the position and size of emitted pools allows to correctly
387 // compute the offset mappings between the different versions of a function in
388 // all situations.
389 //
390 // The parameter indicates the size of the pool (in bytes), including
391 // the marker and branch over the data.
392 void RecordConstPool(int size);
393
394 // Instruction set functions ------------------------------------------------
395
396 // Branch / Jump instructions.
397 // For branches offsets are scaled, i.e. in instructions not in bytes.
398 // Branch to register.
399 void br(const Register& xn);
400
401 // Branch-link to register.
402 void blr(const Register& xn);
403
404 // Branch to register with return hint.
405 void ret(const Register& xn = lr);
406
407 // Unconditional branch to label.
408 void b(Label* label);
409
410 // Conditional branch to label.
411 void b(Label* label, Condition cond);
412
413 // Unconditional branch to PC offset.
414 void b(int imm26);
415
416 // Conditional branch to PC offset.
417 void b(int imm19, Condition cond);
418
419 // Branch-link to label / pc offset.
420 void bl(Label* label);
421 void bl(int imm26);
422
423 // Compare and branch to label / pc offset if zero.
424 void cbz(const Register& rt, Label* label);
425 void cbz(const Register& rt, int imm19);
426
427 // Compare and branch to label / pc offset if not zero.
428 void cbnz(const Register& rt, Label* label);
429 void cbnz(const Register& rt, int imm19);
430
431 // Test bit and branch to label / pc offset if zero.
432 void tbz(const Register& rt, unsigned bit_pos, Label* label);
433 void tbz(const Register& rt, unsigned bit_pos, int imm14);
434
435 // Test bit and branch to label / pc offset if not zero.
436 void tbnz(const Register& rt, unsigned bit_pos, Label* label);
437 void tbnz(const Register& rt, unsigned bit_pos, int imm14);
438
439 // Address calculation instructions.
440 // Calculate a PC-relative address. Unlike for branches the offset in adr is
441 // unscaled (i.e. the result can be unaligned).
442 void adr(const Register& rd, Label* label);
443 void adr(const Register& rd, int imm21);
444
445 // Data Processing instructions.
446 // Add.
447 void add(const Register& rd, const Register& rn, const Operand& operand);
448
449 // Add and update status flags.
450 void adds(const Register& rd, const Register& rn, const Operand& operand);
451
452 // Compare negative.
453 void cmn(const Register& rn, const Operand& operand);
454
455 // Subtract.
456 void sub(const Register& rd, const Register& rn, const Operand& operand);
457
458 // Subtract and update status flags.
459 void subs(const Register& rd, const Register& rn, const Operand& operand);
460
461 // Compare.
462 void cmp(const Register& rn, const Operand& operand);
463
464 // Negate.
465 void neg(const Register& rd, const Operand& operand);
466
467 // Negate and update status flags.
468 void negs(const Register& rd, const Operand& operand);
469
470 // Add with carry bit.
471 void adc(const Register& rd, const Register& rn, const Operand& operand);
472
473 // Add with carry bit and update status flags.
474 void adcs(const Register& rd, const Register& rn, const Operand& operand);
475
476 // Subtract with carry bit.
477 void sbc(const Register& rd, const Register& rn, const Operand& operand);
478
479 // Subtract with carry bit and update status flags.
480 void sbcs(const Register& rd, const Register& rn, const Operand& operand);
481
482 // Negate with carry bit.
483 void ngc(const Register& rd, const Operand& operand);
484
485 // Negate with carry bit and update status flags.
486 void ngcs(const Register& rd, const Operand& operand);
487
488 // Logical instructions.
489 // Bitwise and (A & B).
490 void and_(const Register& rd, const Register& rn, const Operand& operand);
491
492 // Bitwise and (A & B) and update status flags.
493 void ands(const Register& rd, const Register& rn, const Operand& operand);
494
495 // Bit test, and set flags.
496 void tst(const Register& rn, const Operand& operand);
497
498 // Bit clear (A & ~B).
499 void bic(const Register& rd, const Register& rn, const Operand& operand);
500
501 // Bit clear (A & ~B) and update status flags.
502 void bics(const Register& rd, const Register& rn, const Operand& operand);
503
504 // Bitwise and.
505 void and_(const VRegister& vd, const VRegister& vn, const VRegister& vm);
506
507 // Bit clear immediate.
508 void bic(const VRegister& vd, const int imm8, const int left_shift = 0);
509
510 // Bit clear.
511 void bic(const VRegister& vd, const VRegister& vn, const VRegister& vm);
512
513 // Bitwise insert if false.
514 void bif(const VRegister& vd, const VRegister& vn, const VRegister& vm);
515
516 // Bitwise insert if true.
517 void bit(const VRegister& vd, const VRegister& vn, const VRegister& vm);
518
519 // Bitwise select.
520 void bsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
521
522 // Polynomial multiply.
523 void pmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
524
525 // Vector move immediate.
526 void movi(const VRegister& vd, const uint64_t imm, Shift shift = LSL,
527 const int shift_amount = 0);
528
529 // Bitwise not.
530 void mvn(const VRegister& vd, const VRegister& vn);
531
532 // Vector move inverted immediate.
533 void mvni(const VRegister& vd, const int imm8, Shift shift = LSL,
534 const int shift_amount = 0);
535
536 // Signed saturating accumulate of unsigned value.
537 void suqadd(const VRegister& vd, const VRegister& vn);
538
539 // Unsigned saturating accumulate of signed value.
540 void usqadd(const VRegister& vd, const VRegister& vn);
541
542 // Absolute value.
543 void abs(const VRegister& vd, const VRegister& vn);
544
545 // Signed saturating absolute value.
546 void sqabs(const VRegister& vd, const VRegister& vn);
547
548 // Negate.
549 void neg(const VRegister& vd, const VRegister& vn);
550
551 // Signed saturating negate.
552 void sqneg(const VRegister& vd, const VRegister& vn);
553
554 // Bitwise not.
555 void not_(const VRegister& vd, const VRegister& vn);
556
557 // Extract narrow.
558 void xtn(const VRegister& vd, const VRegister& vn);
559
560 // Extract narrow (second part).
561 void xtn2(const VRegister& vd, const VRegister& vn);
562
563 // Signed saturating extract narrow.
564 void sqxtn(const VRegister& vd, const VRegister& vn);
565
566 // Signed saturating extract narrow (second part).
567 void sqxtn2(const VRegister& vd, const VRegister& vn);
568
569 // Unsigned saturating extract narrow.
570 void uqxtn(const VRegister& vd, const VRegister& vn);
571
572 // Unsigned saturating extract narrow (second part).
573 void uqxtn2(const VRegister& vd, const VRegister& vn);
574
575 // Signed saturating extract unsigned narrow.
576 void sqxtun(const VRegister& vd, const VRegister& vn);
577
578 // Signed saturating extract unsigned narrow (second part).
579 void sqxtun2(const VRegister& vd, const VRegister& vn);
580
581 // Move register to register.
582 void mov(const VRegister& vd, const VRegister& vn);
583
584 // Bitwise not or.
585 void orn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
586
587 // Bitwise exclusive or.
588 void eor(const VRegister& vd, const VRegister& vn, const VRegister& vm);
589
590 // Bitwise or (A | B).
591 void orr(const Register& rd, const Register& rn, const Operand& operand);
592
593 // Bitwise or.
594 void orr(const VRegister& vd, const VRegister& vn, const VRegister& vm);
595
596 // Bitwise or immediate.
597 void orr(const VRegister& vd, const int imm8, const int left_shift = 0);
598
599 // Bitwise nor (A | ~B).
600 void orn(const Register& rd, const Register& rn, const Operand& operand);
601
602 // Bitwise eor/xor (A ^ B).
603 void eor(const Register& rd, const Register& rn, const Operand& operand);
604
605 // Bitwise enor/xnor (A ^ ~B).
606 void eon(const Register& rd, const Register& rn, const Operand& operand);
607
608 // Logical shift left variable.
609 void lslv(const Register& rd, const Register& rn, const Register& rm);
610
611 // Logical shift right variable.
612 void lsrv(const Register& rd, const Register& rn, const Register& rm);
613
614 // Arithmetic shift right variable.
615 void asrv(const Register& rd, const Register& rn, const Register& rm);
616
617 // Rotate right variable.
618 void rorv(const Register& rd, const Register& rn, const Register& rm);
619
620 // Bitfield instructions.
621 // Bitfield move.
622 void bfm(const Register& rd, const Register& rn, int immr, int imms);
623
624 // Signed bitfield move.
625 void sbfm(const Register& rd, const Register& rn, int immr, int imms);
626
627 // Unsigned bitfield move.
628 void ubfm(const Register& rd, const Register& rn, int immr, int imms);
629
630 // Bfm aliases.
631 // Bitfield insert.
632 void bfi(const Register& rd, const Register& rn, int lsb, int width) {
633 DCHECK_GE(width, 1);
634 DCHECK(lsb + width <= rn.SizeInBits());
635 bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
636 }
637
638 // Bitfield extract and insert low.
639 void bfxil(const Register& rd, const Register& rn, int lsb, int width) {
640 DCHECK_GE(width, 1);
641 DCHECK(lsb + width <= rn.SizeInBits());
642 bfm(rd, rn, lsb, lsb + width - 1);
643 }
644
645 // Sbfm aliases.
646 // Arithmetic shift right.
647 void asr(const Register& rd, const Register& rn, int shift) {
648 DCHECK(shift < rd.SizeInBits());
649 sbfm(rd, rn, shift, rd.SizeInBits() - 1);
650 }
651
652 // Signed bitfield insert in zero.
653 void sbfiz(const Register& rd, const Register& rn, int lsb, int width) {
654 DCHECK_GE(width, 1);
655 DCHECK(lsb + width <= rn.SizeInBits());
656 sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
657 }
658
659 // Signed bitfield extract.
660 void sbfx(const Register& rd, const Register& rn, int lsb, int width) {
661 DCHECK_GE(width, 1);
662 DCHECK(lsb + width <= rn.SizeInBits());
663 sbfm(rd, rn, lsb, lsb + width - 1);
664 }
665
666 // Signed extend byte.
667 void sxtb(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 7); }
668
669 // Signed extend halfword.
670 void sxth(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 15); }
671
672 // Signed extend word.
673 void sxtw(const Register& rd, const Register& rn) { sbfm(rd, rn, 0, 31); }
674
675 // Ubfm aliases.
676 // Logical shift left.
677 void lsl(const Register& rd, const Register& rn, int shift) {
678 int reg_size = rd.SizeInBits();
679 DCHECK(shift < reg_size);
680 ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1);
681 }
682
683 // Logical shift right.
684 void lsr(const Register& rd, const Register& rn, int shift) {
685 DCHECK(shift < rd.SizeInBits());
686 ubfm(rd, rn, shift, rd.SizeInBits() - 1);
687 }
688
689 // Unsigned bitfield insert in zero.
690 void ubfiz(const Register& rd, const Register& rn, int lsb, int width) {
691 DCHECK_GE(width, 1);
692 DCHECK(lsb + width <= rn.SizeInBits());
693 ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1);
694 }
695
696 // Unsigned bitfield extract.
697 void ubfx(const Register& rd, const Register& rn, int lsb, int width) {
698 DCHECK_GE(width, 1);
699 DCHECK(lsb + width <= rn.SizeInBits());
700 ubfm(rd, rn, lsb, lsb + width - 1);
701 }
702
703 // Unsigned extend byte.
704 void uxtb(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 7); }
705
706 // Unsigned extend halfword.
707 void uxth(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 15); }
708
709 // Unsigned extend word.
710 void uxtw(const Register& rd, const Register& rn) { ubfm(rd, rn, 0, 31); }
711
712 // Extract.
713 void extr(const Register& rd, const Register& rn, const Register& rm,
714 int lsb);
715
716 // Conditional select: rd = cond ? rn : rm.
717 void csel(const Register& rd, const Register& rn, const Register& rm,
718 Condition cond);
719
720 // Conditional select increment: rd = cond ? rn : rm + 1.
721 void csinc(const Register& rd, const Register& rn, const Register& rm,
722 Condition cond);
723
724 // Conditional select inversion: rd = cond ? rn : ~rm.
725 void csinv(const Register& rd, const Register& rn, const Register& rm,
726 Condition cond);
727
728 // Conditional select negation: rd = cond ? rn : -rm.
729 void csneg(const Register& rd, const Register& rn, const Register& rm,
730 Condition cond);
731
732 // Conditional set: rd = cond ? 1 : 0.
733 void cset(const Register& rd, Condition cond);
734
735 // Conditional set minus: rd = cond ? -1 : 0.
736 void csetm(const Register& rd, Condition cond);
737
738 // Conditional increment: rd = cond ? rn + 1 : rn.
739 void cinc(const Register& rd, const Register& rn, Condition cond);
740
741 // Conditional invert: rd = cond ? ~rn : rn.
742 void cinv(const Register& rd, const Register& rn, Condition cond);
743
744 // Conditional negate: rd = cond ? -rn : rn.
745 void cneg(const Register& rd, const Register& rn, Condition cond);
746
747 // Extr aliases.
748 void ror(const Register& rd, const Register& rs, unsigned shift) {
749 extr(rd, rs, rs, shift);
750 }
751
752 // Conditional comparison.
753 // Conditional compare negative.
754 void ccmn(const Register& rn, const Operand& operand, StatusFlags nzcv,
755 Condition cond);
756
757 // Conditional compare.
758 void ccmp(const Register& rn, const Operand& operand, StatusFlags nzcv,
759 Condition cond);
760
761 // Multiplication.
762 // 32 x 32 -> 32-bit and 64 x 64 -> 64-bit multiply.
763 void mul(const Register& rd, const Register& rn, const Register& rm);
764
765 // 32 + 32 x 32 -> 32-bit and 64 + 64 x 64 -> 64-bit multiply accumulate.
766 void madd(const Register& rd, const Register& rn, const Register& rm,
767 const Register& ra);
768
769 // -(32 x 32) -> 32-bit and -(64 x 64) -> 64-bit multiply.
770 void mneg(const Register& rd, const Register& rn, const Register& rm);
771
772 // 32 - 32 x 32 -> 32-bit and 64 - 64 x 64 -> 64-bit multiply subtract.
773 void msub(const Register& rd, const Register& rn, const Register& rm,
774 const Register& ra);
775
776 // 32 x 32 -> 64-bit multiply.
777 void smull(const Register& rd, const Register& rn, const Register& rm);
778
779 // Xd = bits<127:64> of Xn * Xm, signed.
780 void smulh(const Register& rd, const Register& rn, const Register& rm);
781
782 // Xd = bits<127:64> of Xn * Xm, unsigned.
783 void umulh(const Register& rd, const Register& rn, const Register& rm);
784
785 // Signed 32 x 32 -> 64-bit multiply and accumulate.
786 void smaddl(const Register& rd, const Register& rn, const Register& rm,
787 const Register& ra);
788
789 // Unsigned 32 x 32 -> 64-bit multiply and accumulate.
790 void umaddl(const Register& rd, const Register& rn, const Register& rm,
791 const Register& ra);
792
793 // Signed 32 x 32 -> 64-bit multiply and subtract.
794 void smsubl(const Register& rd, const Register& rn, const Register& rm,
795 const Register& ra);
796
797 // Unsigned 32 x 32 -> 64-bit multiply and subtract.
798 void umsubl(const Register& rd, const Register& rn, const Register& rm,
799 const Register& ra);
800
801 // Signed integer divide.
802 void sdiv(const Register& rd, const Register& rn, const Register& rm);
803
804 // Unsigned integer divide.
805 void udiv(const Register& rd, const Register& rn, const Register& rm);
806
807 // Bit count, bit reverse and endian reverse.
808 void rbit(const Register& rd, const Register& rn);
809 void rev16(const Register& rd, const Register& rn);
810 void rev32(const Register& rd, const Register& rn);
811 void rev(const Register& rd, const Register& rn);
812 void clz(const Register& rd, const Register& rn);
813 void cls(const Register& rd, const Register& rn);
814
815 // Pointer Authentication InstructionStream for Instruction address, using key
816 // B, with address in x17 and modifier in x16 [Armv8.3].
817 void pacib1716();
818
819 // Pointer Authentication InstructionStream for Instruction address, using key
820 // B, with address in LR and modifier in SP [Armv8.3].
821 void pacibsp();
822
823 // Authenticate Instruction address, using key B, with address in x17 and
824 // modifier in x16 [Armv8.3].
825 void autib1716();
826
827 // Authenticate Instruction address, using key B, with address in LR and
828 // modifier in SP [Armv8.3].
829 void autibsp();
830
831 // Memory instructions.
832
833 // Load integer or FP register.
834 void ldr(const CPURegister& rt, const MemOperand& src);
835
836 // Store integer or FP register.
837 void str(const CPURegister& rt, const MemOperand& dst);
838
839 // Load word with sign extension.
840 void ldrsw(const Register& rt, const MemOperand& src);
841
842 // Load byte.
843 void ldrb(const Register& rt, const MemOperand& src);
844
845 // Store byte.
846 void strb(const Register& rt, const MemOperand& dst);
847
848 // Load byte with sign extension.
849 void ldrsb(const Register& rt, const MemOperand& src);
850
851 // Load half-word.
852 void ldrh(const Register& rt, const MemOperand& src);
853
854 // Store half-word.
855 void strh(const Register& rt, const MemOperand& dst);
856
857 // Load half-word with sign extension.
858 void ldrsh(const Register& rt, const MemOperand& src);
859
860 // Load integer or FP register pair.
861 void ldp(const CPURegister& rt, const CPURegister& rt2,
862 const MemOperand& src);
863
864 // Store integer or FP register pair.
865 void stp(const CPURegister& rt, const CPURegister& rt2,
866 const MemOperand& dst);
867
868 // Load word pair with sign extension.
869 void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src);
870
871 // Load literal to register from a pc relative address.
872 void ldr_pcrel(const CPURegister& rt, int imm19);
873
874 // Load literal to register.
875 void ldr(const CPURegister& rt, const Immediate& imm);
876 void ldr(const CPURegister& rt, const Operand& operand);
877
878 // Load-acquire word.
879 void ldar(const Register& rt, const Register& rn);
880
881 // Load-acquire exclusive word.
882 void ldaxr(const Register& rt, const Register& rn);
883
884 // Store-release word.
885 void stlr(const Register& rt, const Register& rn);
886
887 // Store-release exclusive word.
888 void stlxr(const Register& rs, const Register& rt, const Register& rn);
889
890 // Load-acquire byte.
891 void ldarb(const Register& rt, const Register& rn);
892
893 // Load-acquire exclusive byte.
894 void ldaxrb(const Register& rt, const Register& rn);
895
896 // Store-release byte.
897 void stlrb(const Register& rt, const Register& rn);
898
899 // Store-release exclusive byte.
900 void stlxrb(const Register& rs, const Register& rt, const Register& rn);
901
902 // Load-acquire half-word.
903 void ldarh(const Register& rt, const Register& rn);
904
905 // Load-acquire exclusive half-word.
906 void ldaxrh(const Register& rt, const Register& rn);
907
908 // Store-release half-word.
909 void stlrh(const Register& rt, const Register& rn);
910
911 // Store-release exclusive half-word.
912 void stlxrh(const Register& rs, const Register& rt, const Register& rn);
913
914 // Compare and Swap word or doubleword in memory [Armv8.1].
915 void cas(const Register& rs, const Register& rt, const MemOperand& src);
916
917 // Compare and Swap word or doubleword in memory, with Load-acquire semantics
918 // [Armv8.1].
919 void casa(const Register& rs, const Register& rt, const MemOperand& src);
920
921 // Compare and Swap word or doubleword in memory, with Store-release semantics
922 // [Armv8.1].
923 void casl(const Register& rs, const Register& rt, const MemOperand& src);
924
925 // Compare and Swap word or doubleword in memory, with Load-acquire and
926 // Store-release semantics [Armv8.1].
927 void casal(const Register& rs, const Register& rt, const MemOperand& src);
928
929 // Compare and Swap byte in memory [Armv8.1].
930 void casb(const Register& rs, const Register& rt, const MemOperand& src);
931
932 // Compare and Swap byte in memory, with Load-acquire semantics [Armv8.1].
933 void casab(const Register& rs, const Register& rt, const MemOperand& src);
934
935 // Compare and Swap byte in memory, with Store-release semantics [Armv8.1].
936 void caslb(const Register& rs, const Register& rt, const MemOperand& src);
937
938 // Compare and Swap byte in memory, with Load-acquire and Store-release
939 // semantics [Armv8.1].
940 void casalb(const Register& rs, const Register& rt, const MemOperand& src);
941
942 // Compare and Swap halfword in memory [Armv8.1].
943 void cash(const Register& rs, const Register& rt, const MemOperand& src);
944
945 // Compare and Swap halfword in memory, with Load-acquire semantics [Armv8.1].
946 void casah(const Register& rs, const Register& rt, const MemOperand& src);
947
948 // Compare and Swap halfword in memory, with Store-release semantics
949 // [Armv8.1].
950 void caslh(const Register& rs, const Register& rt, const MemOperand& src);
951
952 // Compare and Swap halfword in memory, with Load-acquire and Store-release
953 // semantics [Armv8.1].
954 void casalh(const Register& rs, const Register& rt, const MemOperand& src);
955
956 // Compare and Swap Pair of words or doublewords in memory [Armv8.1].
957 void casp(const Register& rs, const Register& rs2, const Register& rt,
958 const Register& rt2, const MemOperand& src);
959
960 // Compare and Swap Pair of words or doublewords in memory, with Load-acquire
961 // semantics [Armv8.1].
962 void caspa(const Register& rs, const Register& rs2, const Register& rt,
963 const Register& rt2, const MemOperand& src);
964
965 // Compare and Swap Pair of words or doublewords in memory, with Store-release
966 // semantics [Armv8.1].
967 void caspl(const Register& rs, const Register& rs2, const Register& rt,
968 const Register& rt2, const MemOperand& src);
969
970 // Compare and Swap Pair of words or doublewords in memory, with Load-acquire
971 // and Store-release semantics [Armv8.1].
972 void caspal(const Register& rs, const Register& rs2, const Register& rt,
973 const Register& rt2, const MemOperand& src);
974
975 // Atomic add on byte in memory [Armv8.1]
976 void ldaddb(const Register& rs, const Register& rt, const MemOperand& src);
977
978 // Atomic add on byte in memory, with Load-acquire semantics [Armv8.1]
979 void ldaddab(const Register& rs, const Register& rt, const MemOperand& src);
980
981 // Atomic add on byte in memory, with Store-release semantics [Armv8.1]
982 void ldaddlb(const Register& rs, const Register& rt, const MemOperand& src);
983
984 // Atomic add on byte in memory, with Load-acquire and Store-release semantics
985 // [Armv8.1]
986 void ldaddalb(const Register& rs, const Register& rt, const MemOperand& src);
987
988 // Atomic add on halfword in memory [Armv8.1]
989 void ldaddh(const Register& rs, const Register& rt, const MemOperand& src);
990
991 // Atomic add on halfword in memory, with Load-acquire semantics [Armv8.1]
992 void ldaddah(const Register& rs, const Register& rt, const MemOperand& src);
993
994 // Atomic add on halfword in memory, with Store-release semantics [Armv8.1]
995 void ldaddlh(const Register& rs, const Register& rt, const MemOperand& src);
996
997 // Atomic add on halfword in memory, with Load-acquire and Store-release
998 // semantics [Armv8.1]
999 void ldaddalh(const Register& rs, const Register& rt, const MemOperand& src);
1000
1001 // Atomic add on word or doubleword in memory [Armv8.1]
1002 void ldadd(const Register& rs, const Register& rt, const MemOperand& src);
1003
1004 // Atomic add on word or doubleword in memory, with Load-acquire semantics
1005 // [Armv8.1]
1006 void ldadda(const Register& rs, const Register& rt, const MemOperand& src);
1007
1008 // Atomic add on word or doubleword in memory, with Store-release semantics
1009 // [Armv8.1]
1010 void ldaddl(const Register& rs, const Register& rt, const MemOperand& src);
1011
1012 // Atomic add on word or doubleword in memory, with Load-acquire and
1013 // Store-release semantics [Armv8.1]
1014 void ldaddal(const Register& rs, const Register& rt, const MemOperand& src);
1015
1016 // Atomic bit clear on byte in memory [Armv8.1]
1017 void ldclrb(const Register& rs, const Register& rt, const MemOperand& src);
1018
1019 // Atomic bit clear on byte in memory, with Load-acquire semantics [Armv8.1]
1020 void ldclrab(const Register& rs, const Register& rt, const MemOperand& src);
1021
1022 // Atomic bit clear on byte in memory, with Store-release semantics [Armv8.1]
1023 void ldclrlb(const Register& rs, const Register& rt, const MemOperand& src);
1024
1025 // Atomic bit clear on byte in memory, with Load-acquire and Store-release
1026 // semantics [Armv8.1]
1027 void ldclralb(const Register& rs, const Register& rt, const MemOperand& src);
1028
1029 // Atomic bit clear on halfword in memory [Armv8.1]
1030 void ldclrh(const Register& rs, const Register& rt, const MemOperand& src);
1031
1032 // Atomic bit clear on halfword in memory, with Load-acquire semantics
1033 // [Armv8.1]
1034 void ldclrah(const Register& rs, const Register& rt, const MemOperand& src);
1035
1036 // Atomic bit clear on halfword in memory, with Store-release semantics
1037 // [Armv8.1]
1038 void ldclrlh(const Register& rs, const Register& rt, const MemOperand& src);
1039
1040 // Atomic bit clear on halfword in memory, with Load-acquire and Store-release
1041 // semantics [Armv8.1]
1042 void ldclralh(const Register& rs, const Register& rt, const MemOperand& src);
1043
1044 // Atomic bit clear on word or doubleword in memory [Armv8.1]
1045 void ldclr(const Register& rs, const Register& rt, const MemOperand& src);
1046
1047 // Atomic bit clear on word or doubleword in memory, with Load-acquire
1048 // semantics [Armv8.1]
1049 void ldclra(const Register& rs, const Register& rt, const MemOperand& src);
1050
1051 // Atomic bit clear on word or doubleword in memory, with Store-release
1052 // semantics [Armv8.1]
1053 void ldclrl(const Register& rs, const Register& rt, const MemOperand& src);
1054
1055 // Atomic bit clear on word or doubleword in memory, with Load-acquire and
1056 // Store-release semantics [Armv8.1]
1057 void ldclral(const Register& rs, const Register& rt, const MemOperand& src);
1058
1059 // Atomic exclusive OR on byte in memory [Armv8.1]
1060 void ldeorb(const Register& rs, const Register& rt, const MemOperand& src);
1061
1062 // Atomic exclusive OR on byte in memory, with Load-acquire semantics
1063 // [Armv8.1]
1064 void ldeorab(const Register& rs, const Register& rt, const MemOperand& src);
1065
1066 // Atomic exclusive OR on byte in memory, with Store-release semantics
1067 // [Armv8.1]
1068 void ldeorlb(const Register& rs, const Register& rt, const MemOperand& src);
1069
1070 // Atomic exclusive OR on byte in memory, with Load-acquire and Store-release
1071 // semantics [Armv8.1]
1072 void ldeoralb(const Register& rs, const Register& rt, const MemOperand& src);
1073
1074 // Atomic exclusive OR on halfword in memory [Armv8.1]
1075 void ldeorh(const Register& rs, const Register& rt, const MemOperand& src);
1076
1077 // Atomic exclusive OR on halfword in memory, with Load-acquire semantics
1078 // [Armv8.1]
1079 void ldeorah(const Register& rs, const Register& rt, const MemOperand& src);
1080
1081 // Atomic exclusive OR on halfword in memory, with Store-release semantics
1082 // [Armv8.1]
1083 void ldeorlh(const Register& rs, const Register& rt, const MemOperand& src);
1084
1085 // Atomic exclusive OR on halfword in memory, with Load-acquire and
1086 // Store-release semantics [Armv8.1]
1087 void ldeoralh(const Register& rs, const Register& rt, const MemOperand& src);
1088
1089 // Atomic exclusive OR on word or doubleword in memory [Armv8.1]
1090 void ldeor(const Register& rs, const Register& rt, const MemOperand& src);
1091
1092 // Atomic exclusive OR on word or doubleword in memory, with Load-acquire
1093 // semantics [Armv8.1]
1094 void ldeora(const Register& rs, const Register& rt, const MemOperand& src);
1095
1096 // Atomic exclusive OR on word or doubleword in memory, with Store-release
1097 // semantics [Armv8.1]
1098 void ldeorl(const Register& rs, const Register& rt, const MemOperand& src);
1099
1100 // Atomic exclusive OR on word or doubleword in memory, with Load-acquire and
1101 // Store-release semantics [Armv8.1]
1102 void ldeoral(const Register& rs, const Register& rt, const MemOperand& src);
1103
1104 // Atomic bit set on byte in memory [Armv8.1]
1105 void ldsetb(const Register& rs, const Register& rt, const MemOperand& src);
1106
1107 // Atomic bit set on byte in memory, with Load-acquire semantics [Armv8.1]
1108 void ldsetab(const Register& rs, const Register& rt, const MemOperand& src);
1109
1110 // Atomic bit set on byte in memory, with Store-release semantics [Armv8.1]
1111 void ldsetlb(const Register& rs, const Register& rt, const MemOperand& src);
1112
1113 // Atomic bit set on byte in memory, with Load-acquire and Store-release
1114 // semantics [Armv8.1]
1115 void ldsetalb(const Register& rs, const Register& rt, const MemOperand& src);
1116
1117 // Atomic bit set on halfword in memory [Armv8.1]
1118 void ldseth(const Register& rs, const Register& rt, const MemOperand& src);
1119
1120 // Atomic bit set on halfword in memory, with Load-acquire semantics [Armv8.1]
1121 void ldsetah(const Register& rs, const Register& rt, const MemOperand& src);
1122
1123 // Atomic bit set on halfword in memory, with Store-release semantics
1124 // [Armv8.1]
1125 void ldsetlh(const Register& rs, const Register& rt, const MemOperand& src);
1126
1127 // Atomic bit set on halfword in memory, with Load-acquire and Store-release
1128 // semantics [Armv8.1]
1129 void ldsetalh(const Register& rs, const Register& rt, const MemOperand& src);
1130
1131 // Atomic bit set on word or doubleword in memory [Armv8.1]
1132 void ldset(const Register& rs, const Register& rt, const MemOperand& src);
1133
1134 // Atomic bit set on word or doubleword in memory, with Load-acquire semantics
1135 // [Armv8.1]
1136 void ldseta(const Register& rs, const Register& rt, const MemOperand& src);
1137
1138 // Atomic bit set on word or doubleword in memory, with Store-release
1139 // semantics [Armv8.1]
1140 void ldsetl(const Register& rs, const Register& rt, const MemOperand& src);
1141
1142 // Atomic bit set on word or doubleword in memory, with Load-acquire and
1143 // Store-release semantics [Armv8.1]
1144 void ldsetal(const Register& rs, const Register& rt, const MemOperand& src);
1145
1146 // Atomic signed maximum on byte in memory [Armv8.1]
1147 void ldsmaxb(const Register& rs, const Register& rt, const MemOperand& src);
1148
1149 // Atomic signed maximum on byte in memory, with Load-acquire semantics
1150 // [Armv8.1]
1151 void ldsmaxab(const Register& rs, const Register& rt, const MemOperand& src);
1152
1153 // Atomic signed maximum on byte in memory, with Store-release semantics
1154 // [Armv8.1]
1155 void ldsmaxlb(const Register& rs, const Register& rt, const MemOperand& src);
1156
1157 // Atomic signed maximum on byte in memory, with Load-acquire and
1158 // Store-release semantics [Armv8.1]
1159 void ldsmaxalb(const Register& rs, const Register& rt, const MemOperand& src);
1160
1161 // Atomic signed maximum on halfword in memory [Armv8.1]
1162 void ldsmaxh(const Register& rs, const Register& rt, const MemOperand& src);
1163
1164 // Atomic signed maximum on halfword in memory, with Load-acquire semantics
1165 // [Armv8.1]
1166 void ldsmaxah(const Register& rs, const Register& rt, const MemOperand& src);
1167
1168 // Atomic signed maximum on halfword in memory, with Store-release semantics
1169 // [Armv8.1]
1170 void ldsmaxlh(const Register& rs, const Register& rt, const MemOperand& src);
1171
1172 // Atomic signed maximum on halfword in memory, with Load-acquire and
1173 // Store-release semantics [Armv8.1]
1174 void ldsmaxalh(const Register& rs, const Register& rt, const MemOperand& src);
1175
1176 // Atomic signed maximum on word or doubleword in memory [Armv8.1]
1177 void ldsmax(const Register& rs, const Register& rt, const MemOperand& src);
1178
1179 // Atomic signed maximum on word or doubleword in memory, with Load-acquire
1180 // semantics [Armv8.1]
1181 void ldsmaxa(const Register& rs, const Register& rt, const MemOperand& src);
1182
1183 // Atomic signed maximum on word or doubleword in memory, with Store-release
1184 // semantics [Armv8.1]
1185 void ldsmaxl(const Register& rs, const Register& rt, const MemOperand& src);
1186
1187 // Atomic signed maximum on word or doubleword in memory, with Load-acquire
1188 // and Store-release semantics [Armv8.1]
1189 void ldsmaxal(const Register& rs, const Register& rt, const MemOperand& src);
1190
1191 // Atomic signed minimum on byte in memory [Armv8.1]
1192 void ldsminb(const Register& rs, const Register& rt, const MemOperand& src);
1193
1194 // Atomic signed minimum on byte in memory, with Load-acquire semantics
1195 // [Armv8.1]
1196 void ldsminab(const Register& rs, const Register& rt, const MemOperand& src);
1197
1198 // Atomic signed minimum on byte in memory, with Store-release semantics
1199 // [Armv8.1]
1200 void ldsminlb(const Register& rs, const Register& rt, const MemOperand& src);
1201
1202 // Atomic signed minimum on byte in memory, with Load-acquire and
1203 // Store-release semantics [Armv8.1]
1204 void ldsminalb(const Register& rs, const Register& rt, const MemOperand& src);
1205
1206 // Atomic signed minimum on halfword in memory [Armv8.1]
1207 void ldsminh(const Register& rs, const Register& rt, const MemOperand& src);
1208
1209 // Atomic signed minimum on halfword in memory, with Load-acquire semantics
1210 // [Armv8.1]
1211 void ldsminah(const Register& rs, const Register& rt, const MemOperand& src);
1212
1213 // Atomic signed minimum on halfword in memory, with Store-release semantics
1214 // [Armv8.1]
1215 void ldsminlh(const Register& rs, const Register& rt, const MemOperand& src);
1216
1217 // Atomic signed minimum on halfword in memory, with Load-acquire and
1218 // Store-release semantics [Armv8.1]
1219 void ldsminalh(const Register& rs, const Register& rt, const MemOperand& src);
1220
1221 // Atomic signed minimum on word or doubleword in memory [Armv8.1]
1222 void ldsmin(const Register& rs, const Register& rt, const MemOperand& src);
1223
1224 // Atomic signed minimum on word or doubleword in memory, with Load-acquire
1225 // semantics [Armv8.1]
1226 void ldsmina(const Register& rs, const Register& rt, const MemOperand& src);
1227
1228 // Atomic signed minimum on word or doubleword in memory, with Store-release
1229 // semantics [Armv8.1]
1230 void ldsminl(const Register& rs, const Register& rt, const MemOperand& src);
1231
1232 // Atomic signed minimum on word or doubleword in memory, with Load-acquire
1233 // and Store-release semantics [Armv8.1]
1234 void ldsminal(const Register& rs, const Register& rt, const MemOperand& src);
1235
1236 // Atomic unsigned maximum on byte in memory [Armv8.1]
1237 void ldumaxb(const Register& rs, const Register& rt, const MemOperand& src);
1238
1239 // Atomic unsigned maximum on byte in memory, with Load-acquire semantics
1240 // [Armv8.1]
1241 void ldumaxab(const Register& rs, const Register& rt, const MemOperand& src);
1242
1243 // Atomic unsigned maximum on byte in memory, with Store-release semantics
1244 // [Armv8.1]
1245 void ldumaxlb(const Register& rs, const Register& rt, const MemOperand& src);
1246
1247 // Atomic unsigned maximum on byte in memory, with Load-acquire and
1248 // Store-release semantics [Armv8.1]
1249 void ldumaxalb(const Register& rs, const Register& rt, const MemOperand& src);
1250
1251 // Atomic unsigned maximum on halfword in memory [Armv8.1]
1252 void ldumaxh(const Register& rs, const Register& rt, const MemOperand& src);
1253
1254 // Atomic unsigned maximum on halfword in memory, with Load-acquire semantics
1255 // [Armv8.1]
1256 void ldumaxah(const Register& rs, const Register& rt, const MemOperand& src);
1257
1258 // Atomic unsigned maximum on halfword in memory, with Store-release semantics
1259 // [Armv8.1]
1260 void ldumaxlh(const Register& rs, const Register& rt, const MemOperand& src);
1261
1262 // Atomic unsigned maximum on halfword in memory, with Load-acquire and
1263 // Store-release semantics [Armv8.1]
1264 void ldumaxalh(const Register& rs, const Register& rt, const MemOperand& src);
1265
1266 // Atomic unsigned maximum on word or doubleword in memory [Armv8.1]
1267 void ldumax(const Register& rs, const Register& rt, const MemOperand& src);
1268
1269 // Atomic unsigned maximum on word or doubleword in memory, with Load-acquire
1270 // semantics [Armv8.1]
1271 void ldumaxa(const Register& rs, const Register& rt, const MemOperand& src);
1272
1273 // Atomic unsigned maximum on word or doubleword in memory, with Store-release
1274 // semantics [Armv8.1]
1275 void ldumaxl(const Register& rs, const Register& rt, const MemOperand& src);
1276
1277 // Atomic unsigned maximum on word or doubleword in memory, with Load-acquire
1278 // and Store-release semantics [Armv8.1]
1279 void ldumaxal(const Register& rs, const Register& rt, const MemOperand& src);
1280
1281 // Atomic unsigned minimum on byte in memory [Armv8.1]
1282 void lduminb(const Register& rs, const Register& rt, const MemOperand& src);
1283
1284 // Atomic unsigned minimum on byte in memory, with Load-acquire semantics
1285 // [Armv8.1]
1286 void lduminab(const Register& rs, const Register& rt, const MemOperand& src);
1287
1288 // Atomic unsigned minimum on byte in memory, with Store-release semantics
1289 // [Armv8.1]
1290 void lduminlb(const Register& rs, const Register& rt, const MemOperand& src);
1291
1292 // Atomic unsigned minimum on byte in memory, with Load-acquire and
1293 // Store-release semantics [Armv8.1]
1294 void lduminalb(const Register& rs, const Register& rt, const MemOperand& src);
1295
1296 // Atomic unsigned minimum on halfword in memory [Armv8.1]
1297 void lduminh(const Register& rs, const Register& rt, const MemOperand& src);
1298
1299 // Atomic unsigned minimum on halfword in memory, with Load-acquire semantics
1300 // [Armv8.1]
1301 void lduminah(const Register& rs, const Register& rt, const MemOperand& src);
1302
1303 // Atomic unsigned minimum on halfword in memory, with Store-release semantics
1304 // [Armv8.1]
1305 void lduminlh(const Register& rs, const Register& rt, const MemOperand& src);
1306
1307 // Atomic unsigned minimum on halfword in memory, with Load-acquire and
1308 // Store-release semantics [Armv8.1]
1309 void lduminalh(const Register& rs, const Register& rt, const MemOperand& src);
1310
1311 // Atomic unsigned minimum on word or doubleword in memory [Armv8.1]
1312 void ldumin(const Register& rs, const Register& rt, const MemOperand& src);
1313
1314 // Atomic unsigned minimum on word or doubleword in memory, with Load-acquire
1315 // semantics [Armv8.1]
1316 void ldumina(const Register& rs, const Register& rt, const MemOperand& src);
1317
1318 // Atomic unsigned minimum on word or doubleword in memory, with Store-release
1319 // semantics [Armv8.1]
1320 void lduminl(const Register& rs, const Register& rt, const MemOperand& src);
1321
1322 // Atomic unsigned minimum on word or doubleword in memory, with Load-acquire
1323 // and Store-release semantics [Armv8.1]
1324 void lduminal(const Register& rs, const Register& rt, const MemOperand& src);
1325
1326 // Atomic add on byte in memory, without return. [Armv8.1]
1327 void staddb(const Register& rs, const MemOperand& src);
1328
1329 // Atomic add on byte in memory, with Store-release semantics and without
1330 // return. [Armv8.1]
1331 void staddlb(const Register& rs, const MemOperand& src);
1332
1333 // Atomic add on halfword in memory, without return. [Armv8.1]
1334 void staddh(const Register& rs, const MemOperand& src);
1335
1336 // Atomic add on halfword in memory, with Store-release semantics and without
1337 // return. [Armv8.1]
1338 void staddlh(const Register& rs, const MemOperand& src);
1339
1340 // Atomic add on word or doubleword in memory, without return. [Armv8.1]
1341 void stadd(const Register& rs, const MemOperand& src);
1342
1343 // Atomic add on word or doubleword in memory, with Store-release semantics
1344 // and without return. [Armv8.1]
1345 void staddl(const Register& rs, const MemOperand& src);
1346
1347 // Atomic bit clear on byte in memory, without return. [Armv8.1]
1348 void stclrb(const Register& rs, const MemOperand& src);
1349
1350 // Atomic bit clear on byte in memory, with Store-release semantics and
1351 // without return. [Armv8.1]
1352 void stclrlb(const Register& rs, const MemOperand& src);
1353
1354 // Atomic bit clear on halfword in memory, without return. [Armv8.1]
1355 void stclrh(const Register& rs, const MemOperand& src);
1356
1357 // Atomic bit clear on halfword in memory, with Store-release semantics and
1358 // without return. [Armv8.1]
1359 void stclrlh(const Register& rs, const MemOperand& src);
1360
1361 // Atomic bit clear on word or doubleword in memory, without return. [Armv8.1]
1362 void stclr(const Register& rs, const MemOperand& src);
1363
1364 // Atomic bit clear on word or doubleword in memory, with Store-release
1365 // semantics and without return. [Armv8.1]
1366 void stclrl(const Register& rs, const MemOperand& src);
1367
1368 // Atomic exclusive OR on byte in memory, without return. [Armv8.1]
1369 void steorb(const Register& rs, const MemOperand& src);
1370
1371 // Atomic exclusive OR on byte in memory, with Store-release semantics and
1372 // without return. [Armv8.1]
1373 void steorlb(const Register& rs, const MemOperand& src);
1374
1375 // Atomic exclusive OR on halfword in memory, without return. [Armv8.1]
1376 void steorh(const Register& rs, const MemOperand& src);
1377
1378 // Atomic exclusive OR on halfword in memory, with Store-release semantics
1379 // and without return. [Armv8.1]
1380 void steorlh(const Register& rs, const MemOperand& src);
1381
1382 // Atomic exclusive OR on word or doubleword in memory, without return.
1383 // [Armv8.1]
1384 void steor(const Register& rs, const MemOperand& src);
1385
1386 // Atomic exclusive OR on word or doubleword in memory, with Store-release
1387 // semantics and without return. [Armv8.1]
1388 void steorl(const Register& rs, const MemOperand& src);
1389
1390 // Atomic bit set on byte in memory, without return. [Armv8.1]
1391 void stsetb(const Register& rs, const MemOperand& src);
1392
1393 // Atomic bit set on byte in memory, with Store-release semantics and without
1394 // return. [Armv8.1]
1395 void stsetlb(const Register& rs, const MemOperand& src);
1396
1397 // Atomic bit set on halfword in memory, without return. [Armv8.1]
1398 void stseth(const Register& rs, const MemOperand& src);
1399
1400 // Atomic bit set on halfword in memory, with Store-release semantics and
1401 // without return. [Armv8.1]
1402 void stsetlh(const Register& rs, const MemOperand& src);
1403
1404 // Atomic bit set on word or doubleword in memory, without return. [Armv8.1]
1405 void stset(const Register& rs, const MemOperand& src);
1406
1407 // Atomic bit set on word or doubleword in memory, with Store-release
1408 // semantics and without return. [Armv8.1]
1409 void stsetl(const Register& rs, const MemOperand& src);
1410
1411 // Atomic signed maximum on byte in memory, without return. [Armv8.1]
1412 void stsmaxb(const Register& rs, const MemOperand& src);
1413
1414 // Atomic signed maximum on byte in memory, with Store-release semantics and
1415 // without return. [Armv8.1]
1416 void stsmaxlb(const Register& rs, const MemOperand& src);
1417
1418 // Atomic signed maximum on halfword in memory, without return. [Armv8.1]
1419 void stsmaxh(const Register& rs, const MemOperand& src);
1420
1421 // Atomic signed maximum on halfword in memory, with Store-release semantics
1422 // and without return. [Armv8.1]
1423 void stsmaxlh(const Register& rs, const MemOperand& src);
1424
1425 // Atomic signed maximum on word or doubleword in memory, without return.
1426 // [Armv8.1]
1427 void stsmax(const Register& rs, const MemOperand& src);
1428
1429 // Atomic signed maximum on word or doubleword in memory, with Store-release
1430 // semantics and without return. [Armv8.1]
1431 void stsmaxl(const Register& rs, const MemOperand& src);
1432
1433 // Atomic signed minimum on byte in memory, without return. [Armv8.1]
1434 void stsminb(const Register& rs, const MemOperand& src);
1435
1436 // Atomic signed minimum on byte in memory, with Store-release semantics and
1437 // without return. [Armv8.1]
1438 void stsminlb(const Register& rs, const MemOperand& src);
1439
1440 // Atomic signed minimum on halfword in memory, without return. [Armv8.1]
1441 void stsminh(const Register& rs, const MemOperand& src);
1442
1443 // Atomic signed minimum on halfword in memory, with Store-release semantics
1444 // and without return. [Armv8.1]
1445 void stsminlh(const Register& rs, const MemOperand& src);
1446
1447 // Atomic signed minimum on word or doubleword in memory, without return.
1448 // [Armv8.1]
1449 void stsmin(const Register& rs, const MemOperand& src);
1450
1451 // Atomic signed minimum on word or doubleword in memory, with Store-release
1452 // semantics and without return. semantics [Armv8.1]
1453 void stsminl(const Register& rs, const MemOperand& src);
1454
1455 // Atomic unsigned maximum on byte in memory, without return. [Armv8.1]
1456 void stumaxb(const Register& rs, const MemOperand& src);
1457
1458 // Atomic unsigned maximum on byte in memory, with Store-release semantics and
1459 // without return. [Armv8.1]
1460 void stumaxlb(const Register& rs, const MemOperand& src);
1461
1462 // Atomic unsigned maximum on halfword in memory, without return. [Armv8.1]
1463 void stumaxh(const Register& rs, const MemOperand& src);
1464
1465 // Atomic unsigned maximum on halfword in memory, with Store-release semantics
1466 // and without return. [Armv8.1]
1467 void stumaxlh(const Register& rs, const MemOperand& src);
1468
1469 // Atomic unsigned maximum on word or doubleword in memory, without return.
1470 // [Armv8.1]
1471 void stumax(const Register& rs, const MemOperand& src);
1472
1473 // Atomic unsigned maximum on word or doubleword in memory, with Store-release
1474 // semantics and without return. [Armv8.1]
1475 void stumaxl(const Register& rs, const MemOperand& src);
1476
1477 // Atomic unsigned minimum on byte in memory, without return. [Armv8.1]
1478 void stuminb(const Register& rs, const MemOperand& src);
1479
1480 // Atomic unsigned minimum on byte in memory, with Store-release semantics and
1481 // without return. [Armv8.1]
1482 void stuminlb(const Register& rs, const MemOperand& src);
1483
1484 // Atomic unsigned minimum on halfword in memory, without return. [Armv8.1]
1485 void stuminh(const Register& rs, const MemOperand& src);
1486
1487 // Atomic unsigned minimum on halfword in memory, with Store-release semantics
1488 // and without return. [Armv8.1]
1489 void stuminlh(const Register& rs, const MemOperand& src);
1490
1491 // Atomic unsigned minimum on word or doubleword in memory, without return.
1492 // [Armv8.1]
1493 void stumin(const Register& rs, const MemOperand& src);
1494
1495 // Atomic unsigned minimum on word or doubleword in memory, with Store-release
1496 // semantics and without return. [Armv8.1]
1497 void stuminl(const Register& rs, const MemOperand& src);
1498
1499 // Swap byte in memory [Armv8.1]
1500 void swpb(const Register& rs, const Register& rt, const MemOperand& src);
1501
1502 // Swap byte in memory, with Load-acquire semantics [Armv8.1]
1503 void swpab(const Register& rs, const Register& rt, const MemOperand& src);
1504
1505 // Swap byte in memory, with Store-release semantics [Armv8.1]
1506 void swplb(const Register& rs, const Register& rt, const MemOperand& src);
1507
1508 // Swap byte in memory, with Load-acquire and Store-release semantics
1509 // [Armv8.1]
1510 void swpalb(const Register& rs, const Register& rt, const MemOperand& src);
1511
1512 // Swap halfword in memory [Armv8.1]
1513 void swph(const Register& rs, const Register& rt, const MemOperand& src);
1514
1515 // Swap halfword in memory, with Load-acquire semantics [Armv8.1]
1516 void swpah(const Register& rs, const Register& rt, const MemOperand& src);
1517
1518 // Swap halfword in memory, with Store-release semantics [Armv8.1]
1519 void swplh(const Register& rs, const Register& rt, const MemOperand& src);
1520
1521 // Swap halfword in memory, with Load-acquire and Store-release semantics
1522 // [Armv8.1]
1523 void swpalh(const Register& rs, const Register& rt, const MemOperand& src);
1524
1525 // Swap word or doubleword in memory [Armv8.1]
1526 void swp(const Register& rs, const Register& rt, const MemOperand& src);
1527
1528 // Swap word or doubleword in memory, with Load-acquire semantics [Armv8.1]
1529 void swpa(const Register& rs, const Register& rt, const MemOperand& src);
1530
1531 // Swap word or doubleword in memory, with Store-release semantics [Armv8.1]
1532 void swpl(const Register& rs, const Register& rt, const MemOperand& src);
1533
1534 // Swap word or doubleword in memory, with Load-acquire and Store-release
1535 // semantics [Armv8.1]
1536 void swpal(const Register& rs, const Register& rt, const MemOperand& src);
1537
1538 // Move instructions. The default shift of -1 indicates that the move
1539 // instruction will calculate an appropriate 16-bit immediate and left shift
1540 // that is equal to the 64-bit immediate argument. If an explicit left shift
1541 // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value.
1542 //
1543 // For movk, an explicit shift can be used to indicate which half word should
1544 // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant
1545 // half word with zero, whereas movk(x0, 0, 48) will overwrite the
1546 // most-significant.
1547
1548 // Move and keep.
1549 void movk(const Register& rd, uint64_t imm, int shift = -1) {
1550 MoveWide(rd, imm, shift, MOVK);
1551 }
1552
1553 // Move with non-zero.
1554 void movn(const Register& rd, uint64_t imm, int shift = -1) {
1555 MoveWide(rd, imm, shift, MOVN);
1556 }
1557
1558 // Move with zero.
1559 void movz(const Register& rd, uint64_t imm, int shift = -1) {
1560 MoveWide(rd, imm, shift, MOVZ);
1561 }
1562
1563 // Misc instructions.
1564 // Monitor debug-mode breakpoint.
1565 void brk(int code);
1566
1567 // Halting debug-mode breakpoint.
1568 void hlt(int code);
1569
1570 // Move register to register.
1571 void mov(const Register& rd, const Register& rn);
1572
1573 // Move NOT(operand) to register.
1574 void mvn(const Register& rd, const Operand& operand);
1575
1576 // System instructions.
1577 // Move to register from system register.
1578 void mrs(const Register& rt, SystemRegister sysreg);
1579
1580 // Move from register to system register.
1581 void msr(SystemRegister sysreg, const Register& rt);
1582
1583 // System hint.
1584 void hint(SystemHint code);
1585
1586 // Data memory barrier
1587 void dmb(BarrierDomain domain, BarrierType type);
1588
1589 // Data synchronization barrier
1590 void dsb(BarrierDomain domain, BarrierType type);
1591
1592 // Instruction synchronization barrier
1593 void isb();
1594
1595 // Conditional speculation barrier.
1596 void csdb();
1597
1598 // Branch target identification.
1600
1601 // No-op.
1602 void nop() { hint(NOP); }
1603
1604 // Different nop operations are used by the code generator to detect certain
1605 // states of the generated code.
1607 DEBUG_BREAK_NOP,
1610 FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
1611 LAST_NOP_MARKER = ADR_FAR_NOP
1613
1615
1616 // Add.
1617 void add(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1618
1619 // Unsigned halving add.
1620 void uhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1621
1622 // Subtract.
1623 void sub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1624
1625 // Signed halving add.
1626 void shadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1627
1628 // Multiply by scalar element.
1629 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1630 int vm_index);
1631
1632 // Multiply-add by scalar element.
1633 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1634 int vm_index);
1635
1636 // Multiply-subtract by scalar element.
1637 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1638 int vm_index);
1639
1640 // Signed long multiply-add by scalar element.
1641 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1642 int vm_index);
1643
1644 // Signed long multiply-add by scalar element (second part).
1645 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1646 int vm_index);
1647
1648 // Unsigned long multiply-add by scalar element.
1649 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1650 int vm_index);
1651
1652 // Unsigned long multiply-add by scalar element (second part).
1653 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1654 int vm_index);
1655
1656 // Signed long multiply-sub by scalar element.
1657 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1658 int vm_index);
1659
1660 // Signed long multiply-sub by scalar element (second part).
1661 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1662 int vm_index);
1663
1664 // Unsigned long multiply-sub by scalar element.
1665 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1666 int vm_index);
1667
1668 // Unsigned long multiply-sub by scalar element (second part).
1669 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1670 int vm_index);
1671
1672 // Signed long multiply by scalar element.
1673 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1674 int vm_index);
1675
1676 // Signed long multiply by scalar element (second part).
1677 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1678 int vm_index);
1679
1680 // Unsigned long multiply by scalar element.
1681 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1682 int vm_index);
1683
1684 // Unsigned long multiply by scalar element (second part).
1685 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1686 int vm_index);
1687
1688 // Add narrow returning high half.
1689 void addhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1690
1691 // Add narrow returning high half (second part).
1692 void addhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1693
1694 // Signed saturating double long multiply by element.
1695 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1696 int vm_index);
1697
1698 // Signed saturating double long multiply by element (second part).
1699 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1700 int vm_index);
1701
1702 // Signed saturating doubling long multiply-add by element.
1703 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1704 int vm_index);
1705
1706 // Signed saturating doubling long multiply-add by element (second part).
1707 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1708 int vm_index);
1709
1710 // Signed saturating doubling long multiply-sub by element.
1711 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1712 int vm_index);
1713
1714 // Signed saturating doubling long multiply-sub by element (second part).
1715 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1716 int vm_index);
1717
1718 // Compare bitwise to zero.
1719 void cmeq(const VRegister& vd, const VRegister& vn, int value);
1720
1721 // Compare signed greater than or equal to zero.
1722 void cmge(const VRegister& vd, const VRegister& vn, int value);
1723
1724 // Compare signed greater than zero.
1725 void cmgt(const VRegister& vd, const VRegister& vn, int value);
1726
1727 // Compare signed less than or equal to zero.
1728 void cmle(const VRegister& vd, const VRegister& vn, int value);
1729
1730 // Compare signed less than zero.
1731 void cmlt(const VRegister& vd, const VRegister& vn, int value);
1732
1733 // Unsigned rounding halving add.
1734 void urhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1735
1736 // Compare equal.
1737 void cmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1738
1739 // Compare signed greater than or equal.
1740 void cmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1741
1742 // Compare signed greater than.
1743 void cmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1744
1745 // Compare unsigned higher.
1746 void cmhi(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1747
1748 // Compare unsigned higher or same.
1749 void cmhs(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1750
1751 // Compare bitwise test bits nonzero.
1752 void cmtst(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1753
1754 // Signed shift left by register.
1755 void sshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1756
1757 // Unsigned shift left by register.
1758 void ushl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1759
1760 // Signed saturating doubling long multiply-subtract.
1761 void sqdmlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1762
1763 // Signed saturating doubling long multiply-subtract (second part).
1764 void sqdmlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1765
1766 // Signed saturating doubling long multiply.
1767 void sqdmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1768
1769 // Signed saturating doubling long multiply (second part).
1770 void sqdmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1771
1772 // Signed saturating doubling multiply returning high half.
1773 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1774
1775 // Signed saturating rounding doubling multiply returning high half.
1776 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1777
1778 // Signed saturating doubling multiply element returning high half.
1779 void sqdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1780 int vm_index);
1781
1782 // Signed saturating rounding doubling multiply element returning high half.
1783 void sqrdmulh(const VRegister& vd, const VRegister& vn, const VRegister& vm,
1784 int vm_index);
1785
1786 // Unsigned long multiply long.
1787 void umull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1788
1789 // Unsigned long multiply (second part).
1790 void umull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1791
1792 // Rounding add narrow returning high half.
1793 void raddhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1794
1795 // Subtract narrow returning high half.
1796 void subhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1797
1798 // Subtract narrow returning high half (second part).
1799 void subhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1800
1801 // Rounding add narrow returning high half (second part).
1802 void raddhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1803
1804 // Rounding subtract narrow returning high half.
1805 void rsubhn(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1806
1807 // Rounding subtract narrow returning high half (second part).
1808 void rsubhn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1809
1810 // Signed saturating shift left by register.
1811 void sqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1812
1813 // Unsigned saturating shift left by register.
1814 void uqshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1815
1816 // Signed rounding shift left by register.
1817 void srshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1818
1819 // Unsigned rounding shift left by register.
1820 void urshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1821
1822 // Signed saturating rounding shift left by register.
1823 void sqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1824
1825 // Unsigned saturating rounding shift left by register.
1826 void uqrshl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1827
1828 // Signed absolute difference.
1829 void sabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1830
1831 // Unsigned absolute difference and accumulate.
1832 void uaba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1833
1834 // Shift left by immediate and insert.
1835 void sli(const VRegister& vd, const VRegister& vn, int shift);
1836
1837 // Shift right by immediate and insert.
1838 void sri(const VRegister& vd, const VRegister& vn, int shift);
1839
1840 // Signed maximum.
1841 void smax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1842
1843 // Signed pairwise maximum.
1844 void smaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1845
1846 // Add across vector.
1847 void addv(const VRegister& vd, const VRegister& vn);
1848
1849 // Signed add long across vector.
1850 void saddlv(const VRegister& vd, const VRegister& vn);
1851
1852 // Unsigned add long across vector.
1853 void uaddlv(const VRegister& vd, const VRegister& vn);
1854
1855 // FP maximum number across vector.
1856 void fmaxnmv(const VRegister& vd, const VRegister& vn);
1857
1858 // FP maximum across vector.
1859 void fmaxv(const VRegister& vd, const VRegister& vn);
1860
1861 // FP minimum number across vector.
1862 void fminnmv(const VRegister& vd, const VRegister& vn);
1863
1864 // FP minimum across vector.
1865 void fminv(const VRegister& vd, const VRegister& vn);
1866
1867 // Signed maximum across vector.
1868 void smaxv(const VRegister& vd, const VRegister& vn);
1869
1870 // Signed minimum.
1871 void smin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1872
1873 // Signed minimum pairwise.
1874 void sminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1875
1876 // Signed minimum across vector.
1877 void sminv(const VRegister& vd, const VRegister& vn);
1878
1879 // Signed dot product
1880 void sdot(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1881
1882 // One-element structure store from one register.
1883 void st1(const VRegister& vt, const MemOperand& src);
1884
1885 // One-element structure store from two registers.
1886 void st1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
1887
1888 // One-element structure store from three registers.
1889 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1890 const MemOperand& src);
1891
1892 // One-element structure store from four registers.
1893 void st1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1894 const VRegister& vt4, const MemOperand& src);
1895
1896 // One-element single structure store from one lane.
1897 void st1(const VRegister& vt, int lane, const MemOperand& src);
1898
1899 // Two-element structure store from two registers.
1900 void st2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
1901
1902 // Two-element single structure store from two lanes.
1903 void st2(const VRegister& vt, const VRegister& vt2, int lane,
1904 const MemOperand& src);
1905
1906 // Three-element structure store from three registers.
1907 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1908 const MemOperand& src);
1909
1910 // Three-element single structure store from three lanes.
1911 void st3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1912 int lane, const MemOperand& src);
1913
1914 // Four-element structure store from four registers.
1915 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1916 const VRegister& vt4, const MemOperand& src);
1917
1918 // Four-element single structure store from four lanes.
1919 void st4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
1920 const VRegister& vt4, int lane, const MemOperand& src);
1921
1922 // Unsigned add long.
1923 void uaddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1924
1925 // Unsigned add long (second part).
1926 void uaddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1927
1928 // Unsigned add wide.
1929 void uaddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1930
1931 // Unsigned add wide (second part).
1932 void uaddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1933
1934 // Signed add long.
1935 void saddl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1936
1937 // Signed add long (second part).
1938 void saddl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1939
1940 // Signed add wide.
1941 void saddw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1942
1943 // Signed add wide (second part).
1944 void saddw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1945
1946 // Unsigned subtract long.
1947 void usubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1948
1949 // Unsigned subtract long (second part).
1950 void usubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1951
1952 // Unsigned subtract wide.
1953 void usubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1954
1955 // Signed subtract long.
1956 void ssubl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1957
1958 // Signed subtract long (second part).
1959 void ssubl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1960
1961 // Signed integer subtract wide.
1962 void ssubw(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1963
1964 // Signed integer subtract wide (second part).
1965 void ssubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1966
1967 // Unsigned subtract wide (second part).
1968 void usubw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1969
1970 // Unsigned maximum.
1971 void umax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1972
1973 // Unsigned pairwise maximum.
1974 void umaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1975
1976 // Unsigned maximum across vector.
1977 void umaxv(const VRegister& vd, const VRegister& vn);
1978
1979 // Unsigned minimum.
1980 void umin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1981
1982 // Unsigned pairwise minimum.
1983 void uminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1984
1985 // Unsigned minimum across vector.
1986 void uminv(const VRegister& vd, const VRegister& vn);
1987
1988 // Transpose vectors (primary).
1989 void trn1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1990
1991 // Transpose vectors (secondary).
1992 void trn2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1993
1994 // Unzip vectors (primary).
1995 void uzp1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1996
1997 // Unzip vectors (secondary).
1998 void uzp2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
1999
2000 // Zip vectors (primary).
2001 void zip1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2002
2003 // Zip vectors (secondary).
2004 void zip2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2005
2006 // Signed shift right by immediate.
2007 void sshr(const VRegister& vd, const VRegister& vn, int shift);
2008
2009 // Unsigned shift right by immediate.
2010 void ushr(const VRegister& vd, const VRegister& vn, int shift);
2011
2012 // Signed rounding shift right by immediate.
2013 void srshr(const VRegister& vd, const VRegister& vn, int shift);
2014
2015 // Unsigned rounding shift right by immediate.
2016 void urshr(const VRegister& vd, const VRegister& vn, int shift);
2017
2018 // Signed shift right by immediate and accumulate.
2019 void ssra(const VRegister& vd, const VRegister& vn, int shift);
2020
2021 // Unsigned shift right by immediate and accumulate.
2022 void usra(const VRegister& vd, const VRegister& vn, int shift);
2023
2024 // Signed rounding shift right by immediate and accumulate.
2025 void srsra(const VRegister& vd, const VRegister& vn, int shift);
2026
2027 // Unsigned rounding shift right by immediate and accumulate.
2028 void ursra(const VRegister& vd, const VRegister& vn, int shift);
2029
2030 // Shift right narrow by immediate.
2031 void shrn(const VRegister& vd, const VRegister& vn, int shift);
2032
2033 // Shift right narrow by immediate (second part).
2034 void shrn2(const VRegister& vd, const VRegister& vn, int shift);
2035
2036 // Rounding shift right narrow by immediate.
2037 void rshrn(const VRegister& vd, const VRegister& vn, int shift);
2038
2039 // Rounding shift right narrow by immediate (second part).
2040 void rshrn2(const VRegister& vd, const VRegister& vn, int shift);
2041
2042 // Unsigned saturating shift right narrow by immediate.
2043 void uqshrn(const VRegister& vd, const VRegister& vn, int shift);
2044
2045 // Unsigned saturating shift right narrow by immediate (second part).
2046 void uqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2047
2048 // Unsigned saturating rounding shift right narrow by immediate.
2049 void uqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2050
2051 // Unsigned saturating rounding shift right narrow by immediate (second part).
2052 void uqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2053
2054 // Signed saturating shift right narrow by immediate.
2055 void sqshrn(const VRegister& vd, const VRegister& vn, int shift);
2056
2057 // Signed saturating shift right narrow by immediate (second part).
2058 void sqshrn2(const VRegister& vd, const VRegister& vn, int shift);
2059
2060 // Signed saturating rounded shift right narrow by immediate.
2061 void sqrshrn(const VRegister& vd, const VRegister& vn, int shift);
2062
2063 // Signed saturating rounded shift right narrow by immediate (second part).
2064 void sqrshrn2(const VRegister& vd, const VRegister& vn, int shift);
2065
2066 // Signed saturating shift right unsigned narrow by immediate.
2067 void sqshrun(const VRegister& vd, const VRegister& vn, int shift);
2068
2069 // Signed saturating shift right unsigned narrow by immediate (second part).
2070 void sqshrun2(const VRegister& vd, const VRegister& vn, int shift);
2071
2072 // Signed sat rounded shift right unsigned narrow by immediate.
2073 void sqrshrun(const VRegister& vd, const VRegister& vn, int shift);
2074
2075 // Signed sat rounded shift right unsigned narrow by immediate (second part).
2076 void sqrshrun2(const VRegister& vd, const VRegister& vn, int shift);
2077
2078 // FP reciprocal step.
2079 void frecps(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2080
2081 // FP reciprocal estimate.
2082 void frecpe(const VRegister& vd, const VRegister& vn);
2083
2084 // FP reciprocal square root estimate.
2085 void frsqrte(const VRegister& vd, const VRegister& vn);
2086
2087 // FP reciprocal square root step.
2088 void frsqrts(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2089
2090 // Signed absolute difference and accumulate long.
2091 void sabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2092
2093 // Signed absolute difference and accumulate long (second part).
2094 void sabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2095
2096 // Unsigned absolute difference and accumulate long.
2097 void uabal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2098
2099 // Unsigned absolute difference and accumulate long (second part).
2100 void uabal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2101
2102 // Signed absolute difference long.
2103 void sabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2104
2105 // Signed absolute difference long (second part).
2106 void sabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2107
2108 // Unsigned absolute difference long.
2109 void uabdl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2110
2111 // Unsigned absolute difference long (second part).
2112 void uabdl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2113
2114 // Polynomial multiply long.
2115 void pmull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2116
2117 // Polynomial multiply long (second part).
2118 void pmull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2119
2120 // Signed long multiply-add.
2121 void smlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2122
2123 // Signed long multiply-add (second part).
2124 void smlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2125
2126 // Unsigned long multiply-add.
2127 void umlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2128
2129 // Unsigned long multiply-add (second part).
2130 void umlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2131
2132 // Signed long multiply-sub.
2133 void smlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2134
2135 // Signed long multiply-sub (second part).
2136 void smlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2137
2138 // Unsigned long multiply-sub.
2139 void umlsl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2140
2141 // Unsigned long multiply-sub (second part).
2142 void umlsl2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2143
2144 // Signed long multiply.
2145 void smull(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2146
2147 // Signed long multiply (second part).
2148 void smull2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2149
2150 // Signed saturating doubling long multiply-add.
2151 void sqdmlal(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2152
2153 // Signed saturating doubling long multiply-add (second part).
2154 void sqdmlal2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2155
2156 // Unsigned absolute difference.
2157 void uabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2158
2159 // Signed absolute difference and accumulate.
2160 void saba(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2161
2162 // FP instructions.
2163 // Move immediate to FP register.
2164 void fmov(const VRegister& fd, double imm);
2165 void fmov(const VRegister& fd, float imm);
2166
2167 // Move FP register to register.
2168 void fmov(const Register& rd, const VRegister& fn);
2169
2170 // Move register to FP register.
2171 void fmov(const VRegister& fd, const Register& rn);
2172
2173 // Move FP register to FP register.
2174 void fmov(const VRegister& fd, const VRegister& fn);
2175
2176 // Move 64-bit register to top half of 128-bit FP register.
2177 void fmov(const VRegister& vd, int index, const Register& rn);
2178
2179 // Move top half of 128-bit FP register to 64-bit register.
2180 void fmov(const Register& rd, const VRegister& vn, int index);
2181
2182 // FP add.
2183 void fadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2184
2185 // FP subtract.
2186 void fsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2187
2188 // FP multiply.
2189 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2190
2191 // FP compare equal to zero.
2192 void fcmeq(const VRegister& vd, const VRegister& vn, double imm);
2193
2194 // FP greater than zero.
2195 void fcmgt(const VRegister& vd, const VRegister& vn, double imm);
2196
2197 // FP greater than or equal to zero.
2198 void fcmge(const VRegister& vd, const VRegister& vn, double imm);
2199
2200 // FP less than or equal to zero.
2201 void fcmle(const VRegister& vd, const VRegister& vn, double imm);
2202
2203 // FP less than to zero.
2204 void fcmlt(const VRegister& vd, const VRegister& vn, double imm);
2205
2206 // FP absolute difference.
2207 void fabd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2208
2209 // FP pairwise add vector.
2210 void faddp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2211
2212 // FP pairwise add scalar.
2213 void faddp(const VRegister& vd, const VRegister& vn);
2214
2215 // FP pairwise maximum scalar.
2216 void fmaxp(const VRegister& vd, const VRegister& vn);
2217
2218 // FP pairwise maximum number scalar.
2219 void fmaxnmp(const VRegister& vd, const VRegister& vn);
2220
2221 // FP pairwise minimum number scalar.
2222 void fminnmp(const VRegister& vd, const VRegister& vn);
2223
2224 // FP vector multiply accumulate.
2225 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2226
2227 // FP vector multiply subtract.
2228 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2229
2230 // FP vector multiply extended.
2231 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2232
2233 // FP absolute greater than or equal.
2234 void facge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2235
2236 // FP absolute greater than.
2237 void facgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2238
2239 // FP multiply by element.
2240 void fmul(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2241 int vm_index);
2242
2243 // FP fused multiply-add to accumulator by element.
2244 void fmla(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2245 int vm_index);
2246
2247 // FP fused multiply-sub from accumulator by element.
2248 void fmls(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2249 int vm_index);
2250
2251 // FP multiply extended by element.
2252 void fmulx(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2253 int vm_index);
2254
2255 // FP compare equal.
2256 void fcmeq(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2257
2258 // FP greater than.
2259 void fcmgt(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2260
2261 // FP greater than or equal.
2262 void fcmge(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2263
2264 // FP pairwise maximum vector.
2265 void fmaxp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2266
2267 // FP pairwise minimum vector.
2268 void fminp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2269
2270 // FP pairwise minimum scalar.
2271 void fminp(const VRegister& vd, const VRegister& vn);
2272
2273 // FP pairwise maximum number vector.
2274 void fmaxnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2275
2276 // FP pairwise minimum number vector.
2277 void fminnmp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2278
2279 // FP fused multiply-add.
2280 void fmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2281 const VRegister& va);
2282
2283 // FP fused multiply-subtract.
2284 void fmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2285 const VRegister& va);
2286
2287 // FP fused multiply-add and negate.
2288 void fnmadd(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2289 const VRegister& va);
2290
2291 // FP fused multiply-subtract and negate.
2292 void fnmsub(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2293 const VRegister& va);
2294
2295 // FP multiply-negate scalar.
2296 void fnmul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2297
2298 // FP reciprocal exponent scalar.
2299 void frecpx(const VRegister& vd, const VRegister& vn);
2300
2301 // FP divide.
2302 void fdiv(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2303
2304 // FP maximum.
2305 void fmax(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2306
2307 // FP minimum.
2308 void fmin(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2309
2310 // FP maximum.
2311 void fmaxnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2312
2313 // FP minimum.
2314 void fminnm(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2315
2316 // FP absolute.
2317 void fabs(const VRegister& vd, const VRegister& vn);
2318
2319 // FP negate.
2320 void fneg(const VRegister& vd, const VRegister& vn);
2321
2322 // FP square root.
2323 void fsqrt(const VRegister& vd, const VRegister& vn);
2324
2325 // FP round to integer nearest with ties to away.
2326 void frinta(const VRegister& vd, const VRegister& vn);
2327
2328 // FP round to integer, implicit rounding.
2329 void frinti(const VRegister& vd, const VRegister& vn);
2330
2331 // FP round to integer toward minus infinity.
2332 void frintm(const VRegister& vd, const VRegister& vn);
2333
2334 // FP round to integer nearest with ties to even.
2335 void frintn(const VRegister& vd, const VRegister& vn);
2336
2337 // FP round to integer towards plus infinity.
2338 void frintp(const VRegister& vd, const VRegister& vn);
2339
2340 // FP round to integer, exact, implicit rounding.
2341 void frintx(const VRegister& vd, const VRegister& vn);
2342
2343 // FP round to integer towards zero.
2344 void frintz(const VRegister& vd, const VRegister& vn);
2345
2346 // FP compare registers.
2347 void fcmp(const VRegister& vn, const VRegister& vm);
2348
2349 // FP compare immediate.
2350 void fcmp(const VRegister& vn, double value);
2351
2352 // FP conditional compare.
2353 void fccmp(const VRegister& vn, const VRegister& vm, StatusFlags nzcv,
2354 Condition cond);
2355
2356 // FP conditional select.
2357 void fcsel(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2358 Condition cond);
2359
2360 // Common FP Convert functions.
2361 void NEONFPConvertToInt(const Register& rd, const VRegister& vn, Instr op);
2362 void NEONFPConvertToInt(const VRegister& vd, const VRegister& vn, Instr op);
2363
2364 // FP convert between precisions.
2365 void fcvt(const VRegister& vd, const VRegister& vn);
2366
2367 // FP convert to higher precision.
2368 void fcvtl(const VRegister& vd, const VRegister& vn);
2369
2370 // FP convert to higher precision (second part).
2371 void fcvtl2(const VRegister& vd, const VRegister& vn);
2372
2373 // FP convert to lower precision.
2374 void fcvtn(const VRegister& vd, const VRegister& vn);
2375
2376 // FP convert to lower prevision (second part).
2377 void fcvtn2(const VRegister& vd, const VRegister& vn);
2378
2379 // FP convert to lower precision, rounding to odd.
2380 void fcvtxn(const VRegister& vd, const VRegister& vn);
2381
2382 // FP convert to lower precision, rounding to odd (second part).
2383 void fcvtxn2(const VRegister& vd, const VRegister& vn);
2384
2385 // FP convert to signed integer, nearest with ties to away.
2386 void fcvtas(const Register& rd, const VRegister& vn);
2387
2388 // FP convert to unsigned integer, nearest with ties to away.
2389 void fcvtau(const Register& rd, const VRegister& vn);
2390
2391 // FP convert to signed integer, nearest with ties to away.
2392 void fcvtas(const VRegister& vd, const VRegister& vn);
2393
2394 // FP convert to unsigned integer, nearest with ties to away.
2395 void fcvtau(const VRegister& vd, const VRegister& vn);
2396
2397 // FP convert to signed integer, round towards -infinity.
2398 void fcvtms(const Register& rd, const VRegister& vn);
2399
2400 // FP convert to unsigned integer, round towards -infinity.
2401 void fcvtmu(const Register& rd, const VRegister& vn);
2402
2403 // FP convert to signed integer, round towards -infinity.
2404 void fcvtms(const VRegister& vd, const VRegister& vn);
2405
2406 // FP convert to unsigned integer, round towards -infinity.
2407 void fcvtmu(const VRegister& vd, const VRegister& vn);
2408
2409 // FP convert to signed integer, nearest with ties to even.
2410 void fcvtns(const Register& rd, const VRegister& vn);
2411
2412 // FP JavaScript convert to signed integer, rounding toward zero [Armv8.3].
2413 void fjcvtzs(const Register& rd, const VRegister& vn);
2414
2415 // FP convert to unsigned integer, nearest with ties to even.
2416 void fcvtnu(const Register& rd, const VRegister& vn);
2417
2418 // FP convert to signed integer, nearest with ties to even.
2419 void fcvtns(const VRegister& rd, const VRegister& vn);
2420
2421 // FP convert to unsigned integer, nearest with ties to even.
2422 void fcvtnu(const VRegister& rd, const VRegister& vn);
2423
2424 // FP convert to signed integer or fixed-point, round towards zero.
2425 void fcvtzs(const Register& rd, const VRegister& vn, int fbits = 0);
2426
2427 // FP convert to unsigned integer or fixed-point, round towards zero.
2428 void fcvtzu(const Register& rd, const VRegister& vn, int fbits = 0);
2429
2430 // FP convert to signed integer or fixed-point, round towards zero.
2431 void fcvtzs(const VRegister& vd, const VRegister& vn, int fbits = 0);
2432
2433 // FP convert to unsigned integer or fixed-point, round towards zero.
2434 void fcvtzu(const VRegister& vd, const VRegister& vn, int fbits = 0);
2435
2436 // FP convert to signed integer, round towards +infinity.
2437 void fcvtps(const Register& rd, const VRegister& vn);
2438
2439 // FP convert to unsigned integer, round towards +infinity.
2440 void fcvtpu(const Register& rd, const VRegister& vn);
2441
2442 // FP convert to signed integer, round towards +infinity.
2443 void fcvtps(const VRegister& vd, const VRegister& vn);
2444
2445 // FP convert to unsigned integer, round towards +infinity.
2446 void fcvtpu(const VRegister& vd, const VRegister& vn);
2447
2448 // Convert signed integer or fixed point to FP.
2449 void scvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2450
2451 // Convert unsigned integer or fixed point to FP.
2452 void ucvtf(const VRegister& fd, const Register& rn, int fbits = 0);
2453
2454 // Convert signed integer or fixed-point to FP.
2455 void scvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2456
2457 // Convert unsigned integer or fixed-point to FP.
2458 void ucvtf(const VRegister& fd, const VRegister& vn, int fbits = 0);
2459
2460 // Extract vector from pair of vectors.
2461 void ext(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2462 int index);
2463
2464 // Duplicate vector element to vector or scalar.
2465 void dup(const VRegister& vd, const VRegister& vn, int vn_index);
2466
2467 // Duplicate general-purpose register to vector.
2468 void dup(const VRegister& vd, const Register& rn);
2469
2470 // Insert vector element from general-purpose register.
2471 void ins(const VRegister& vd, int vd_index, const Register& rn);
2472
2473 // Move general-purpose register to a vector element.
2474 void mov(const VRegister& vd, int vd_index, const Register& rn);
2475
2476 // Unsigned move vector element to general-purpose register.
2477 void umov(const Register& rd, const VRegister& vn, int vn_index);
2478
2479 // Move vector element to general-purpose register.
2480 void mov(const Register& rd, const VRegister& vn, int vn_index);
2481
2482 // Move vector element to scalar.
2483 void mov(const VRegister& vd, const VRegister& vn, int vn_index);
2484
2485 // Insert vector element from another vector element.
2486 void ins(const VRegister& vd, int vd_index, const VRegister& vn,
2487 int vn_index);
2488
2489 // Move vector element to another vector element.
2490 void mov(const VRegister& vd, int vd_index, const VRegister& vn,
2491 int vn_index);
2492
2493 // Signed move vector element to general-purpose register.
2494 void smov(const Register& rd, const VRegister& vn, int vn_index);
2495
2496 // One-element structure load to one register.
2497 void ld1(const VRegister& vt, const MemOperand& src);
2498
2499 // One-element structure load to two registers.
2500 void ld1(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2501
2502 // One-element structure load to three registers.
2503 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2504 const MemOperand& src);
2505
2506 // One-element structure load to four registers.
2507 void ld1(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2508 const VRegister& vt4, const MemOperand& src);
2509
2510 // One-element single structure load to one lane.
2511 void ld1(const VRegister& vt, int lane, const MemOperand& src);
2512
2513 // One-element single structure load to all lanes.
2514 void ld1r(const VRegister& vt, const MemOperand& src);
2515
2516 // Two-element structure load.
2517 void ld2(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2518
2519 // Two-element single structure load to one lane.
2520 void ld2(const VRegister& vt, const VRegister& vt2, int lane,
2521 const MemOperand& src);
2522
2523 // Two-element single structure load to all lanes.
2524 void ld2r(const VRegister& vt, const VRegister& vt2, const MemOperand& src);
2525
2526 // Three-element structure load.
2527 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2528 const MemOperand& src);
2529
2530 // Three-element single structure load to one lane.
2531 void ld3(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2532 int lane, const MemOperand& src);
2533
2534 // Three-element single structure load to all lanes.
2535 void ld3r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2536 const MemOperand& src);
2537
2538 // Four-element structure load.
2539 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2540 const VRegister& vt4, const MemOperand& src);
2541
2542 // Four-element single structure load to one lane.
2543 void ld4(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2544 const VRegister& vt4, int lane, const MemOperand& src);
2545
2546 // Four-element single structure load to all lanes.
2547 void ld4r(const VRegister& vt, const VRegister& vt2, const VRegister& vt3,
2548 const VRegister& vt4, const MemOperand& src);
2549
2550 // Count leading sign bits.
2551 void cls(const VRegister& vd, const VRegister& vn);
2552
2553 // Count leading zero bits (vector).
2554 void clz(const VRegister& vd, const VRegister& vn);
2555
2556 // Population count per byte.
2557 void cnt(const VRegister& vd, const VRegister& vn);
2558
2559 // Reverse bit order.
2560 void rbit(const VRegister& vd, const VRegister& vn);
2561
2562 // Reverse elements in 16-bit halfwords.
2563 void rev16(const VRegister& vd, const VRegister& vn);
2564
2565 // Reverse elements in 32-bit words.
2566 void rev32(const VRegister& vd, const VRegister& vn);
2567
2568 // Reverse elements in 64-bit doublewords.
2569 void rev64(const VRegister& vd, const VRegister& vn);
2570
2571 // Unsigned reciprocal square root estimate.
2572 void ursqrte(const VRegister& vd, const VRegister& vn);
2573
2574 // Unsigned reciprocal estimate.
2575 void urecpe(const VRegister& vd, const VRegister& vn);
2576
2577 // Signed pairwise long add and accumulate.
2578 void sadalp(const VRegister& vd, const VRegister& vn);
2579
2580 // Signed pairwise long add.
2581 void saddlp(const VRegister& vd, const VRegister& vn);
2582
2583 // Unsigned pairwise long add.
2584 void uaddlp(const VRegister& vd, const VRegister& vn);
2585
2586 // Unsigned pairwise long add and accumulate.
2587 void uadalp(const VRegister& vd, const VRegister& vn);
2588
2589 // Shift left by immediate.
2590 void shl(const VRegister& vd, const VRegister& vn, int shift);
2591
2592 // Signed saturating shift left by immediate.
2593 void sqshl(const VRegister& vd, const VRegister& vn, int shift);
2594
2595 // Signed saturating shift left unsigned by immediate.
2596 void sqshlu(const VRegister& vd, const VRegister& vn, int shift);
2597
2598 // Unsigned saturating shift left by immediate.
2599 void uqshl(const VRegister& vd, const VRegister& vn, int shift);
2600
2601 // Signed shift left long by immediate.
2602 void sshll(const VRegister& vd, const VRegister& vn, int shift);
2603
2604 // Signed shift left long by immediate (second part).
2605 void sshll2(const VRegister& vd, const VRegister& vn, int shift);
2606
2607 // Signed extend long.
2608 void sxtl(const VRegister& vd, const VRegister& vn);
2609
2610 // Signed extend long (second part).
2611 void sxtl2(const VRegister& vd, const VRegister& vn);
2612
2613 // Unsigned shift left long by immediate.
2614 void ushll(const VRegister& vd, const VRegister& vn, int shift);
2615
2616 // Unsigned shift left long by immediate (second part).
2617 void ushll2(const VRegister& vd, const VRegister& vn, int shift);
2618
2619 // Shift left long by element size.
2620 void shll(const VRegister& vd, const VRegister& vn, int shift);
2621
2622 // Shift left long by element size (second part).
2623 void shll2(const VRegister& vd, const VRegister& vn, int shift);
2624
2625 // Unsigned extend long.
2626 void uxtl(const VRegister& vd, const VRegister& vn);
2627
2628 // Unsigned extend long (second part).
2629 void uxtl2(const VRegister& vd, const VRegister& vn);
2630
2631 // Signed rounding halving add.
2632 void srhadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2633
2634 // Unsigned halving sub.
2635 void uhsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2636
2637 // Signed halving sub.
2638 void shsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2639
2640 // Unsigned saturating add.
2641 void uqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2642
2643 // Signed saturating add.
2644 void sqadd(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2645
2646 // Unsigned saturating subtract.
2647 void uqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2648
2649 // Signed saturating subtract.
2650 void sqsub(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2651
2652 // Add pairwise.
2653 void addp(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2654
2655 // Add pair of elements scalar.
2656 void addp(const VRegister& vd, const VRegister& vn);
2657
2658 // Multiply-add to accumulator.
2659 void mla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2660
2661 // Multiply-subtract to accumulator.
2662 void mls(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2663
2664 // Multiply.
2665 void mul(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2666
2667 // Table lookup from one register.
2668 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2669
2670 // Table lookup from two registers.
2671 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2672 const VRegister& vm);
2673
2674 // Table lookup from three registers.
2675 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2676 const VRegister& vn3, const VRegister& vm);
2677
2678 // Table lookup from four registers.
2679 void tbl(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2680 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
2681
2682 // Table lookup extension from one register.
2683 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vm);
2684
2685 // Table lookup extension from two registers.
2686 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2687 const VRegister& vm);
2688
2689 // Table lookup extension from three registers.
2690 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2691 const VRegister& vn3, const VRegister& vm);
2692
2693 // Table lookup extension from four registers.
2694 void tbx(const VRegister& vd, const VRegister& vn, const VRegister& vn2,
2695 const VRegister& vn3, const VRegister& vn4, const VRegister& vm);
2696
2697 // Instruction functions used only for test, debug, and patching.
2698 // Emit raw instructions in the instruction stream.
2699 void dci(Instr raw_inst) { Emit(raw_inst); }
2700
2701 // Emit 8 bits of data in the instruction stream.
2702 void dc8(uint8_t data) { EmitData(&data, sizeof(data)); }
2703
2704 // Emit 32 bits of data in the instruction stream.
2705 void dc32(uint32_t data) { EmitData(&data, sizeof(data)); }
2706
2707 // Emit 64 bits of data in the instruction stream.
2708 void dc64(uint64_t data) { EmitData(&data, sizeof(data)); }
2709
2710 // Emit an address in the instruction stream.
2712
2713 // SHA3 instructions
2714 // Bit Clear and exclusive-OR.
2715 void bcax(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2716 const VRegister& va);
2717
2718 // Three-way Exclusive-OR.
2719 void eor3(const VRegister& vd, const VRegister& vn, const VRegister& vm,
2720 const VRegister& va);
2721
2722 // Copy a string into the instruction stream, including the terminating
2723 // nullptr character. The instruction pointer (pc_) is then aligned correctly
2724 // for subsequent instructions.
2725 void EmitStringData(const char* string);
2726
2727 // Pseudo-instructions ------------------------------------------------------
2728
2729 // Parameters are described in arm64/instructions-arm64.h.
2730 void debug(const char* message, uint32_t code, Instr params = BREAK);
2731
2732 // Required by V8.
2733 void db(uint8_t data) { dc8(data); }
2734 void dd(uint32_t data) {
2735 BlockPoolsScope no_pool_scope(this);
2736 dc32(data);
2737 }
2738 void dq(uint64_t data) {
2739 BlockPoolsScope no_pool_scope(this);
2740 dc64(data);
2741 }
2742 void dp(uintptr_t data) {
2743 BlockPoolsScope no_pool_scope(this);
2744 dc64(data);
2745 }
2746
2747 // InstructionStream generation helpers
2748 // --------------------------------------------------
2749
2750 Instruction* pc() const { return Instruction::Cast(pc_); }
2751
2753 return reinterpret_cast<Instruction*>(buffer_start_ + offset);
2754 }
2755
2757 return reinterpret_cast<uint8_t*>(instr) - buffer_start_;
2758 }
2759
2760 // Register encoding.
2761 static Instr Rd(CPURegister rd) {
2763 return rd.code() << Rd_offset;
2764 }
2765
2766 static Instr Rn(CPURegister rn) {
2768 return rn.code() << Rn_offset;
2769 }
2770
2771 static Instr Rm(CPURegister rm) {
2773 return rm.code() << Rm_offset;
2774 }
2775
2778 DCHECK(!rm.IsZero());
2779 return Rm(rm);
2780 }
2781
2782 static Instr Ra(CPURegister ra) {
2784 return ra.code() << Ra_offset;
2785 }
2786
2787 static Instr Rt(CPURegister rt) {
2789 return rt.code() << Rt_offset;
2790 }
2791
2792 static Instr Rt2(CPURegister rt2) {
2794 return rt2.code() << Rt2_offset;
2795 }
2796
2797 static Instr Rs(CPURegister rs) {
2799 return rs.code() << Rs_offset;
2800 }
2801
2802 // These encoding functions allow the stack pointer to be encoded, and
2803 // disallow the zero register.
2804 static Instr RdSP(Register rd) {
2805 DCHECK(!rd.IsZero());
2806 return (rd.code() & kRegCodeMask) << Rd_offset;
2807 }
2808
2809 static Instr RnSP(Register rn) {
2810 DCHECK(!rn.IsZero());
2811 return (rn.code() & kRegCodeMask) << Rn_offset;
2812 }
2813
2814 // Flags encoding.
2815 inline static Instr Flags(FlagsUpdate S);
2816 inline static Instr Cond(Condition cond);
2817
2818 // PC-relative address encoding.
2819 inline static Instr ImmPCRelAddress(int imm21);
2820
2821 // Branch encoding.
2822 inline static Instr ImmUncondBranch(int imm26);
2823 inline static Instr ImmCondBranch(int imm19);
2824 inline static Instr ImmCmpBranch(int imm19);
2825 inline static Instr ImmTestBranch(int imm14);
2826 inline static Instr ImmTestBranchBit(unsigned bit_pos);
2827
2828 // Data Processing encoding.
2829 inline static Instr SF(Register rd);
2830 inline static Instr ImmAddSub(int imm);
2831 inline static Instr ImmS(unsigned imms, unsigned reg_size);
2832 inline static Instr ImmR(unsigned immr, unsigned reg_size);
2833 inline static Instr ImmSetBits(unsigned imms, unsigned reg_size);
2834 inline static Instr ImmRotate(unsigned immr, unsigned reg_size);
2835 inline static Instr ImmLLiteral(int imm19);
2836 inline static Instr BitN(unsigned bitn, unsigned reg_size);
2837 inline static Instr ShiftDP(Shift shift);
2838 inline static Instr ImmDPShift(unsigned amount);
2839 inline static Instr ExtendMode(Extend extend);
2840 inline static Instr ImmExtendShift(unsigned left_shift);
2841 inline static Instr ImmCondCmp(unsigned imm);
2842 inline static Instr Nzcv(StatusFlags nzcv);
2843
2844 static constexpr bool IsImmAddSub(int64_t immediate) {
2845 return is_uint12(immediate) ||
2846 (is_uint12(immediate >> 12) && ((immediate & 0xFFF) == 0));
2847 }
2848
2849 static constexpr bool IsImmConditionalCompare(int64_t immediate) {
2850 return is_uint5(immediate);
2851 }
2852
2853 static bool IsImmLogical(uint64_t value, unsigned width, unsigned* n,
2854 unsigned* imm_s, unsigned* imm_r);
2855
2856 // MemOperand offset encoding.
2857 inline static Instr ImmLSUnsigned(int imm12);
2858 inline static Instr ImmLS(int imm9);
2859 inline static Instr ImmLSPair(int imm7, unsigned size);
2860 inline static Instr ImmShiftLS(unsigned shift_amount);
2861 inline static Instr ImmException(int imm16);
2862 inline static Instr ImmSystemRegister(int imm15);
2863 inline static Instr ImmHint(int imm7);
2864 inline static Instr ImmBarrierDomain(int imm2);
2865 inline static Instr ImmBarrierType(int imm2);
2866 inline static unsigned CalcLSDataSizeLog2(LoadStoreOp op);
2867
2868 // Instruction bits for vector format in data processing operations.
2870 if (vd.Is64Bits()) {
2871 switch (vd.LaneCount()) {
2872 case 1:
2873 return NEON_1D;
2874 case 2:
2875 return NEON_2S;
2876 case 4:
2877 return NEON_4H;
2878 case 8:
2879 return NEON_8B;
2880 default:
2881 UNREACHABLE();
2882 }
2883 } else {
2884 DCHECK(vd.Is128Bits());
2885 switch (vd.LaneCount()) {
2886 case 2:
2887 return NEON_2D;
2888 case 4:
2889 return NEON_4S;
2890 case 8:
2891 return NEON_8H;
2892 case 16:
2893 return NEON_16B;
2894 default:
2895 UNREACHABLE();
2896 }
2897 }
2898 }
2899
2900 // Instruction bits for vector format in floating point data processing
2901 // operations.
2903 if (vd.LaneCount() == 1) {
2904 // Floating point scalar formats.
2905 DCHECK(vd.Is32Bits() || vd.Is64Bits());
2906 return vd.Is64Bits() ? FP64 : FP32;
2907 }
2908
2909 // Two lane floating point vector formats.
2910 if (vd.LaneCount() == 2) {
2911 DCHECK(vd.Is64Bits() || vd.Is128Bits());
2912 return vd.Is128Bits() ? NEON_FP_2D : NEON_FP_2S;
2913 }
2914
2915 // Four lane floating point vector formats.
2916 if (vd.LaneCount() == 4) {
2917 DCHECK(vd.Is64Bits() || vd.Is128Bits());
2918 return vd.Is128Bits() ? NEON_FP_4S : NEON_FP_4H;
2919 }
2920
2921 // Eight lane floating point vector format.
2922 DCHECK((vd.LaneCount() == 8) && vd.Is128Bits());
2923 return NEON_FP_8H;
2924 }
2925
2926 // Instruction bits for vector format in load and store operations.
2928 if (vd.Is64Bits()) {
2929 switch (vd.LaneCount()) {
2930 case 1:
2931 return LS_NEON_1D;
2932 case 2:
2933 return LS_NEON_2S;
2934 case 4:
2935 return LS_NEON_4H;
2936 case 8:
2937 return LS_NEON_8B;
2938 default:
2939 UNREACHABLE();
2940 }
2941 } else {
2942 DCHECK(vd.Is128Bits());
2943 switch (vd.LaneCount()) {
2944 case 2:
2945 return LS_NEON_2D;
2946 case 4:
2947 return LS_NEON_4S;
2948 case 8:
2949 return LS_NEON_8H;
2950 case 16:
2951 return LS_NEON_16B;
2952 default:
2953 UNREACHABLE();
2954 }
2955 }
2956 }
2957
2958 // Instruction bits for scalar format in data processing operations.
2960 DCHECK(vd.IsScalar());
2961 switch (vd.SizeInBytes()) {
2962 case 1:
2963 return NEON_B;
2964 case 2:
2965 return NEON_H;
2966 case 4:
2967 return NEON_S;
2968 case 8:
2969 return NEON_D;
2970 default:
2971 UNREACHABLE();
2972 }
2973 }
2974
2975 static Instr ImmNEONHLM(int index, int num_bits) {
2976 int h, l, m;
2977 if (num_bits == 3) {
2978 DCHECK(is_uint3(index));
2979 h = (index >> 2) & 1;
2980 l = (index >> 1) & 1;
2981 m = (index >> 0) & 1;
2982 } else if (num_bits == 2) {
2983 DCHECK(is_uint2(index));
2984 h = (index >> 1) & 1;
2985 l = (index >> 0) & 1;
2986 m = 0;
2987 } else {
2988 DCHECK(is_uint1(index) && (num_bits == 1));
2989 h = (index >> 0) & 1;
2990 l = 0;
2991 m = 0;
2992 }
2993 return (h << NEONH_offset) | (l << NEONL_offset) | (m << NEONM_offset);
2994 }
2995
2996 static Instr ImmNEONExt(int imm4) {
2997 DCHECK(is_uint4(imm4));
2998 return imm4 << ImmNEONExt_offset;
2999 }
3000
3001 static Instr ImmNEON5(Instr format, int index) {
3002 DCHECK(is_uint4(index));
3003 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3004 int imm5 = (index << (s + 1)) | (1 << s);
3005 return imm5 << ImmNEON5_offset;
3006 }
3007
3008 static Instr ImmNEON4(Instr format, int index) {
3009 DCHECK(is_uint4(index));
3010 int s = LaneSizeInBytesLog2FromFormat(static_cast<VectorFormat>(format));
3011 int imm4 = index << s;
3012 return imm4 << ImmNEON4_offset;
3013 }
3014
3015 static Instr ImmNEONabcdefgh(int imm8) {
3016 DCHECK(is_uint8(imm8));
3017 Instr instr;
3018 instr = ((imm8 >> 5) & 7) << ImmNEONabc_offset;
3019 instr |= (imm8 & 0x1f) << ImmNEONdefgh_offset;
3020 return instr;
3021 }
3022
3023 static Instr NEONCmode(int cmode) {
3024 DCHECK(is_uint4(cmode));
3025 return cmode << NEONCmode_offset;
3026 }
3027
3028 static Instr NEONModImmOp(int op) {
3029 DCHECK(is_uint1(op));
3030 return op << NEONModImmOp_offset;
3031 }
3032
3033 static constexpr bool IsImmLSUnscaled(int64_t offset) {
3034 return is_int9(offset);
3035 }
3036 static constexpr bool IsImmLSScaled(int64_t offset, unsigned size_log2) {
3037 bool offset_is_size_multiple =
3038 (static_cast<int64_t>(static_cast<uint64_t>(offset >> size_log2)
3039 << size_log2) == offset);
3040 return offset_is_size_multiple && is_uint12(offset >> size_log2);
3041 }
3042 static bool IsImmLLiteral(int64_t offset);
3043
3044 // Move immediates encoding.
3045 inline static Instr ImmMoveWide(int imm);
3046 inline static Instr ShiftMoveWide(int shift);
3047
3048 // FP Immediates.
3049 static Instr ImmFP(double imm);
3050 static Instr ImmNEONFP(double imm);
3051 inline static Instr FPScale(unsigned scale);
3052
3053 // FP register type.
3054 inline static Instr FPType(VRegister fd);
3055
3056 // Unused on this architecture.
3058
3060 constpool_.Check(Emission::kForced, Jump::kOmitted);
3061 }
3063 constpool_.Check(Emission::kForced, Jump::kRequired);
3064 }
3065 // Check if the const pool needs to be emitted while pretending that {margin}
3066 // more bytes of instructions have already been emitted.
3067 void EmitConstPoolWithJumpIfNeeded(size_t margin = 0) {
3068 if (constpool_.IsEmpty()) return;
3069 constpool_.Check(Emission::kIfNeeded, Jump::kRequired, margin);
3070 }
3071
3072 // Used by veneer checks below - returns the max (= overapproximated) pc
3073 // offset after the veneer pool, if the veneer pool were to be emitted
3074 // immediately.
3076 // Returns true if we should emit a veneer as soon as possible for a branch
3077 // which can at most reach to specified pc.
3078 bool ShouldEmitVeneer(int max_reachable_pc, size_t margin) {
3079 return max_reachable_pc < MaxPCOffsetAfterVeneerPoolIfEmittedNow(margin);
3080 }
3081 bool ShouldEmitVeneers(size_t margin = kVeneerDistanceMargin) {
3082 return ShouldEmitVeneer(unresolved_branches_first_limit(), margin);
3083 }
3084
3085 // The code size generated for a veneer. Currently one branch
3086 // instruction. This is for code size checking purposes, and can be extended
3087 // in the future for example if we decide to add nops between the veneers.
3088 static constexpr int kVeneerCodeSize = 1 * kInstrSize;
3089
3090 void RecordVeneerPool(int location_offset, int size);
3091 // Emits veneers for branches that are approaching their maximum range.
3092 // If need_protection is true, the veneers are protected by a branch jumping
3093 // over the code.
3094 void EmitVeneers(bool force_emit, bool need_protection,
3095 size_t margin = kVeneerDistanceMargin);
3096 void EmitVeneersGuard() { EmitPoolGuard(); }
3097 // Checks whether veneers need to be emitted at this point.
3098 // If force_emit is set, a veneer is generated for *all* unresolved branches.
3099 void CheckVeneerPool(bool force_emit, bool require_jump,
3100 size_t margin = kVeneerDistanceMargin);
3101
3102 using BlockConstPoolScope = ConstantPool::BlockScope;
3103
3105 public:
3106 // Block veneer and constant pool. Emits pools if necessary to ensure that
3107 // {margin} more bytes can be emitted without triggering pool emission.
3108 explicit BlockPoolsScope(Assembler* assem, size_t margin = 0)
3109 : assem_(assem), block_const_pool_(assem, margin) {
3110 assem_->CheckVeneerPool(false, true, margin);
3111 assem_->StartBlockVeneerPool();
3112 }
3113
3114 BlockPoolsScope(Assembler* assem, PoolEmissionCheck check)
3115 : assem_(assem), block_const_pool_(assem, check) {
3116 assem_->StartBlockVeneerPool();
3117 }
3118 ~BlockPoolsScope() { assem_->EndBlockVeneerPool(); }
3119
3120 private:
3124 };
3125
3126#if defined(V8_OS_WIN)
3127 win64_unwindinfo::XdataEncoder* GetXdataEncoder() {
3128 return xdata_encoder_.get();
3129 }
3130
3131 win64_unwindinfo::BuiltinUnwindInfo GetUnwindInfo() const;
3132#endif
3133
3134 protected:
3135 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const;
3136
3137 void LoadStore(const CPURegister& rt, const MemOperand& addr, LoadStoreOp op);
3138 inline void LoadStoreScaledImmOffset(Instr memop, int offset, unsigned size);
3139 inline void LoadStoreUnscaledImmOffset(Instr memop, int offset);
3140 inline void LoadStoreWRegOffset(Instr memop, const Register& regoffset);
3141 void LoadStorePair(const CPURegister& rt, const CPURegister& rt2,
3142 const MemOperand& addr, LoadStorePairOp op);
3143 void LoadStoreStruct(const VRegister& vt, const MemOperand& addr,
3145 void LoadStoreStruct1(const VRegister& vt, int reg_count,
3146 const MemOperand& addr);
3147 void LoadStoreStructSingle(const VRegister& vt, uint32_t lane,
3148 const MemOperand& addr,
3151 const MemOperand& addr,
3153 void LoadStoreStructVerify(const VRegister& vt, const MemOperand& addr,
3154 Instr op);
3155
3156 static bool IsImmLSPair(int64_t offset, unsigned size);
3157
3158 void Logical(const Register& rd, const Register& rn, const Operand& operand,
3159 LogicalOp op);
3160 void LogicalImmediate(const Register& rd, const Register& rn, unsigned n,
3161 unsigned imm_s, unsigned imm_r, LogicalOp op);
3162
3163 void ConditionalCompare(const Register& rn, const Operand& operand,
3164 StatusFlags nzcv, Condition cond,
3166
3167 void AddSubWithCarry(const Register& rd, const Register& rn,
3168 const Operand& operand, FlagsUpdate S,
3170
3171 // Functions for emulating operands not directly supported by the instruction
3172 // set.
3173 void EmitShift(const Register& rd, const Register& rn, Shift shift,
3174 unsigned amount);
3175 void EmitExtendShift(const Register& rd, const Register& rn, Extend extend,
3176 unsigned left_shift);
3177
3178 void AddSub(const Register& rd, const Register& rn, const Operand& operand,
3179 FlagsUpdate S, AddSubOp op);
3180
3181 inline void DataProcPlainRegister(const Register& rd, const Register& rn,
3182 const Register& rm, Instr op);
3183 inline void CmpPlainRegister(const Register& rn, const Register& rm);
3184 inline void DataProcImmediate(const Register& rd, const Register& rn,
3185 int immediate, Instr op);
3186
3187 static bool IsImmFP32(uint32_t bits);
3188 static bool IsImmFP64(uint64_t bits);
3189
3190 // Find an appropriate LoadStoreOp or LoadStorePairOp for the specified
3191 // registers. Only simple loads are supported; sign- and zero-extension (such
3192 // as in LDPSW_x or LDRB_w) are not supported.
3193 static inline LoadStoreOp LoadOpFor(const CPURegister& rt);
3194 static inline LoadStorePairOp LoadPairOpFor(const CPURegister& rt,
3195 const CPURegister& rt2);
3196 static inline LoadStoreOp StoreOpFor(const CPURegister& rt);
3197 static inline LoadStorePairOp StorePairOpFor(const CPURegister& rt,
3198 const CPURegister& rt2);
3199 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt);
3200
3201 // Remove the specified branch from the unbound label link chain.
3202 // If available, a veneer for this label can be used for other branches in the
3203 // chain if the link chain cannot be fixed up without this branch.
3205 Instruction* label_veneer = nullptr);
3206
3207 private:
3208 static uint32_t FPToImm8(double imm);
3209
3210 // Instruction helpers.
3211 void MoveWide(const Register& rd, uint64_t imm, int shift,
3212 MoveWideImmediateOp mov_op);
3213 void DataProcShiftedRegister(const Register& rd, const Register& rn,
3214 const Operand& operand, FlagsUpdate S, Instr op);
3215 void DataProcExtendedRegister(const Register& rd, const Register& rn,
3216 const Operand& operand, FlagsUpdate S,
3217 Instr op);
3218 void ConditionalSelect(const Register& rd, const Register& rn,
3219 const Register& rm, Condition cond,
3221 void DataProcessing1Source(const Register& rd, const Register& rn,
3223 void DataProcessing3Source(const Register& rd, const Register& rn,
3224 const Register& rm, const Register& ra,
3229 const VRegister& fm,
3232 const VRegister& fm, const VRegister& fa,
3234 void NEONAcrossLanesL(const VRegister& vd, const VRegister& vn,
3236 void NEONAcrossLanes(const VRegister& vd, const VRegister& vn,
3238 void NEONModifiedImmShiftLsl(const VRegister& vd, const int imm8,
3239 const int left_shift,
3241 void NEONModifiedImmShiftMsl(const VRegister& vd, const int imm8,
3242 const int shift_amount,
3244 void NEON3Same(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3245 NEON3SameOp vop);
3246 void NEONFP3Same(const VRegister& vd, const VRegister& vn,
3247 const VRegister& vm, Instr op);
3248 void NEON3DifferentL(const VRegister& vd, const VRegister& vn,
3249 const VRegister& vm, NEON3DifferentOp vop);
3250 void NEON3DifferentW(const VRegister& vd, const VRegister& vn,
3251 const VRegister& vm, NEON3DifferentOp vop);
3252 void NEON3DifferentHN(const VRegister& vd, const VRegister& vn,
3253 const VRegister& vm, NEON3DifferentOp vop);
3254 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn,
3255 NEON2RegMiscOp vop, double value);
3256 void NEON2RegMisc(const VRegister& vd, const VRegister& vn,
3257 NEON2RegMiscOp vop, int value = 0);
3258 void NEONFP2RegMisc(const VRegister& vd, const VRegister& vn, Instr op);
3259 void NEONAddlp(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp op);
3260 void NEONPerm(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3261 NEONPermOp op);
3262 void NEONFPByElement(const VRegister& vd, const VRegister& vn,
3263 const VRegister& vm, int vm_index,
3265 void NEONByElement(const VRegister& vd, const VRegister& vn,
3266 const VRegister& vm, int vm_index,
3268 void NEONByElementL(const VRegister& vd, const VRegister& vn,
3269 const VRegister& vm, int vm_index,
3271 void NEONShiftImmediate(const VRegister& vd, const VRegister& vn,
3272 NEONShiftImmediateOp op, int immh_immb);
3273 void NEONShiftLeftImmediate(const VRegister& vd, const VRegister& vn,
3274 int shift, NEONShiftImmediateOp op);
3276 int shift, NEONShiftImmediateOp op);
3277 void NEONShiftImmediateL(const VRegister& vd, const VRegister& vn, int shift,
3279 void NEONShiftImmediateN(const VRegister& vd, const VRegister& vn, int shift,
3281 void NEONXtn(const VRegister& vd, const VRegister& vn, NEON2RegMiscOp vop);
3282 void NEONTable(const VRegister& vd, const VRegister& vn, const VRegister& vm,
3283 NEONTableOp op);
3284
3286
3287 // Label helpers.
3288
3289 // Return an offset for a label-referencing instruction, typically a branch.
3291
3292 // This is the same as LinkAndGetByteOffsetTo, but return an offset
3293 // suitable for fields that take instruction offsets: branches.
3294 inline int LinkAndGetBranchInstructionOffsetTo(Label* label);
3295
3296 static constexpr int kStartOfLabelLinkChain = 0;
3297
3298 // Verify that a label's link chain is intact.
3300
3301 // Emit the instruction at pc_.
3302 void Emit(Instr instruction) {
3303 static_assert(sizeof(*pc_) == 1);
3304 static_assert(sizeof(instruction) == kInstrSize);
3305 DCHECK_LE(pc_ + sizeof(instruction), buffer_start_ + buffer_->size());
3306
3307 memcpy(pc_, &instruction, sizeof(instruction));
3308 pc_ += sizeof(instruction);
3309 CheckBuffer();
3310 }
3311
3312 // Emit data inline in the instruction stream.
3313 void EmitData(void const* data, unsigned size) {
3314 DCHECK_EQ(sizeof(*pc_), 1);
3315 DCHECK_LE(pc_ + size, buffer_start_ + buffer_->size());
3316
3317 // TODO(all): Somehow register we have some data here. Then we can
3318 // disassemble it correctly.
3319 memcpy(pc_, data, size);
3320 pc_ += size;
3321 CheckBuffer();
3322 }
3323
3325
3327 DCHECK_LT(pc_, buffer_start_ + buffer_->size());
3328 if (V8_UNLIKELY(buffer_space() < kGap)) {
3329 GrowBuffer();
3330 }
3331 }
3332
3334 CheckBufferSpace();
3335 if (pc_offset() >= next_veneer_pool_check_) {
3336 CheckVeneerPool(false, true);
3337 }
3338 constpool_.MaybeCheck();
3339 }
3340
3341 // Emission of the veneer pools may be blocked in some code sequences.
3342 int veneer_pool_blocked_nesting_ = 0; // Block emission if this is not zero.
3343
3344 // Relocation info generation
3345 // Each relocation is encoded as a variable size value
3346 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
3347 RelocInfoWriter reloc_info_writer;
3348
3349 // Internal reference positions, required for (potential) patching in
3350 // GrowBuffer(); contains only those internal references whose labels
3351 // are already bound.
3353
3354 protected:
3355 // InstructionStream generation
3356 // The relocation writer's position is at least kGap bytes below the end of
3357 // the generated instructions. This is so that multi-instruction sequences do
3358 // not have to check for overflow. The same is true for writes of large
3359 // relocation info entries, and debug strings encoded in the instruction
3360 // stream.
3361 static constexpr int kGap = 64;
3362 static_assert(AssemblerBase::kMinimalBufferSize >= 2 * kGap);
3363
3364 public:
3365#ifdef DEBUG
3366 // Functions used for testing.
3367 size_t GetConstantPoolEntriesSizeForTesting() const {
3368 // Do not include branch over the pool.
3369 return constpool_.Entry32Count() * kInt32Size +
3370 constpool_.Entry64Count() * kInt64Size;
3371 }
3372
3373 static size_t GetCheckConstPoolIntervalForTesting() {
3374 return ConstantPool::kCheckInterval;
3375 }
3376
3377 static size_t GetApproxMaxDistToConstPoolForTesting() {
3378 return ConstantPool::kApproxDistToPool64;
3379 }
3380#endif
3381
3382 protected:
3384
3385 // Information about unresolved (forward) branches.
3386 // The Assembler is only allowed to delete out-of-date information from here
3387 // after a label is bound. The MacroAssembler uses this information to
3388 // generate veneers.
3389 //
3390 // The first member of the pair (max_pc) is the maximum offset that the branch
3391 // can reach in the buffer, with the bottom bit set to indicate a
3392 // test-and-branch instruction. This bit is used to help in calculating the
3393 // address of the branch, ie.
3394 //
3395 // branch_addr = { max_pc - 2^21, if max_pc<0> == 0 (B.cond, CB[N]Z)
3396 // { max_pc - 2^16 - 1, if max_pc<0> == 1 (TB[N]Z)
3397 //
3398 // The second member is a pointer to the Label targetted by the branch.
3399 //
3400 // The map is sorted according to the reachable offset, max_pc, allowing to
3401 // check easily when veneers need to be emitted.
3402 // Note that the maximum reachable offset (first member of the pairs) should
3403 // always be positive but has the same type as the return value for
3404 // pc_offset() for convenience.
3406
3407 // Back edge offsets for the link chain - the forward edge is stored in the
3408 // generated code. This is used to accelerate removing branches from the
3409 // link chain when emitting veneers.
3410 absl::flat_hash_map<int, int> branch_link_chain_back_edge_;
3411
3412 // We generate a veneer for a branch if we reach within this distance of the
3413 // limit of the range.
3414 static constexpr int kVeneerDistanceMargin = 1 * KB;
3415 // The factor of 2 is a finger in the air guess. With a default margin of
3416 // 1KB, that leaves us an addional 256 instructions to avoid generating a
3417 // protective branch.
3418 static constexpr int kVeneerNoProtectionFactor = 2;
3419 static constexpr int kVeneerDistanceCheckMargin =
3420 kVeneerNoProtectionFactor * kVeneerDistanceMargin;
3422 DCHECK(!unresolved_branches_.empty());
3423
3424 // Mask branch type tag bit.
3425 return unresolved_branches_.begin()->first & ~1;
3426 }
3427
3428 // This PC-offset of the next veneer pool check helps reduce the overhead
3429 // of checking for veneer pools.
3430 // It is maintained to the closest unresolved branch limit minus the maximum
3431 // veneer margin (or kMaxInt if there are no unresolved branches).
3433
3434#if defined(V8_OS_WIN)
3435 std::unique_ptr<win64_unwindinfo::XdataEncoder> xdata_encoder_;
3436#endif
3437
3438 private:
3439 // Avoid overflows for displacements etc.
3440 static const int kMaximalBufferSize = 512 * MB;
3441
3442 // If a veneer is emitted for a branch instruction, that instruction must be
3443 // removed from the associated label's link chain so that the assembler does
3444 // not later attempt (likely unsuccessfully) to patch it to branch directly to
3445 // the label.
3447 // This function deletes the information related to the label by traversing
3448 // the label chain, and for each PC-relative instruction in the chain checking
3449 // if pending unresolved information exists. Its complexity is proportional to
3450 // the length of the label chain.
3452
3454
3456
3457 // The pending constant pool.
3458 ConstantPool constpool_;
3459
3460 friend class EnsureSpace;
3461 friend class ConstantPool;
3462};
3463
3464class PatchingAssembler : public Assembler {
3465 public:
3466 // Create an Assembler with a buffer starting at 'start'.
3467 // The buffer size is
3468 // size of instructions to patch + kGap
3469 // Where kGap is the distance from which the Assembler tries to grow the
3470 // buffer.
3471 // If more or fewer instructions than expected are generated or if some
3472 // relocation information takes space in the buffer, the PatchingAssembler
3473 // will crash trying to grow the buffer.
3474 // Note that the instruction cache will not be flushed.
3476 unsigned count)
3477 : Assembler(zone, options,
3480
3482 // Verify we have generated the number of instruction we expected.
3483 DCHECK_EQ(pc_offset() + kGap, buffer_->size());
3484 }
3485
3486 // See definition of PatchAdrFar() for details.
3487 static constexpr int kAdrFarPatchableNNops = 2;
3489 void PatchAdrFar(int64_t target_offset);
3490 void PatchSubSp(uint32_t immediate);
3491
3492 private:
3494};
3495
3496class EnsureSpace {
3497 public:
3498 explicit V8_INLINE EnsureSpace(Assembler* assembler);
3499
3500 private:
3502};
3503
3504} // namespace internal
3505} // namespace v8
3506
3507#endif // V8_CODEGEN_ARM64_ASSEMBLER_ARM64_H_
#define BREAK
interpreter::OperandScale scale
Definition builtins.cc:44
std::unique_ptr< AssemblerBuffer > buffer_
Definition assembler.h:504
std::optional< Zone > maybe_local_zone_
AssemblerZone(const MaybeAssemblerZone &zone)
BlockPoolsScope(Assembler *assem, size_t margin=0)
BlockPoolsScope(Assembler *assem, PoolEmissionCheck check)
void ldumina(const Register &rs, const Register &rt, const MemOperand &src)
void smax(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void uxtb(const Register &rd, const Register &rn)
void ssra(const VRegister &vd, const VRegister &vn, int shift)
void NEONAddlp(const VRegister &vd, const VRegister &vn, NEON2RegMiscOp op)
void stsetlb(const Register &rs, const MemOperand &src)
void ldeoral(const Register &rs, const Register &rt, const MemOperand &src)
static bool IsImmFP32(uint32_t bits)
void LogicalImmediate(const Register &rd, const Register &rn, unsigned n, unsigned imm_s, unsigned imm_r, LogicalOp op)
void lsr(const Register &rd, const Register &rn, int shift)
void ldsminl(const Register &rs, const Register &rt, const MemOperand &src)
void shsub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void uaba(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void uqshrn(const VRegister &vd, const VRegister &vn, int shift)
void staddlb(const Register &rs, const MemOperand &src)
void ldclralh(const Register &rs, const Register &rt, const MemOperand &src)
void sbcs(const Register &rd, const Register &rn, const Operand &operand)
void fcvtms(const VRegister &vd, const VRegister &vn)
void rev32(const Register &rd, const Register &rn)
static Instr RnSP(Register rn)
void smlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void lduminlh(const Register &rs, const Register &rt, const MemOperand &src)
void steorb(const Register &rs, const MemOperand &src)
void fcvtnu(const Register &rd, const VRegister &vn)
void fmaxp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldsmaxal(const Register &rs, const Register &rt, const MemOperand &src)
uint64_t InstructionsGeneratedSince(const Label *label)
void mvni(const VRegister &vd, const int imm8, Shift shift=LSL, const int shift_amount=0)
void uadalp(const VRegister &vd, const VRegister &vn)
void frinti(const VRegister &vd, const VRegister &vn)
intptr_t MaxPCOffsetAfterVeneerPoolIfEmittedNow(size_t margin)
void steorlh(const Register &rs, const MemOperand &src)
void GetCode(LocalIsolate *isolate, CodeDesc *desc)
void swpah(const Register &rs, const Register &rt, const MemOperand &src)
void ssubl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
const AssemblerZone zone_
void cset(const Register &rd, Condition cond)
void umaddl(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void rshrn2(const VRegister &vd, const VRegister &vn, int shift)
void mul(const Register &rd, const Register &rn, const Register &rm)
void stsminh(const Register &rs, const MemOperand &src)
void fmov(const VRegister &fd, const Register &rn)
static Instr NEONCmode(int cmode)
static Instr RdSP(Register rd)
void uqxtn(const VRegister &vd, const VRegister &vn)
void ldumaxalb(const Register &rs, const Register &rt, const MemOperand &src)
void fcmle(const VRegister &vd, const VRegister &vn, double imm)
void fcvtzs(const Register &rd, const VRegister &vn, int fbits=0)
void casah(const Register &rs, const Register &rt, const MemOperand &src)
void ldaddalh(const Register &rs, const Register &rt, const MemOperand &src)
void uabal2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void dup(const VRegister &vd, const VRegister &vn, int vn_index)
void ldsetb(const Register &rs, const Register &rt, const MemOperand &src)
void LoadStoreStructSingleAllLanes(const VRegister &vt, const MemOperand &addr, NEONLoadStoreSingleStructOp op)
void uhsub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void NEONPerm(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEONPermOp op)
void lduminalb(const Register &rs, const Register &rt, const MemOperand &src)
void sxtl(const VRegister &vd, const VRegister &vn)
void ldclrb(const Register &rs, const Register &rt, const MemOperand &src)
void casal(const Register &rs, const Register &rt, const MemOperand &src)
void zip1(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void staddb(const Register &rs, const MemOperand &src)
void bif(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldeorlh(const Register &rs, const Register &rt, const MemOperand &src)
void umov(const Register &rd, const VRegister &vn, int vn_index)
static constexpr bool IsImmLSScaled(int64_t offset, unsigned size_log2)
static Instr RmNot31(CPURegister rm)
void csetm(const Register &rd, Condition cond)
void sqdmlal(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stclrlb(const Register &rs, const MemOperand &src)
void casb(const Register &rs, const Register &rt, const MemOperand &src)
void ldsmaxl(const Register &rs, const Register &rt, const MemOperand &src)
void sqshrun(const VRegister &vd, const VRegister &vn, int shift)
void DataProcExtendedRegister(const Register &rd, const Register &rn, const Operand &operand, FlagsUpdate S, Instr op)
void fcmgt(const VRegister &vd, const VRegister &vn, double imm)
void pmull(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldsminab(const Register &rs, const Register &rt, const MemOperand &src)
void frintx(const VRegister &vd, const VRegister &vn)
void urhadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sdot(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fcvtnu(const VRegister &rd, const VRegister &vn)
void smull2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void cmge(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void bic(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void tbx(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vn3, const VRegister &vm)
void uaddl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void bit(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ld3r(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const MemOperand &src)
void ngcs(const Register &rd, const Operand &operand)
void NEON3DifferentW(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEON3DifferentOp vop)
static bool IsImmLSPair(int64_t offset, unsigned size)
void ldumaxh(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtps(const VRegister &vd, const VRegister &vn)
void shll(const VRegister &vd, const VRegister &vn, int shift)
void mov(const VRegister &vd, const VRegister &vn, int vn_index)
void rbit(const Register &rd, const Register &rn)
void addp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void movn(const Register &rd, uint64_t imm, int shift=-1)
void swp(const Register &rs, const Register &rt, const MemOperand &src)
void FPDataProcessing1Source(const VRegister &fd, const VRegister &fn, FPDataProcessing1SourceOp op)
void hint(SystemHint code)
void NEONFP2RegMisc(const VRegister &vd, const VRegister &vn, NEON2RegMiscOp vop, double value)
static Instr LSVFormat(VRegister vd)
void sqrshrun2(const VRegister &vd, const VRegister &vn, int shift)
static Instr Ra(CPURegister ra)
void sqxtn(const VRegister &vd, const VRegister &vn)
void bl(int imm26)
void RecordConstPool(int size)
void ldumaxlh(const Register &rs, const Register &rt, const MemOperand &src)
void eor(const Register &rd, const Register &rn, const Operand &operand)
void lduminl(const Register &rs, const Register &rt, const MemOperand &src)
void smull(const Register &rd, const Register &rn, const Register &rm)
void smaxp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fminp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void saddw2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ConditionalSelect(const Register &rd, const Register &rn, const Register &rm, Condition cond, ConditionalSelectOp op)
void ldsetab(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtzu(const Register &rd, const VRegister &vn, int fbits=0)
void st1(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const MemOperand &src)
void fnmsub(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void fcvtau(const VRegister &vd, const VRegister &vn)
void tbl(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vn3, const VRegister &vn4, const VRegister &vm)
void facge(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqdmull(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void subhn(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqsub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void rsubhn2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void near_call(HeapNumberRequest request)
void ldumaxal(const Register &rs, const Register &rt, const MemOperand &src)
void FPDataProcessing2Source(const VRegister &fd, const VRegister &fn, const VRegister &fm, FPDataProcessing2SourceOp op)
void uzp2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void NEONFPByElement(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index, NEONByIndexedElementOp op)
void fcvtxn(const VRegister &vd, const VRegister &vn)
void stlxrb(const Register &rs, const Register &rt, const Register &rn)
void ands(const Register &rd, const Register &rn, const Operand &operand)
void ld4r(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, const MemOperand &src)
void mla(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void csinc(const Register &rd, const Register &rn, const Register &rm, Condition cond)
void ucvtf(const VRegister &fd, const Register &rn, int fbits=0)
absl::flat_hash_map< int, int > branch_link_chain_back_edge_
void ldumin(const Register &rs, const Register &rt, const MemOperand &src)
void adcs(const Register &rd, const Register &rn, const Operand &operand)
void AddSubWithCarry(const Register &rd, const Register &rn, const Operand &operand, FlagsUpdate S, AddSubWithCarryOp op)
Assembler(const MaybeAssemblerZone &, const AssemblerOptions &, std::unique_ptr< AssemblerBuffer >={})
void stsmaxlb(const Register &rs, const MemOperand &src)
void ldaddal(const Register &rs, const Register &rt, const MemOperand &src)
void NEONAcrossLanes(const VRegister &vd, const VRegister &vn, NEONAcrossLanesOp op)
void ldclrh(const Register &rs, const Register &rt, const MemOperand &src)
void br(const Register &xn)
void DeleteUnresolvedBranchInfoForLabelTraverse(Label *label)
void sqneg(const VRegister &vd, const VRegister &vn)
void swpalb(const Register &rs, const Register &rt, const MemOperand &src)
void frinta(const VRegister &vd, const VRegister &vn)
void sshr(const VRegister &vd, const VRegister &vn, int shift)
void staddlh(const Register &rs, const MemOperand &src)
void ldumaxl(const Register &rs, const Register &rt, const MemOperand &src)
void ldeorb(const Register &rs, const Register &rt, const MemOperand &src)
void str(const CPURegister &rt, const MemOperand &dst)
void st1(const VRegister &vt, const VRegister &vt2, const MemOperand &src)
void ld1(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const MemOperand &src)
void NEONByElementL(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index, NEONByIndexedElementOp op)
void steorl(const Register &rs, const MemOperand &src)
void cmn(const Register &rn, const Operand &operand)
void uqxtn2(const VRegister &vd, const VRegister &vn)
void lduminh(const Register &rs, const Register &rt, const MemOperand &src)
uint64_t SizeOfCodeGeneratedSince(const Label *label)
void scvtf(const VRegister &fd, const VRegister &vn, int fbits=0)
void stumax(const Register &rs, const MemOperand &src)
void ldset(const Register &rs, const Register &rt, const MemOperand &src)
void fmsub(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void RecordVeneerPool(int location_offset, int size)
void fmov(const Register &rd, const VRegister &vn, int index)
void ldclr(const Register &rs, const Register &rt, const MemOperand &src)
void ushll2(const VRegister &vd, const VRegister &vn, int shift)
static bool IsConstantPoolAt(Instruction *instr)
void swpl(const Register &rs, const Register &rt, const MemOperand &src)
void sbfiz(const Register &rd, const Register &rn, int lsb, int width)
void AllocateAndInstallRequestedHeapNumbers(LocalIsolate *isolate)
void sadalp(const VRegister &vd, const VRegister &vn)
void usqadd(const VRegister &vd, const VRegister &vn)
void strh(const Register &rt, const MemOperand &dst)
static Instr Rm(CPURegister rm)
void caspl(const Register &rs, const Register &rs2, const Register &rt, const Register &rt2, const MemOperand &src)
void sqshrn2(const VRegister &vd, const VRegister &vn, int shift)
void ldeorab(const Register &rs, const Register &rt, const MemOperand &src)
void ldsminah(const Register &rs, const Register &rt, const MemOperand &src)
static Instr Rd(CPURegister rd)
void sxtw(const Register &rd, const Register &rn)
void ldsetal(const Register &rs, const Register &rt, const MemOperand &src)
void ld1(const VRegister &vt, const MemOperand &src)
void fminnmp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void orr(const VRegister &vd, const int imm8, const int left_shift=0)
void NEONShiftImmediate(const VRegister &vd, const VRegister &vn, NEONShiftImmediateOp op, int immh_immb)
void mneg(const Register &rd, const Register &rn, const Register &rm)
void mvn(const Register &rd, const Operand &operand)
void fcvtzs(const VRegister &vd, const VRegister &vn, int fbits=0)
void cmeq(const VRegister &vd, const VRegister &vn, int value)
bool ShouldEmitVeneers(size_t margin=kVeneerDistanceMargin)
void tbl(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vn3, const VRegister &vm)
void orr(const VRegister &vd, const VRegister &vn, const VRegister &vm)
uint64_t SizeOfGeneratedCode() const
void suqadd(const VRegister &vd, const VRegister &vn)
void dci(Instr raw_inst)
void stuminlb(const Register &rs, const MemOperand &src)
void uqshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void NEONFPConvertToInt(const Register &rd, const VRegister &vn, Instr op)
void ldclrl(const Register &rs, const Register &rt, const MemOperand &src)
void umull2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void and_(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void bind(Label *label)
void sminv(const VRegister &vd, const VRegister &vn)
void ursqrte(const VRegister &vd, const VRegister &vn)
void smull(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void umlal(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void raddhn2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void urshr(const VRegister &vd, const VRegister &vn, int shift)
static void deserialization_set_target_internal_reference_at(Address pc, Address target, WritableJitAllocation &jit_allocation, RelocInfo::Mode mode=RelocInfo::INTERNAL_REFERENCE)
void ccmn(const Register &rn, const Operand &operand, StatusFlags nzcv, Condition cond)
void udiv(const Register &rd, const Register &rn, const Register &rm)
void bcax(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void bti(BranchTargetIdentifier id)
void xtn2(const VRegister &vd, const VRegister &vn)
void ldsetalh(const Register &rs, const Register &rt, const MemOperand &src)
void frsqrts(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqdmulh(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void ldclra(const Register &rs, const Register &rt, const MemOperand &src)
void ushll(const VRegister &vd, const VRegister &vn, int shift)
void ldadd(const Register &rs, const Register &rt, const MemOperand &src)
void swplb(const Register &rs, const Register &rt, const MemOperand &src)
void DataProcessing3Source(const Register &rd, const Register &rn, const Register &rm, const Register &ra, DataProcessing3SourceOp op)
void ldumaxb(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtl(const VRegister &vd, const VRegister &vn)
void subs(const Register &rd, const Register &rn, const Operand &operand)
void st1(const VRegister &vt, int lane, const MemOperand &src)
void caslb(const Register &rs, const Register &rt, const MemOperand &src)
void ldaddh(const Register &rs, const Register &rt, const MemOperand &src)
void sbfx(const Register &rd, const Register &rn, int lsb, int width)
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data=0, ConstantPoolMode constant_pool_mode=NEEDS_POOL_ENTRY)
void uxth(const Register &rd, const Register &rn)
void ldadda(const Register &rs, const Register &rt, const MemOperand &src)
void tbl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stclrlh(const Register &rs, const MemOperand &src)
void facgt(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void asrv(const Register &rd, const Register &rn, const Register &rm)
void NEONAcrossLanesL(const VRegister &vd, const VRegister &vn, NEONAcrossLanesOp op)
void umlal(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void saba(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void smull2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqabs(const VRegister &vd, const VRegister &vn)
void ldr_pcrel(const CPURegister &rt, int imm19)
void mov(const VRegister &vd, const VRegister &vn)
void scvtf(const VRegister &fd, const Register &rn, int fbits=0)
void ror(const Register &rd, const Register &rs, unsigned shift)
void ldaxrh(const Register &rt, const Register &rn)
void ldumaxalh(const Register &rs, const Register &rt, const MemOperand &src)
void ld3(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, int lane, const MemOperand &src)
void ldsetah(const Register &rs, const Register &rt, const MemOperand &src)
void fmaxnmv(const VRegister &vd, const VRegister &vn)
void ssubw(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void frintn(const VRegister &vd, const VRegister &vn)
void ldaddab(const Register &rs, const Register &rt, const MemOperand &src)
void ldeorh(const Register &rs, const Register &rt, const MemOperand &src)
void fjcvtzs(const Register &rd, const VRegister &vn)
void rbit(const VRegister &vd, const VRegister &vn)
void usubl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stsminlb(const Register &rs, const MemOperand &src)
void ngc(const Register &rd, const Operand &operand)
void fmaxnm(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void madd(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void smlal(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void caspal(const Register &rs, const Register &rs2, const Register &rt, const Register &rt2, const MemOperand &src)
ZoneAbslBTreeMap< int, Label * > unresolved_branches_
void stsetl(const Register &rs, const MemOperand &src)
void sqrshrn(const VRegister &vd, const VRegister &vn, int shift)
ptrdiff_t InstructionOffset(Instruction *instr) const
Instruction * InstructionAt(ptrdiff_t offset) const
void stsminlh(const Register &rs, const MemOperand &src)
void b(Label *label, Condition cond)
void fmulx(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqdmlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
static Instr ImmNEONHLM(int index, int num_bits)
void swpalh(const Register &rs, const Register &rt, const MemOperand &src)
void ldsetlh(const Register &rs, const Register &rt, const MemOperand &src)
void cmge(const VRegister &vd, const VRegister &vn, int value)
void lduminab(const Register &rs, const Register &rt, const MemOperand &src)
void mla(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fcmge(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sxth(const Register &rd, const Register &rn)
void ldsminlh(const Register &rs, const Register &rt, const MemOperand &src)
void frintp(const VRegister &vd, const VRegister &vn)
void neg(const Register &rd, const Operand &operand)
void tbz(const Register &rt, unsigned bit_pos, Label *label)
void sqdmlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void srhadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldrsw(const Register &rt, const MemOperand &src)
void ldclrlh(const Register &rs, const Register &rt, const MemOperand &src)
static Instr VFormat(VRegister vd)
void stlrh(const Register &rt, const Register &rn)
void fcvtn(const VRegister &vd, const VRegister &vn)
void ldsetl(const Register &rs, const Register &rt, const MemOperand &src)
static Instr Rt(CPURegister rt)
void fmov(const VRegister &fd, const VRegister &fn)
void sqxtun2(const VRegister &vd, const VRegister &vn)
void fminv(const VRegister &vd, const VRegister &vn)
void clz(const VRegister &vd, const VRegister &vn)
void uabdl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void abs(const VRegister &vd, const VRegister &vn)
void sqrdmulh(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sli(const VRegister &vd, const VRegister &vn, int shift)
void casa(const Register &rs, const Register &rt, const MemOperand &src)
void saddl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sabdl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void saddw(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void cmhs(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldaddalb(const Register &rs, const Register &rt, const MemOperand &src)
void bfm(const Register &rd, const Register &rn, int immr, int imms)
void zip2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void uaddw2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void lslv(const Register &rd, const Register &rn, const Register &rm)
void frintz(const VRegister &vd, const VRegister &vn)
void fcvtms(const Register &rd, const VRegister &vn)
void NEON2RegMisc(const VRegister &vd, const VRegister &vn, NEON2RegMiscOp vop, int value=0)
void near_jump(int offset, RelocInfo::Mode rmode)
void fminnmv(const VRegister &vd, const VRegister &vn)
void mov(const Register &rd, const VRegister &vn, int vn_index)
void sqxtun(const VRegister &vd, const VRegister &vn)
void ld4(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, int lane, const MemOperand &src)
void cmp(const Register &rn, const Operand &operand)
void mov(const Register &rd, const Register &rn)
void ld2(const VRegister &vt, const VRegister &vt2, const MemOperand &src)
void ssubw2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void tbx(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void EmitExtendShift(const Register &rd, const Register &rn, Extend extend, unsigned left_shift)
static constexpr bool IsImmAddSub(int64_t immediate)
void ldsminb(const Register &rs, const Register &rt, const MemOperand &src)
void LoadStoreStruct(const VRegister &vt, const MemOperand &addr, NEONLoadStoreMultiStructOp op)
void sqshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void smlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldumaxa(const Register &rs, const Register &rt, const MemOperand &src)
void fmul(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void strb(const Register &rt, const MemOperand &dst)
void cmgt(const VRegister &vd, const VRegister &vn, int value)
void faddp(const VRegister &vd, const VRegister &vn)
void msr(SystemRegister sysreg, const Register &rt)
void stlrb(const Register &rt, const Register &rn)
void fcvtxn2(const VRegister &vd, const VRegister &vn)
void faddp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void steor(const Register &rs, const MemOperand &src)
void stlr(const Register &rt, const Register &rn)
void ldsetlb(const Register &rs, const Register &rt, const MemOperand &src)
void ldumaxlb(const Register &rs, const Register &rt, const MemOperand &src)
void uabdl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void umax(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void addv(const VRegister &vd, const VRegister &vn)
void ssubl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void umlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static Instr NEONModImmOp(int op)
void fcvtmu(const Register &rd, const VRegister &vn)
void EmitConstPoolWithJumpIfNeeded(size_t margin=0)
void ldumaxah(const Register &rs, const Register &rt, const MemOperand &src)
void uaddw(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static uint32_t uint32_constant_at(Address pc, Address constant_pool)
void casab(const Register &rs, const Register &rt, const MemOperand &src)
static Instr FPFormat(VRegister vd)
void msub(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void ldaddah(const Register &rs, const Register &rt, const MemOperand &src)
void umin(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldr(const CPURegister &rt, const Operand &operand)
void cneg(const Register &rd, const Register &rn, Condition cond)
void dsb(BarrierDomain domain, BarrierType type)
void umlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void DeleteUnresolvedBranchInfoForLabel(Label *label)
void adc(const Register &rd, const Register &rn, const Operand &operand)
void uaddl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldsmaxalh(const Register &rs, const Register &rt, const MemOperand &src)
void frecps(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fminnmp(const VRegister &vd, const VRegister &vn)
void sqdmull2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void DataProcShiftedRegister(const Register &rd, const Register &rn, const Operand &operand, FlagsUpdate S, Instr op)
void uhadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void add(const Register &rd, const Register &rn, const Operand &operand)
void fcvtzu(const VRegister &vd, const VRegister &vn, int fbits=0)
void ldrb(const Register &rt, const MemOperand &src)
void ldrsb(const Register &rt, const MemOperand &src)
void uqsub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sri(const VRegister &vd, const VRegister &vn, int shift)
void dmb(BarrierDomain domain, BarrierType type)
void pmull2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void dc32(uint32_t data)
void fcmp(const VRegister &vn, const VRegister &vm)
void cls(const Register &rd, const Register &rn)
void umulh(const Register &rd, const Register &rn, const Register &rm)
void sabal(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void dcptr(Label *label)
void smlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void swpab(const Register &rs, const Register &rt, const MemOperand &src)
void ldsmax(const Register &rs, const Register &rt, const MemOperand &src)
void bsl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ushr(const VRegister &vd, const VRegister &vn, int shift)
void rev16(const VRegister &vd, const VRegister &vn)
void saddlv(const VRegister &vd, const VRegister &vn)
static void set_uint32_constant_at(Address pc, Address constant_pool, uint32_t new_constant, WritableJitAllocation *jit_allocation=nullptr, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void uqrshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static Instr Rt2(CPURegister rt2)
void swplh(const Register &rs, const Register &rt, const MemOperand &src)
void sminp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void rorv(const Register &rd, const Register &rn, const Register &rm)
static Address target_address_at(Address pc, Address constant_pool)
void lduminal(const Register &rs, const Register &rt, const MemOperand &src)
void ubfx(const Register &rd, const Register &rn, int lsb, int width)
void ConditionalCompare(const Register &rn, const Operand &operand, StatusFlags nzcv, Condition cond, ConditionalCompareOp op)
void umlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stsmax(const Register &rs, const MemOperand &src)
void fmov(const VRegister &fd, double imm)
void smaddl(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void shrn2(const VRegister &vd, const VRegister &vn, int shift)
void stsetlh(const Register &rs, const MemOperand &src)
void eor3(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void ld3(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const MemOperand &src)
void fcmp(const VRegister &vn, double value)
void Emit(Instr instruction)
void fcmeq(const VRegister &vd, const VRegister &vn, double imm)
void stclr(const Register &rs, const MemOperand &src)
void ldaddlb(const Register &rs, const Register &rt, const MemOperand &src)
void extr(const Register &rd, const Register &rn, const Register &rm, int lsb)
void addp(const VRegister &vd, const VRegister &vn)
void frecpe(const VRegister &vd, const VRegister &vn)
void ldaddb(const Register &rs, const Register &rt, const MemOperand &src)
void sqrshrun(const VRegister &vd, const VRegister &vn, int shift)
static Instr ImmNEON5(Instr format, int index)
void fcvt(const VRegister &vd, const VRegister &vn)
void ld1(const VRegister &vt, int lane, const MemOperand &src)
void near_call(int offset, RelocInfo::Mode rmode)
int unresolved_branches_first_limit() const
void fcvtns(const Register &rd, const VRegister &vn)
void cmhi(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldar(const Register &rt, const Register &rn)
void ldp(const CPURegister &rt, const CPURegister &rt2, const MemOperand &src)
void ld2(const VRegister &vt, const VRegister &vt2, int lane, const MemOperand &src)
void fsqrt(const VRegister &vd, const VRegister &vn)
void ld1r(const VRegister &vt, const MemOperand &src)
void cmgt(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fminp(const VRegister &vd, const VRegister &vn)
void staddl(const Register &rs, const MemOperand &src)
static Instr Rs(CPURegister rs)
void smsubl(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void umull(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static constexpr int kGap
static Instr ImmNEONExt(int imm4)
void stset(const Register &rs, const MemOperand &src)
void tbl(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vm)
void caspa(const Register &rs, const Register &rs2, const Register &rt, const Register &rt2, const MemOperand &src)
void ld1(const VRegister &vt, const VRegister &vt2, const MemOperand &src)
static Instr SFormat(VRegister vd)
static Instr ImmNEONFP(double imm)
std::deque< int > internal_reference_positions_
void fadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void usubl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void smlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void LoadStore(const CPURegister &rt, const MemOperand &addr, LoadStoreOp op)
void ldsmaxb(const Register &rs, const Register &rt, const MemOperand &src)
static Instr ImmFP(double imm)
void smull(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void fcvtn2(const VRegister &vd, const VRegister &vn)
void swpb(const Register &rs, const Register &rt, const MemOperand &src)
void cas(const Register &rs, const Register &rt, const MemOperand &src)
void RemoveBranchFromLabelLinkChain(Instruction *branch, Label *label, Instruction *label_veneer=nullptr)
void sqdmlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void bl(Label *label)
void NEONShiftRightImmediate(const VRegister &vd, const VRegister &vn, int shift, NEONShiftImmediateOp op)
void dc64(uint64_t data)
static bool IsImmFP64(uint64_t bits)
void uqrshrn(const VRegister &vd, const VRegister &vn, int shift)
int LinkAndGetByteOffsetTo(Label *label)
void fminnm(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldaddl(const Register &rs, const Register &rt, const MemOperand &src)
void adr(const Register &rd, Label *label)
void ldsminh(const Register &rs, const Register &rt, const MemOperand &src)
void mov(const VRegister &vd, int vd_index, const VRegister &vn, int vn_index)
void NEONShiftImmediateN(const VRegister &vd, const VRegister &vn, int shift, NEONShiftImmediateOp op)
void adr(const Register &rd, int imm21)
void trn1(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static Instr ImmNEON4(Instr format, int index)
void trn2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void frecpx(const VRegister &vd, const VRegister &vn)
void rshrn(const VRegister &vd, const VRegister &vn, int shift)
void fmulx(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void cls(const VRegister &vd, const VRegister &vn)
void fccmp(const VRegister &vn, const VRegister &vm, StatusFlags nzcv, Condition cond)
void fmadd(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void GetCode(Isolate *isolate, CodeDesc *desc)
void st3(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const MemOperand &src)
void NEON3Same(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEON3SameOp vop)
void lduminalh(const Register &rs, const Register &rt, const MemOperand &src)
void uxtl(const VRegister &vd, const VRegister &vn)
void fcvtpu(const Register &rd, const VRegister &vn)
void add(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void orr(const Register &rd, const Register &rn, const Operand &operand)
void sxtl2(const VRegister &vd, const VRegister &vn)
void stclrb(const Register &rs, const MemOperand &src)
void cinc(const Register &rd, const Register &rn, Condition cond)
void ldsmaxa(const Register &rs, const Register &rt, const MemOperand &src)
void urecpe(const VRegister &vd, const VRegister &vn)
void fcvtmu(const VRegister &vd, const VRegister &vn)
void ubfiz(const Register &rd, const Register &rn, int lsb, int width)
void smulh(const Register &rd, const Register &rn, const Register &rm)
void cmtst(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fmov(const VRegister &vd, int index, const Register &rn)
void uxtl2(const VRegister &vd, const VRegister &vn)
void fsub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void LoadStoreStructVerify(const VRegister &vt, const MemOperand &addr, Instr op)
void bfxil(const Register &rd, const Register &rn, int lsb, int width)
void ldclrah(const Register &rs, const Register &rt, const MemOperand &src)
void ldclrab(const Register &rs, const Register &rt, const MemOperand &src)
void sub(const Register &rd, const Register &rn, const Operand &operand)
void csel(const Register &rd, const Register &rn, const Register &rm, Condition cond)
void lduminb(const Register &rs, const Register &rt, const MemOperand &src)
void fmaxv(const VRegister &vd, const VRegister &vn)
void fabs(const VRegister &vd, const VRegister &vn)
void tst(const Register &rn, const Operand &operand)
void fcmge(const VRegister &vd, const VRegister &vn, double imm)
void usubw2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static constexpr bool IsImmConditionalCompare(int64_t immediate)
void ldrsh(const Register &rt, const MemOperand &src)
void fmls(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void sqrshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sshll(const VRegister &vd, const VRegister &vn, int shift)
void saddl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void tbz(const Register &rt, unsigned bit_pos, int imm14)
void bics(const Register &rd, const Register &rn, const Operand &operand)
void and_(const Register &rd, const Register &rn, const Operand &operand)
void ldeora(const Register &rs, const Register &rt, const MemOperand &src)
void fmax(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqshrun2(const VRegister &vd, const VRegister &vn, int shift)
void ldeoralb(const Register &rs, const Register &rt, const MemOperand &src)
void ldr(const CPURegister &rt, const Immediate &imm)
void eon(const Register &rd, const Register &rn, const Operand &operand)
void ldseta(const Register &rs, const Register &rt, const MemOperand &src)
static Instr ImmNEONabcdefgh(int imm8)
void dq(uint64_t data)
void movz(const Register &rd, uint64_t imm, int shift=-1)
static bool IsImmLLiteral(int64_t offset)
void umull2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void lduminlb(const Register &rs, const Register &rt, const MemOperand &src)
void fcmgt(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void umlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void neg(const VRegister &vd, const VRegister &vn)
void uqshrn2(const VRegister &vd, const VRegister &vn, int shift)
void ldeorah(const Register &rs, const Register &rt, const MemOperand &src)
void b(int imm19, Condition cond)
void stsmaxl(const Register &rs, const MemOperand &src)
void umlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void FPDataProcessing3Source(const VRegister &fd, const VRegister &fn, const VRegister &fm, const VRegister &fa, FPDataProcessing3SourceOp op)
void cbnz(const Register &rt, int imm19)
void sqdmlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void lsl(const Register &rd, const Register &rn, int shift)
void stuminh(const Register &rs, const MemOperand &src)
void stumaxb(const Register &rs, const MemOperand &src)
void fcmeq(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sabd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fdiv(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void NEONShiftImmediateL(const VRegister &vd, const VRegister &vn, int shift, NEONShiftImmediateOp op)
void sqdmulh(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void tbnz(const Register &rt, unsigned bit_pos, Label *label)
void ccmp(const Register &rn, const Operand &operand, StatusFlags nzcv, Condition cond)
void casp(const Register &rs, const Register &rs2, const Register &rt, const Register &rt2, const MemOperand &src)
void rev16(const Register &rd, const Register &rn)
void not_(const VRegister &vd, const VRegister &vn)
void eor(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqxtn2(const VRegister &vd, const VRegister &vn)
void EmitVeneers(bool force_emit, bool need_protection, size_t margin=kVeneerDistanceMargin)
void LoadStoreStructSingle(const VRegister &vt, uint32_t lane, const MemOperand &addr, NEONLoadStoreSingleStructOp op)
void MoveWide(const Register &rd, uint64_t imm, int shift, MoveWideImmediateOp mov_op)
void tbx(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vn3, const VRegister &vn4, const VRegister &vm)
void ld2r(const VRegister &vt, const VRegister &vt2, const MemOperand &src)
void ldeorl(const Register &rs, const Register &rt, const MemOperand &src)
void mul(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void uqadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void mov(const VRegister &vd, int vd_index, const Register &rn)
void stseth(const Register &rs, const MemOperand &src)
void EmitShift(const Register &rd, const Register &rn, Shift shift, unsigned amount)
void sqshrn(const VRegister &vd, const VRegister &vn, int shift)
void cash(const Register &rs, const Register &rt, const MemOperand &src)
void stsminl(const Register &rs, const MemOperand &src)
void ldclrlb(const Register &rs, const Register &rt, const MemOperand &src)
void sshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ubfm(const Register &rd, const Register &rn, int immr, int imms)
void mul(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void smov(const Register &rd, const VRegister &vn, int vn_index)
void ldsminalh(const Register &rs, const Register &rt, const MemOperand &src)
void shadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ushl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ld4(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, const MemOperand &src)
void LoadStoreStruct1(const VRegister &vt, int reg_count, const MemOperand &addr)
void pmul(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void addhn(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void adds(const Register &rd, const Register &rn, const Operand &operand)
void uqrshrn2(const VRegister &vd, const VRegister &vn, int shift)
void st4(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, const MemOperand &src)
void fmla(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fmaxnmp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqdmull(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void stclrh(const Register &rs, const MemOperand &src)
void movi(const VRegister &vd, const uint64_t imm, Shift shift=LSL, const int shift_amount=0)
void st3(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, int lane, const MemOperand &src)
void stsetb(const Register &rs, const MemOperand &src)
void sqdmlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void uminp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqrshrn2(const VRegister &vd, const VRegister &vn, int shift)
void movk(const Register &rd, uint64_t imm, int shift=-1)
void umaxv(const VRegister &vd, const VRegister &vn)
void sbfm(const Register &rd, const Register &rn, int immr, int imms)
void ldsmaxh(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtpu(const VRegister &vd, const VRegister &vn)
void GetCode(LocalIsolate *isolate, CodeDesc *desc, SafepointTableBuilderBase *safepoint_table_builder, int handler_table_offset)
void steorh(const Register &rs, const MemOperand &src)
void sqshlu(const VRegister &vd, const VRegister &vn, int shift)
void sshll2(const VRegister &vd, const VRegister &vn, int shift)
void ldsmina(const Register &rs, const Register &rt, const MemOperand &src)
void tbx(const VRegister &vd, const VRegister &vn, const VRegister &vn2, const VRegister &vm)
void ext(const VRegister &vd, const VRegister &vn, const VRegister &vm, int index)
static Instr Rn(CPURegister rn)
void ldaddlh(const Register &rs, const Register &rt, const MemOperand &src)
void orn(const Register &rd, const Register &rn, const Operand &operand)
void sabdl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldaxrb(const Register &rt, const Register &rn)
void bic(const Register &rd, const Register &rn, const Operand &operand)
void fmaxnmp(const VRegister &vd, const VRegister &vn)
static constexpr bool IsImmLSUnscaled(int64_t offset)
void cinv(const Register &rd, const Register &rn, Condition cond)
static int deserialization_special_target_size(Address location)
void ldeor(const Register &rs, const Register &rt, const MemOperand &src)
void sub(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void addhn2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void mls(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void uzp1(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void fcvtns(const VRegister &rd, const VRegister &vn)
void swpa(const Register &rs, const Register &rt, const MemOperand &src)
void ins(const VRegister &vd, int vd_index, const VRegister &vn, int vn_index)
void fcvtl2(const VRegister &vd, const VRegister &vn)
void EmitStringData(const char *string)
void bic(const VRegister &vd, const int imm8, const int left_shift=0)
void dp(uintptr_t data)
void stumaxh(const Register &rs, const MemOperand &src)
void NEONModifiedImmShiftMsl(const VRegister &vd, const int imm8, const int shift_amount, NEONModifiedImmediateOp op)
void smlsl2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void uaddlv(const VRegister &vd, const VRegister &vn)
void urshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void frintm(const VRegister &vd, const VRegister &vn)
void stsminb(const Register &rs, const MemOperand &src)
void uminv(const VRegister &vd, const VRegister &vn)
void blr(const Register &xn)
void ldsminal(const Register &rs, const Register &rt, const MemOperand &src)
void sqshl(const VRegister &vd, const VRegister &vn, int shift)
void fnmadd(const VRegister &vd, const VRegister &vn, const VRegister &vm, const VRegister &va)
void stsmaxlh(const Register &rs, const MemOperand &src)
void cnt(const VRegister &vd, const VRegister &vn)
void stumaxl(const Register &rs, const MemOperand &src)
void shrn(const VRegister &vd, const VRegister &vn, int shift)
void NEON3DifferentL(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEON3DifferentOp vop)
void nop(NopMarkerTypes n)
void uabd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldsmaxlb(const Register &rs, const Register &rt, const MemOperand &src)
void ucvtf(const VRegister &fd, const VRegister &vn, int fbits=0)
void shl(const VRegister &vd, const VRegister &vn, int shift)
void tbnz(const Register &rt, unsigned bit_pos, int imm14)
void sqdmull2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void DataProcessing1Source(const Register &rd, const Register &rn, DataProcessing1SourceOp op)
void stlxr(const Register &rs, const Register &rt, const Register &rn)
static uint32_t FPToImm8(double imm)
void uqshl(const VRegister &vd, const VRegister &vn, int shift)
void st2(const VRegister &vt, const VRegister &vt2, const MemOperand &src)
void usra(const VRegister &vd, const VRegister &vn, int shift)
void LoadStorePair(const CPURegister &rt, const CPURegister &rt2, const MemOperand &addr, LoadStorePairOp op)
void fmov(const VRegister &fd, float imm)
void stp(const CPURegister &rt, const CPURegister &rt2, const MemOperand &dst)
void sqadd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ins(const VRegister &vd, int vd_index, const Register &rn)
void shll2(const VRegister &vd, const VRegister &vn, int shift)
void fmaxp(const VRegister &vd, const VRegister &vn)
static void set_target_address_at(Address pc, Address constant_pool, Address target, WritableJitAllocation *jit_allocation, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void ldclralb(const Register &rs, const Register &rt, const MemOperand &src)
void ldeoralh(const Register &rs, const Register &rt, const MemOperand &src)
void stumaxlb(const Register &rs, const MemOperand &src)
void NEONModifiedImmShiftLsl(const VRegister &vd, const int imm8, const int left_shift, NEONModifiedImmediateOp op)
void ldsmaxah(const Register &rs, const Register &rt, const MemOperand &src)
void negs(const Register &rd, const Operand &operand)
void ldseth(const Register &rs, const Register &rt, const MemOperand &src)
void stuminb(const Register &rs, const MemOperand &src)
void cbnz(const Register &rt, Label *label)
void stadd(const Register &rs, const MemOperand &src)
void dd(uint32_t data)
void mvn(const VRegister &vd, const VRegister &vn)
void rev64(const VRegister &vd, const VRegister &vn)
void AddSub(const Register &rd, const Register &rn, const Operand &operand, FlagsUpdate S, AddSubOp op)
void st2(const VRegister &vt, const VRegister &vt2, int lane, const MemOperand &src)
void stsmaxb(const Register &rs, const MemOperand &src)
void cbz(const Register &rt, int imm19)
void steorlb(const Register &rs, const MemOperand &src)
static bool IsImmLogical(uint64_t value, unsigned width, unsigned *n, unsigned *imm_s, unsigned *imm_r)
void NEONShiftLeftImmediate(const VRegister &vd, const VRegister &vn, int shift, NEONShiftImmediateOp op)
void ursra(const VRegister &vd, const VRegister &vn, int shift)
void cbz(const Register &rt, Label *label)
void fneg(const VRegister &vd, const VRegister &vn)
void sqrdmulh(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void NEONFP2RegMisc(const VRegister &vd, const VRegister &vn, Instr op)
void ldumax(const Register &rs, const Register &rt, const MemOperand &src)
void fmul(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void st1(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, const MemOperand &src)
void stsmaxh(const Register &rs, const MemOperand &src)
void ldsmaxalb(const Register &rs, const Register &rt, const MemOperand &src)
void srshr(const VRegister &vd, const VRegister &vn, int shift)
void CheckLabelLinkChain(Label const *label)
void srsra(const VRegister &vd, const VRegister &vn, int shift)
void stuminlh(const Register &rs, const MemOperand &src)
void fcvtas(const VRegister &vd, const VRegister &vn)
void frsqrte(const VRegister &vd, const VRegister &vn)
void ld1(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, const MemOperand &src)
void umull(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void cmlt(const VRegister &vd, const VRegister &vn, int value)
void caslh(const Register &rs, const Register &rt, const MemOperand &src)
void uxtw(const Register &rd, const Register &rn)
void NEONTable(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEONTableOp op)
void mls(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void st1(const VRegister &vt, const MemOperand &src)
void srshl(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stumaxlh(const Register &rs, const MemOperand &src)
void smaxv(const VRegister &vd, const VRegister &vn)
void fmin(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void smlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void fmla(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void clz(const Register &rd, const Register &rn)
void subhn2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void dup(const VRegister &vd, const Register &rn)
void sdiv(const Register &rd, const Register &rn, const Register &rm)
void uaddlp(const VRegister &vd, const VRegister &vn)
bool ShouldEmitVeneer(int max_reachable_pc, size_t margin)
void stsmin(const Register &rs, const MemOperand &src)
void mrs(const Register &rt, SystemRegister sysreg)
void EmitData(void const *data, unsigned size)
void AbortedCodeGeneration() override
void swpal(const Register &rs, const Register &rt, const MemOperand &src)
void ldsmaxab(const Register &rs, const Register &rt, const MemOperand &src)
void sxtb(const Register &rd, const Register &rn)
void ldumaxab(const Register &rs, const Register &rt, const MemOperand &src)
void debug(const char *message, uint32_t code, Instr params=BREAK)
void usubw(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void sqdmlsl(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void st4(const VRegister &vt, const VRegister &vt2, const VRegister &vt3, const VRegister &vt4, int lane, const MemOperand &src)
void casl(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtps(const Register &rd, const VRegister &vn)
void fcvtas(const Register &rd, const VRegister &vn)
void rev(const Register &rd, const Register &rn)
void ldsetalb(const Register &rs, const Register &rt, const MemOperand &src)
void smin(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void saddlp(const VRegister &vd, const VRegister &vn)
void NEONFP3Same(const VRegister &vd, const VRegister &vn, const VRegister &vm, Instr op)
void umaxp(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void asr(const Register &rd, const Register &rn, int shift)
void fabd(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ret(const Register &xn=lr)
void umsubl(const Register &rd, const Register &rn, const Register &rm, const Register &ra)
void sbc(const Register &rd, const Register &rn, const Operand &operand)
Instr LoadStoreStructAddrModeField(const MemOperand &addr)
void fmls(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldaxr(const Register &rt, const Register &rn)
void sabal2(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stumin(const Register &rs, const MemOperand &src)
void ldarb(const Register &rt, const Register &rn)
void casalb(const Register &rs, const Register &rt, const MemOperand &src)
void Logical(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op)
void umlal2(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void xtn(const VRegister &vd, const VRegister &vn)
void bfi(const Register &rd, const Register &rn, int lsb, int width)
Instruction * pc() const
void ldarh(const Register &rt, const Register &rn)
void stclrl(const Register &rs, const MemOperand &src)
void NEONByElement(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index, NEONByIndexedElementOp op)
void ldclral(const Register &rs, const Register &rt, const MemOperand &src)
void ldsmin(const Register &rs, const Register &rt, const MemOperand &src)
void orn(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void ldsminlb(const Register &rs, const Register &rt, const MemOperand &src)
bool is_veneer_pool_blocked() const
void fcsel(const VRegister &vd, const VRegister &vn, const VRegister &vm, Condition cond)
void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id, SourcePosition position, int id)
void ldrh(const Register &rt, const MemOperand &src)
void ldeorlb(const Register &rs, const Register &rt, const MemOperand &src)
void smlal(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void ldr(const CPURegister &rt, const MemOperand &src)
void casalh(const Register &rs, const Register &rt, const MemOperand &src)
void fmov(const Register &rd, const VRegister &fn)
void NEONFPConvertToInt(const VRegister &vd, const VRegister &vn, Instr op)
void swph(const Register &rs, const Register &rt, const MemOperand &src)
void ldsminalb(const Register &rs, const Register &rt, const MemOperand &src)
void fcvtau(const Register &rd, const VRegister &vn)
void stlxrh(const Register &rs, const Register &rt, const Register &rn)
void b(Label *label)
void cmeq(const VRegister &vd, const VRegister &vn, const VRegister &vm)
static int ConstantPoolSizeAt(Instruction *instr)
void staddh(const Register &rs, const MemOperand &src)
void cmle(const VRegister &vd, const VRegister &vn, int value)
void uabal(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void csinv(const Register &rd, const Register &rn, const Register &rm, Condition cond)
void csneg(const Register &rd, const Register &rn, const Register &rm, Condition cond)
void sqdmlal(const VRegister &vd, const VRegister &vn, const VRegister &vm, int vm_index)
void fnmul(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void rev32(const VRegister &vd, const VRegister &vn)
void rsubhn(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void stuminl(const Register &rs, const MemOperand &src)
void lsrv(const Register &rd, const Register &rn, const Register &rm)
void fcmlt(const VRegister &vd, const VRegister &vn, double imm)
void ldsmaxlh(const Register &rs, const Register &rt, const MemOperand &src)
void NEONXtn(const VRegister &vd, const VRegister &vn, NEON2RegMiscOp vop)
void CheckVeneerPool(bool force_emit, bool require_jump, size_t margin=kVeneerDistanceMargin)
void raddhn(const VRegister &vd, const VRegister &vn, const VRegister &vm)
void NEON3DifferentHN(const VRegister &vd, const VRegister &vn, const VRegister &vm, NEON3DifferentOp vop)
void ldpsw(const Register &rt, const Register &rt2, const MemOperand &src)
void lduminah(const Register &rs, const Register &rt, const MemOperand &src)
Assembler::BlockPoolsScope block_pools_scope_
V8_INLINE EnsureSpace(Assembler *assembler)
Immediate(Handle< T > handle, RelocInfo::Mode mode=RelocInfo::FULL_EMBEDDED_OBJECT)
RelocInfo::Mode rmode() const
const Register & base() const
bool IsImmediateOffset() const
unsigned shift_amount() const
const Register & regoffset() const
std::optional< HeapNumberRequest > heap_number_request_
RelocInfo::Mode ImmediateRMode() const
unsigned shift_amount() const
bool IsImmediate() const
RelocInfo::Mode rmode()
bool NeedsRelocation(const Assembler *assembler) const
HeapNumberRequest heap_number_request() const
Immediate immediate_for_heap_number_request() const
bool IsHeapNumberRequest() const
Operand ToExtendedRegister() const
static Operand EmbeddedHeapNumber(double number)
static Operand EmbeddedNumber(double number)
V8_INLINE Operand(int32_t immediate, RelocInfo::Mode rmode=RelocInfo::NO_INFO)
Immediate immediate() const
BlockPoolsScope block_constant_pool_emission_scope
static constexpr int kAdrFarPatchableNNops
void PatchSubSp(uint32_t immediate)
static constexpr int kAdrFarPatchableNInstrs
void PatchAdrFar(int64_t target_offset)
PatchingAssembler(Zone *zone, const AssemblerOptions &options, uint8_t *start, unsigned count)
constexpr int8_t code() const
Zone * zone_
base::OwnedVector< uint8_t > buffer_
Definition assembler.cc:111
int start
Label label
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage * MB
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation trace turbo cfg trace TurboFan s graph trimmer trace TurboFan s control equivalence trace TurboFan s register allocator trace stack load store counters for optimized code in run fuzzing &&concurrent_recompilation trace_turbo trace_turbo_scheduled trace_turbo_stack_accesses verify TurboFan machine graph of code stubs enable FixedArray bounds checks print TurboFan statistics of wasm compilations maximum cumulative size of bytecode considered for inlining scale factor of bytecode size used to calculate the inlining budget * KB
int32_t offset
Instruction * instr
LiftoffRegister reg
int pc_offset
EmitFn fn
int position
Definition liveedit.cc:290
int s
Definition mul-fft.cc:297
int m
Definition mul-fft.cc:294
STL namespace.
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr NEONFormatField NEON_8B
V8_EXPORT_PRIVATE base::Vector< Flag > Flags()
Definition flags.cc:300
uint32_t AddSubWithCarryOp
constexpr NEONFormatField NEON_16B
uint32_t NEONAcrossLanesOp
constexpr NEONLSFormatField LS_NEON_1D
constexpr MoveWideImmediateOp MOVZ
constexpr MoveWideImmediateOp MOVN
constexpr int kInt64Size
Definition globals.h:402
constexpr NEONScalarFormatField NEON_H
uint32_t NEONModifiedImmediateOp
constexpr GenericInstrField FP64
uint32_t LoadLiteralOp
uint32_t NEONShiftImmediateOp
constexpr NEONLSFormatField LS_NEON_2D
constexpr NEONFPFormatField NEON_FP_2D
constexpr NEONFormatField NEON_2S
uint32_t ConditionalSelectOp
std::variant< Zone *, AccountingAllocator * > MaybeAssemblerZone
Definition assembler.h:262
const int kSmiTagSize
Definition v8-internal.h:87
uint32_t ConditionalCompareOp
uint32_t FPDataProcessing3SourceOp
constexpr AddrMode Offset
constexpr NEONFormatField NEON_1D
constexpr uint64_t kSmiShiftMask
uint32_t FPDataProcessing2SourceOp
constexpr ShiftOp LSL
constexpr NEONFPFormatField NEON_FP_4S
constexpr NEONLSFormatField LS_NEON_4H
int LaneSizeInBytesLog2FromFormat(VectorFormat vform)
uint32_t DataProcessing3SourceOp
constexpr NEONFormatField NEON_4H
Address Tagged_t
Definition globals.h:547
uint32_t NEON3DifferentOp
constexpr NEONLSFormatField LS_NEON_8H
constexpr int kSmiShift
constexpr NEONFormatField NEON_8H
constexpr unsigned kRegCodeMask
unsigned CalcLSDataSizeLog2(LoadStoreOp op)
constexpr NEONFPFormatField NEON_FP_8H
constexpr int kInt32Size
Definition globals.h:401
constexpr MoveWideImmediateOp MOVK
constexpr NEONLSFormatField LS_NEON_16B
uint32_t LoadStorePairOp
uint32_t NEONLoadStoreMultiStructOp
constexpr NEONFormatField NEON_4S
uint32_t MoveWideImmediateOp
const int kSmiShiftSize
uint32_t NEON2RegMiscOp
constexpr NEONScalarFormatField NEON_D
constexpr NEONFPFormatField NEON_FP_2S
uint32_t NEONLoadStoreSingleStructOp
constexpr NEONFormatField NEON_2D
constexpr NEONScalarFormatField NEON_S
constexpr GenericInstrField FP32
constexpr uint8_t kInstrSize
constexpr int kSPRegInternalCode
constexpr NEONScalarFormatField NEON_B
constexpr NEONLSFormatField LS_NEON_2S
uint32_t DataProcessing1SourceOp
constexpr NEONLSFormatField LS_NEON_8B
std::unique_ptr< AssemblerBuffer > ExternalAssemblerBuffer(void *start, int size)
Definition assembler.cc:161
uint32_t LoadStoreOp
constexpr NEONLSFormatField LS_NEON_4S
uint32_t NEONByIndexedElementOp
uint32_t FPDataProcessing1SourceOp
constexpr NEONFPFormatField NEON_FP_4H
#define NOP(...)
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_INLINE
Definition v8config.h:500
#define V8_UNLIKELY(condition)
Definition v8config.h:660
#define V8_NODISCARD
Definition v8config.h:693
#define ZONE_NAME
Definition zone.h:22