5 #ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ 6 #define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ 10 #include "src/globals.h" 12 #include "src/arm64/assembler-arm64-inl.h" 13 #include "src/arm64/assembler-arm64.h" 14 #include "src/arm64/instrument-arm64.h" 15 #include "src/base/bits.h" 16 #include "src/macro-assembler.h" 22 MemOperand FieldMemOperand(Register
object,
int offset) {
23 return MemOperand(
object, offset - kHeapObjectTag);
27 void TurboAssembler::And(
const Register& rd,
const Register& rn,
28 const Operand& operand) {
29 DCHECK(allow_macro_instructions());
31 LogicalMacro(rd, rn, operand, AND);
34 void TurboAssembler::Ands(
const Register& rd,
const Register& rn,
35 const Operand& operand) {
36 DCHECK(allow_macro_instructions());
38 LogicalMacro(rd, rn, operand, ANDS);
41 void TurboAssembler::Tst(
const Register& rn,
const Operand& operand) {
42 DCHECK(allow_macro_instructions());
43 LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS);
46 void TurboAssembler::Bic(
const Register& rd,
const Register& rn,
47 const Operand& operand) {
48 DCHECK(allow_macro_instructions());
50 LogicalMacro(rd, rn, operand, BIC);
54 void MacroAssembler::Bics(
const Register& rd,
56 const Operand& operand) {
57 DCHECK(allow_macro_instructions());
59 LogicalMacro(rd, rn, operand, BICS);
62 void TurboAssembler::Orr(
const Register& rd,
const Register& rn,
63 const Operand& operand) {
64 DCHECK(allow_macro_instructions());
66 LogicalMacro(rd, rn, operand, ORR);
69 void TurboAssembler::Orn(
const Register& rd,
const Register& rn,
70 const Operand& operand) {
71 DCHECK(allow_macro_instructions());
73 LogicalMacro(rd, rn, operand, ORN);
76 void TurboAssembler::Eor(
const Register& rd,
const Register& rn,
77 const Operand& operand) {
78 DCHECK(allow_macro_instructions());
80 LogicalMacro(rd, rn, operand, EOR);
83 void TurboAssembler::Eon(
const Register& rd,
const Register& rn,
84 const Operand& operand) {
85 DCHECK(allow_macro_instructions());
87 LogicalMacro(rd, rn, operand, EON);
90 void TurboAssembler::Ccmp(
const Register& rn,
const Operand& operand,
91 StatusFlags nzcv, Condition cond) {
92 DCHECK(allow_macro_instructions());
93 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
94 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMN);
96 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
101 void MacroAssembler::Ccmn(
const Register& rn,
102 const Operand& operand,
105 DCHECK(allow_macro_instructions());
106 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
107 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP);
109 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
113 void TurboAssembler::Add(
const Register& rd,
const Register& rn,
114 const Operand& operand) {
115 DCHECK(allow_macro_instructions());
116 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
117 IsImmAddSub(-operand.ImmediateValue())) {
118 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, SUB);
120 AddSubMacro(rd, rn, operand, LeaveFlags, ADD);
124 void TurboAssembler::Adds(
const Register& rd,
const Register& rn,
125 const Operand& operand) {
126 DCHECK(allow_macro_instructions());
127 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
128 IsImmAddSub(-operand.ImmediateValue())) {
129 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, SUB);
131 AddSubMacro(rd, rn, operand, SetFlags, ADD);
135 void TurboAssembler::Sub(
const Register& rd,
const Register& rn,
136 const Operand& operand) {
137 DCHECK(allow_macro_instructions());
138 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
139 IsImmAddSub(-operand.ImmediateValue())) {
140 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, ADD);
142 AddSubMacro(rd, rn, operand, LeaveFlags, SUB);
146 void TurboAssembler::Subs(
const Register& rd,
const Register& rn,
147 const Operand& operand) {
148 DCHECK(allow_macro_instructions());
149 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
150 IsImmAddSub(-operand.ImmediateValue())) {
151 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, ADD);
153 AddSubMacro(rd, rn, operand, SetFlags, SUB);
157 void TurboAssembler::Cmn(
const Register& rn,
const Operand& operand) {
158 DCHECK(allow_macro_instructions());
159 Adds(AppropriateZeroRegFor(rn), rn, operand);
162 void TurboAssembler::Cmp(
const Register& rn,
const Operand& operand) {
163 DCHECK(allow_macro_instructions());
164 Subs(AppropriateZeroRegFor(rn), rn, operand);
167 void TurboAssembler::Neg(
const Register& rd,
const Operand& operand) {
168 DCHECK(allow_macro_instructions());
169 DCHECK(!rd.IsZero());
170 if (operand.IsImmediate()) {
171 Mov(rd, -operand.ImmediateValue());
173 Sub(rd, AppropriateZeroRegFor(rd), operand);
177 void TurboAssembler::Negs(
const Register& rd,
const Operand& operand) {
178 DCHECK(allow_macro_instructions());
179 Subs(rd, AppropriateZeroRegFor(rd), operand);
182 void TurboAssembler::Adc(
const Register& rd,
const Register& rn,
183 const Operand& operand) {
184 DCHECK(allow_macro_instructions());
185 DCHECK(!rd.IsZero());
186 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, ADC);
190 void MacroAssembler::Adcs(
const Register& rd,
192 const Operand& operand) {
193 DCHECK(allow_macro_instructions());
194 DCHECK(!rd.IsZero());
195 AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC);
199 void MacroAssembler::Sbc(
const Register& rd,
201 const Operand& operand) {
202 DCHECK(allow_macro_instructions());
203 DCHECK(!rd.IsZero());
204 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC);
208 void MacroAssembler::Sbcs(
const Register& rd,
210 const Operand& operand) {
211 DCHECK(allow_macro_instructions());
212 DCHECK(!rd.IsZero());
213 AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC);
217 void MacroAssembler::Ngc(
const Register& rd,
218 const Operand& operand) {
219 DCHECK(allow_macro_instructions());
220 DCHECK(!rd.IsZero());
221 Register zr = AppropriateZeroRegFor(rd);
222 Sbc(rd, zr, operand);
226 void MacroAssembler::Ngcs(
const Register& rd,
227 const Operand& operand) {
228 DCHECK(allow_macro_instructions());
229 DCHECK(!rd.IsZero());
230 Register zr = AppropriateZeroRegFor(rd);
231 Sbcs(rd, zr, operand);
234 void TurboAssembler::Mvn(
const Register& rd, uint64_t imm) {
235 DCHECK(allow_macro_instructions());
236 DCHECK(!rd.IsZero());
240 #define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \ 241 void TurboAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \ 242 DCHECK(allow_macro_instructions()); \ 243 LoadStoreMacro(REG, addr, OP); \ 245 LS_MACRO_LIST(DEFINE_FUNCTION)
246 #undef DEFINE_FUNCTION 248 #define DEFINE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \ 249 void TurboAssembler::FN(const REGTYPE REG, const REGTYPE REG2, \ 250 const MemOperand& addr) { \ 251 DCHECK(allow_macro_instructions()); \ 252 LoadStorePairMacro(REG, REG2, addr, OP); \ 254 LSPAIR_MACRO_LIST(DEFINE_FUNCTION)
255 #undef DEFINE_FUNCTION 257 #define DECLARE_FUNCTION(FN, OP) \ 258 void TurboAssembler::FN(const Register& rt, const Register& rn) { \ 259 DCHECK(allow_macro_instructions()); \ 262 LDA_STL_MACRO_LIST(DECLARE_FUNCTION)
263 #undef DECLARE_FUNCTION 265 #define DECLARE_FUNCTION(FN, OP) \ 266 void MacroAssembler::FN(const Register& rs, const Register& rt, \ 267 const Register& rn) { \ 268 DCHECK(allow_macro_instructions()); \ 271 STLX_MACRO_LIST(DECLARE_FUNCTION)
272 #undef DECLARE_FUNCTION 274 void TurboAssembler::Asr(
const Register& rd,
const Register& rn,
276 DCHECK(allow_macro_instructions());
277 DCHECK(!rd.IsZero());
281 void TurboAssembler::Asr(
const Register& rd,
const Register& rn,
282 const Register& rm) {
283 DCHECK(allow_macro_instructions());
284 DCHECK(!rd.IsZero());
288 void TurboAssembler::B(Label* label) {
289 DCHECK(allow_macro_instructions());
291 CheckVeneerPool(
false,
false);
294 void TurboAssembler::B(Condition cond, Label* label) {
295 DCHECK(allow_macro_instructions());
299 void TurboAssembler::Bfi(
const Register& rd,
const Register& rn,
unsigned lsb,
301 DCHECK(allow_macro_instructions());
302 DCHECK(!rd.IsZero());
303 bfi(rd, rn, lsb, width);
307 void MacroAssembler::Bfxil(
const Register& rd,
311 DCHECK(allow_macro_instructions());
312 DCHECK(!rd.IsZero());
313 bfxil(rd, rn, lsb, width);
316 void TurboAssembler::Bind(Label* label) {
317 DCHECK(allow_macro_instructions());
321 void TurboAssembler::Bl(Label* label) {
322 DCHECK(allow_macro_instructions());
326 void TurboAssembler::Blr(
const Register& xn) {
327 DCHECK(allow_macro_instructions());
328 DCHECK(!xn.IsZero());
332 void TurboAssembler::Br(
const Register& xn) {
333 DCHECK(allow_macro_instructions());
334 DCHECK(!xn.IsZero());
338 void TurboAssembler::Brk(
int code) {
339 DCHECK(allow_macro_instructions());
344 void MacroAssembler::Cinc(
const Register& rd,
347 DCHECK(allow_macro_instructions());
348 DCHECK(!rd.IsZero());
349 DCHECK((cond != al) && (cond != nv));
354 void MacroAssembler::Cinv(
const Register& rd,
357 DCHECK(allow_macro_instructions());
358 DCHECK(!rd.IsZero());
359 DCHECK((cond != al) && (cond != nv));
363 void TurboAssembler::Cls(
const Register& rd,
const Register& rn) {
364 DCHECK(allow_macro_instructions());
365 DCHECK(!rd.IsZero());
369 void TurboAssembler::Clz(
const Register& rd,
const Register& rn) {
370 DCHECK(allow_macro_instructions());
371 DCHECK(!rd.IsZero());
375 void TurboAssembler::Cneg(
const Register& rd,
const Register& rn,
377 DCHECK(allow_macro_instructions());
378 DCHECK(!rd.IsZero());
379 DCHECK((cond != al) && (cond != nv));
386 void MacroAssembler::CzeroX(
const Register& rd,
388 DCHECK(allow_macro_instructions());
389 DCHECK(!rd.IsSP() && rd.Is64Bits());
390 DCHECK((cond != al) && (cond != nv));
391 csel(rd, xzr, rd, cond);
397 void TurboAssembler::CmovX(
const Register& rd,
const Register& rn,
399 DCHECK(allow_macro_instructions());
401 DCHECK(rd.Is64Bits() && rn.Is64Bits());
402 DCHECK((cond != al) && (cond != nv));
404 csel(rd, rn, rd, cond);
408 void TurboAssembler::Csdb() {
409 DCHECK(allow_macro_instructions());
413 void TurboAssembler::Cset(
const Register& rd, Condition cond) {
414 DCHECK(allow_macro_instructions());
415 DCHECK(!rd.IsZero());
416 DCHECK((cond != al) && (cond != nv));
420 void TurboAssembler::Csetm(
const Register& rd, Condition cond) {
421 DCHECK(allow_macro_instructions());
422 DCHECK(!rd.IsZero());
423 DCHECK((cond != al) && (cond != nv));
427 void TurboAssembler::Csinc(
const Register& rd,
const Register& rn,
428 const Register& rm, Condition cond) {
429 DCHECK(allow_macro_instructions());
430 DCHECK(!rd.IsZero());
431 DCHECK((cond != al) && (cond != nv));
432 csinc(rd, rn, rm, cond);
436 void MacroAssembler::Csinv(
const Register& rd,
440 DCHECK(allow_macro_instructions());
441 DCHECK(!rd.IsZero());
442 DCHECK((cond != al) && (cond != nv));
443 csinv(rd, rn, rm, cond);
447 void MacroAssembler::Csneg(
const Register& rd,
451 DCHECK(allow_macro_instructions());
452 DCHECK(!rd.IsZero());
453 DCHECK((cond != al) && (cond != nv));
454 csneg(rd, rn, rm, cond);
457 void TurboAssembler::Dmb(BarrierDomain domain, BarrierType type) {
458 DCHECK(allow_macro_instructions());
462 void TurboAssembler::Dsb(BarrierDomain domain, BarrierType type) {
463 DCHECK(allow_macro_instructions());
467 void TurboAssembler::Debug(
const char* message,
uint32_t code, Instr params) {
468 DCHECK(allow_macro_instructions());
469 debug(message, code, params);
473 void MacroAssembler::Extr(
const Register& rd,
477 DCHECK(allow_macro_instructions());
478 DCHECK(!rd.IsZero());
479 extr(rd, rn, rm, lsb);
482 void TurboAssembler::Fabs(
const VRegister& fd,
const VRegister& fn) {
483 DCHECK(allow_macro_instructions());
487 void TurboAssembler::Fadd(
const VRegister& fd,
const VRegister& fn,
488 const VRegister& fm) {
489 DCHECK(allow_macro_instructions());
493 void TurboAssembler::Fccmp(
const VRegister& fn,
const VRegister& fm,
494 StatusFlags nzcv, Condition cond) {
495 DCHECK(allow_macro_instructions());
496 DCHECK((cond != al) && (cond != nv));
497 fccmp(fn, fm, nzcv, cond);
500 void TurboAssembler::Fcmp(
const VRegister& fn,
const VRegister& fm) {
501 DCHECK(allow_macro_instructions());
505 void TurboAssembler::Fcmp(
const VRegister& fn,
double value) {
506 DCHECK(allow_macro_instructions());
508 UseScratchRegisterScope temps(
this);
509 VRegister tmp = temps.AcquireSameSizeAs(fn);
517 void MacroAssembler::Fcsel(
const VRegister& fd,
const VRegister& fn,
518 const VRegister& fm, Condition cond) {
519 DCHECK(allow_macro_instructions());
520 DCHECK((cond != al) && (cond != nv));
521 fcsel(fd, fn, fm, cond);
524 void TurboAssembler::Fcvt(
const VRegister& fd,
const VRegister& fn) {
525 DCHECK(allow_macro_instructions());
529 void TurboAssembler::Fcvtas(
const Register& rd,
const VRegister& fn) {
530 DCHECK(allow_macro_instructions());
531 DCHECK(!rd.IsZero());
535 void TurboAssembler::Fcvtau(
const Register& rd,
const VRegister& fn) {
536 DCHECK(allow_macro_instructions());
537 DCHECK(!rd.IsZero());
541 void TurboAssembler::Fcvtms(
const Register& rd,
const VRegister& fn) {
542 DCHECK(allow_macro_instructions());
543 DCHECK(!rd.IsZero());
547 void TurboAssembler::Fcvtmu(
const Register& rd,
const VRegister& fn) {
548 DCHECK(allow_macro_instructions());
549 DCHECK(!rd.IsZero());
553 void TurboAssembler::Fcvtns(
const Register& rd,
const VRegister& fn) {
554 DCHECK(allow_macro_instructions());
555 DCHECK(!rd.IsZero());
559 void TurboAssembler::Fcvtnu(
const Register& rd,
const VRegister& fn) {
560 DCHECK(allow_macro_instructions());
561 DCHECK(!rd.IsZero());
565 void TurboAssembler::Fcvtzs(
const Register& rd,
const VRegister& fn) {
566 DCHECK(allow_macro_instructions());
567 DCHECK(!rd.IsZero());
570 void TurboAssembler::Fcvtzu(
const Register& rd,
const VRegister& fn) {
571 DCHECK(allow_macro_instructions());
572 DCHECK(!rd.IsZero());
576 void TurboAssembler::Fdiv(
const VRegister& fd,
const VRegister& fn,
577 const VRegister& fm) {
578 DCHECK(allow_macro_instructions());
582 void MacroAssembler::Fmadd(
const VRegister& fd,
const VRegister& fn,
583 const VRegister& fm,
const VRegister& fa) {
584 DCHECK(allow_macro_instructions());
585 fmadd(fd, fn, fm, fa);
588 void TurboAssembler::Fmax(
const VRegister& fd,
const VRegister& fn,
589 const VRegister& fm) {
590 DCHECK(allow_macro_instructions());
594 void MacroAssembler::Fmaxnm(
const VRegister& fd,
const VRegister& fn,
595 const VRegister& fm) {
596 DCHECK(allow_macro_instructions());
600 void TurboAssembler::Fmin(
const VRegister& fd,
const VRegister& fn,
601 const VRegister& fm) {
602 DCHECK(allow_macro_instructions());
606 void MacroAssembler::Fminnm(
const VRegister& fd,
const VRegister& fn,
607 const VRegister& fm) {
608 DCHECK(allow_macro_instructions());
612 void TurboAssembler::Fmov(VRegister fd, VRegister fn) {
613 DCHECK(allow_macro_instructions());
618 if (!fd.Is(fn) || !fd.Is64Bits()) {
623 void TurboAssembler::Fmov(VRegister fd, Register rn) {
624 DCHECK(allow_macro_instructions());
628 void TurboAssembler::Fmov(VRegister vd,
double imm) {
629 DCHECK(allow_macro_instructions());
631 if (vd.Is1S() || vd.Is2S() || vd.Is4S()) {
632 Fmov(vd, static_cast<float>(imm));
636 DCHECK(vd.Is1D() || vd.Is2D());
637 if (IsImmFP64(imm)) {
640 uint64_t bits = bit_cast<uint64_t>(imm);
645 UseScratchRegisterScope temps(
this);
646 Register tmp = temps.AcquireX();
656 void TurboAssembler::Fmov(VRegister vd,
float imm) {
657 DCHECK(allow_macro_instructions());
658 if (vd.Is1D() || vd.Is2D()) {
659 Fmov(vd, static_cast<double>(imm));
663 DCHECK(vd.Is1S() || vd.Is2S() || vd.Is4S());
664 if (IsImmFP32(imm)) {
672 UseScratchRegisterScope temps(
this);
673 Register tmp = temps.AcquireW();
674 Mov(tmp, bit_cast<uint32_t>(imm));
683 void TurboAssembler::Fmov(Register rd, VRegister fn) {
684 DCHECK(allow_macro_instructions());
685 DCHECK(!rd.IsZero());
689 void MacroAssembler::Fmsub(
const VRegister& fd,
const VRegister& fn,
690 const VRegister& fm,
const VRegister& fa) {
691 DCHECK(allow_macro_instructions());
692 fmsub(fd, fn, fm, fa);
695 void TurboAssembler::Fmul(
const VRegister& fd,
const VRegister& fn,
696 const VRegister& fm) {
697 DCHECK(allow_macro_instructions());
701 void MacroAssembler::Fnmadd(
const VRegister& fd,
const VRegister& fn,
702 const VRegister& fm,
const VRegister& fa) {
703 DCHECK(allow_macro_instructions());
704 fnmadd(fd, fn, fm, fa);
707 void MacroAssembler::Fnmsub(
const VRegister& fd,
const VRegister& fn,
708 const VRegister& fm,
const VRegister& fa) {
709 DCHECK(allow_macro_instructions());
710 fnmsub(fd, fn, fm, fa);
713 void TurboAssembler::Fsub(
const VRegister& fd,
const VRegister& fn,
714 const VRegister& fm) {
715 DCHECK(allow_macro_instructions());
720 void MacroAssembler::Hint(SystemHint code) {
721 DCHECK(allow_macro_instructions());
726 void MacroAssembler::Hlt(
int code) {
727 DCHECK(allow_macro_instructions());
731 void TurboAssembler::Isb() {
732 DCHECK(allow_macro_instructions());
736 void TurboAssembler::Ldr(
const CPURegister& rt,
const Operand& operand) {
737 DCHECK(allow_macro_instructions());
741 void TurboAssembler::Lsl(
const Register& rd,
const Register& rn,
743 DCHECK(allow_macro_instructions());
744 DCHECK(!rd.IsZero());
748 void TurboAssembler::Lsl(
const Register& rd,
const Register& rn,
749 const Register& rm) {
750 DCHECK(allow_macro_instructions());
751 DCHECK(!rd.IsZero());
755 void TurboAssembler::Lsr(
const Register& rd,
const Register& rn,
757 DCHECK(allow_macro_instructions());
758 DCHECK(!rd.IsZero());
762 void TurboAssembler::Lsr(
const Register& rd,
const Register& rn,
763 const Register& rm) {
764 DCHECK(allow_macro_instructions());
765 DCHECK(!rd.IsZero());
769 void TurboAssembler::Madd(
const Register& rd,
const Register& rn,
770 const Register& rm,
const Register& ra) {
771 DCHECK(allow_macro_instructions());
772 DCHECK(!rd.IsZero());
773 madd(rd, rn, rm, ra);
776 void TurboAssembler::Mneg(
const Register& rd,
const Register& rn,
777 const Register& rm) {
778 DCHECK(allow_macro_instructions());
779 DCHECK(!rd.IsZero());
783 void MacroAssembler::Movk(
const Register& rd, uint64_t imm,
int shift) {
784 DCHECK(allow_macro_instructions());
785 DCHECK(!rd.IsZero());
786 movk(rd, imm, shift);
789 void TurboAssembler::Mrs(
const Register& rt, SystemRegister sysreg) {
790 DCHECK(allow_macro_instructions());
791 DCHECK(!rt.IsZero());
796 void MacroAssembler::Msr(SystemRegister sysreg,
const Register& rt) {
797 DCHECK(allow_macro_instructions());
801 void TurboAssembler::Msub(
const Register& rd,
const Register& rn,
802 const Register& rm,
const Register& ra) {
803 DCHECK(allow_macro_instructions());
804 DCHECK(!rd.IsZero());
805 msub(rd, rn, rm, ra);
808 void TurboAssembler::Mul(
const Register& rd,
const Register& rn,
809 const Register& rm) {
810 DCHECK(allow_macro_instructions());
811 DCHECK(!rd.IsZero());
815 void TurboAssembler::Rbit(
const Register& rd,
const Register& rn) {
816 DCHECK(allow_macro_instructions());
817 DCHECK(!rd.IsZero());
821 void TurboAssembler::Rev(
const Register& rd,
const Register& rn) {
822 DCHECK(allow_macro_instructions());
823 DCHECK(!rd.IsZero());
827 void TurboAssembler::Ret(
const Register& xn) {
828 DCHECK(allow_macro_instructions());
829 DCHECK(!xn.IsZero());
831 CheckVeneerPool(
false,
false);
835 void MacroAssembler::Rev(
const Register& rd,
const Register& rn) {
836 DCHECK(allow_macro_instructions());
837 DCHECK(!rd.IsZero());
841 void TurboAssembler::Rev16(
const Register& rd,
const Register& rn) {
842 DCHECK(allow_macro_instructions());
843 DCHECK(!rd.IsZero());
847 void TurboAssembler::Rev32(
const Register& rd,
const Register& rn) {
848 DCHECK(allow_macro_instructions());
849 DCHECK(!rd.IsZero());
853 void TurboAssembler::Ror(
const Register& rd,
const Register& rs,
855 DCHECK(allow_macro_instructions());
856 DCHECK(!rd.IsZero());
860 void TurboAssembler::Ror(
const Register& rd,
const Register& rn,
861 const Register& rm) {
862 DCHECK(allow_macro_instructions());
863 DCHECK(!rd.IsZero());
868 void MacroAssembler::Sbfiz(
const Register& rd,
872 DCHECK(allow_macro_instructions());
873 DCHECK(!rd.IsZero());
874 sbfiz(rd, rn, lsb, width);
877 void TurboAssembler::Sbfx(
const Register& rd,
const Register& rn,
unsigned lsb,
879 DCHECK(allow_macro_instructions());
880 DCHECK(!rd.IsZero());
881 sbfx(rd, rn, lsb, width);
884 void TurboAssembler::Scvtf(
const VRegister& fd,
const Register& rn,
886 DCHECK(allow_macro_instructions());
887 scvtf(fd, rn, fbits);
890 void TurboAssembler::Sdiv(
const Register& rd,
const Register& rn,
891 const Register& rm) {
892 DCHECK(allow_macro_instructions());
893 DCHECK(!rd.IsZero());
898 void MacroAssembler::Smaddl(
const Register& rd,
901 const Register& ra) {
902 DCHECK(allow_macro_instructions());
903 DCHECK(!rd.IsZero());
904 smaddl(rd, rn, rm, ra);
908 void MacroAssembler::Smsubl(
const Register& rd,
911 const Register& ra) {
912 DCHECK(allow_macro_instructions());
913 DCHECK(!rd.IsZero());
914 smsubl(rd, rn, rm, ra);
917 void TurboAssembler::Smull(
const Register& rd,
const Register& rn,
918 const Register& rm) {
919 DCHECK(allow_macro_instructions());
920 DCHECK(!rd.IsZero());
925 void MacroAssembler::Smulh(
const Register& rd,
927 const Register& rm) {
928 DCHECK(allow_macro_instructions());
929 DCHECK(!rd.IsZero());
933 void TurboAssembler::Umull(
const Register& rd,
const Register& rn,
934 const Register& rm) {
935 DCHECK(allow_macro_instructions());
936 DCHECK(!rd.IsZero());
937 umaddl(rd, rn, rm, xzr);
940 void TurboAssembler::Sxtb(
const Register& rd,
const Register& rn) {
941 DCHECK(allow_macro_instructions());
942 DCHECK(!rd.IsZero());
946 void TurboAssembler::Sxth(
const Register& rd,
const Register& rn) {
947 DCHECK(allow_macro_instructions());
948 DCHECK(!rd.IsZero());
952 void TurboAssembler::Sxtw(
const Register& rd,
const Register& rn) {
953 DCHECK(allow_macro_instructions());
954 DCHECK(!rd.IsZero());
958 void TurboAssembler::Ubfiz(
const Register& rd,
const Register& rn,
unsigned lsb,
960 DCHECK(allow_macro_instructions());
961 DCHECK(!rd.IsZero());
962 ubfiz(rd, rn, lsb, width);
965 void TurboAssembler::Ubfx(
const Register& rd,
const Register& rn,
unsigned lsb,
967 DCHECK(allow_macro_instructions());
968 DCHECK(!rd.IsZero());
969 ubfx(rd, rn, lsb, width);
972 void TurboAssembler::Ucvtf(
const VRegister& fd,
const Register& rn,
974 DCHECK(allow_macro_instructions());
975 ucvtf(fd, rn, fbits);
978 void TurboAssembler::Udiv(
const Register& rd,
const Register& rn,
979 const Register& rm) {
980 DCHECK(allow_macro_instructions());
981 DCHECK(!rd.IsZero());
986 void MacroAssembler::Umaddl(
const Register& rd,
989 const Register& ra) {
990 DCHECK(allow_macro_instructions());
991 DCHECK(!rd.IsZero());
992 umaddl(rd, rn, rm, ra);
996 void MacroAssembler::Umsubl(
const Register& rd,
999 const Register& ra) {
1000 DCHECK(allow_macro_instructions());
1001 DCHECK(!rd.IsZero());
1002 umsubl(rd, rn, rm, ra);
1005 void TurboAssembler::Uxtb(
const Register& rd,
const Register& rn) {
1006 DCHECK(allow_macro_instructions());
1007 DCHECK(!rd.IsZero());
1011 void TurboAssembler::Uxth(
const Register& rd,
const Register& rn) {
1012 DCHECK(allow_macro_instructions());
1013 DCHECK(!rd.IsZero());
1017 void TurboAssembler::Uxtw(
const Register& rd,
const Register& rn) {
1018 DCHECK(allow_macro_instructions());
1019 DCHECK(!rd.IsZero());
1023 void TurboAssembler::InitializeRootRegister() {
1024 ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
1025 Mov(kRootRegister, Operand(isolate_root));
1029 void MacroAssembler::SmiTag(Register dst, Register src) {
1030 DCHECK(dst.Is64Bits() && src.Is64Bits());
1031 DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
1032 Lsl(dst, src, kSmiShift);
1035 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); }
1037 void TurboAssembler::SmiUntag(Register dst, Register src) {
1038 DCHECK(dst.Is64Bits() && src.Is64Bits());
1039 if (FLAG_enable_slow_asserts) {
1042 DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
1043 Asr(dst, src, kSmiShift);
1046 void TurboAssembler::SmiUntag(Register dst,
const MemOperand& src) {
1047 DCHECK(dst.Is64Bits());
1048 if (SmiValuesAre32Bits()) {
1049 if (src.IsImmediateOffset() && src.shift_amount() == 0) {
1052 DCHECK_EQ(kSmiShift, 32);
1054 MemOperand(src.base(), src.offset() + (kSmiShift / kBitsPerByte),
1062 DCHECK(SmiValuesAre31Bits());
1068 void TurboAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); }
1070 void TurboAssembler::JumpIfSmi(Register value, Label* smi_label,
1071 Label* not_smi_label) {
1072 STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1075 Tbz(value, 0, smi_label);
1076 if (not_smi_label) {
1080 DCHECK(not_smi_label);
1081 Tbnz(value, 0, not_smi_label);
1085 void TurboAssembler::JumpIfEqual(Register x, int32_t y, Label* dest) {
1090 void TurboAssembler::JumpIfLessThan(Register x, int32_t y, Label* dest) {
1095 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) {
1096 JumpIfSmi(value,
nullptr, not_smi_label);
1100 void MacroAssembler::JumpIfBothSmi(Register value1,
1102 Label* both_smi_label,
1103 Label* not_smi_label) {
1104 STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1105 UseScratchRegisterScope temps(
this);
1106 Register tmp = temps.AcquireX();
1108 Orr(tmp, value1, value2);
1109 JumpIfSmi(tmp, both_smi_label, not_smi_label);
1113 void MacroAssembler::JumpIfEitherSmi(Register value1,
1115 Label* either_smi_label,
1116 Label* not_smi_label) {
1117 STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1118 UseScratchRegisterScope temps(
this);
1119 Register tmp = temps.AcquireX();
1121 And(tmp, value1, value2);
1122 JumpIfSmi(tmp, either_smi_label, not_smi_label);
1126 void MacroAssembler::JumpIfEitherNotSmi(Register value1,
1128 Label* not_smi_label) {
1129 JumpIfBothSmi(value1, value2,
nullptr, not_smi_label);
1133 void MacroAssembler::JumpIfBothNotSmi(Register value1,
1135 Label* not_smi_label) {
1136 JumpIfEitherSmi(value1, value2,
nullptr, not_smi_label);
1140 void MacroAssembler::ObjectTag(Register tagged_obj, Register obj) {
1141 STATIC_ASSERT(kHeapObjectTag == 1);
1142 if (emit_debug_code()) {
1145 Abort(AbortReason::kObjectTagged);
1148 Orr(tagged_obj, obj, kHeapObjectTag);
1152 void MacroAssembler::ObjectUntag(Register untagged_obj, Register obj) {
1153 STATIC_ASSERT(kHeapObjectTag == 1);
1154 if (emit_debug_code()) {
1157 Abort(AbortReason::kObjectNotTagged);
1160 Bic(untagged_obj, obj, kHeapObjectTag);
1163 void TurboAssembler::jmp(Label* L) { B(L); }
1165 void TurboAssembler::Push(Handle<HeapObject> handle) {
1166 UseScratchRegisterScope temps(
this);
1167 Register tmp = temps.AcquireX();
1168 Mov(tmp, Operand(handle));
1175 void TurboAssembler::Push(Smi smi) {
1176 UseScratchRegisterScope temps(
this);
1177 Register tmp = temps.AcquireX();
1178 Mov(tmp, Operand(smi));
1182 void TurboAssembler::Claim(
int64_t count, uint64_t unit_size) {
1183 DCHECK_GE(count, 0);
1184 uint64_t size = count * unit_size;
1189 DCHECK_EQ(size % 16, 0);
1194 void TurboAssembler::Claim(
const Register& count, uint64_t unit_size) {
1195 if (unit_size == 0)
return;
1196 DCHECK(base::bits::IsPowerOfTwo(unit_size));
1198 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1199 const Operand size(count, LSL, shift);
1201 if (size.IsZero()) {
1204 AssertPositiveOrZero(count);
1210 void MacroAssembler::ClaimBySMI(
const Register& count_smi, uint64_t unit_size) {
1211 DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo(unit_size));
1212 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
1213 const Operand size(count_smi,
1214 (shift >= 0) ? (LSL) : (LSR),
1215 (shift >= 0) ? (shift) : (-shift));
1217 if (size.IsZero()) {
1224 void TurboAssembler::Drop(
int64_t count, uint64_t unit_size) {
1225 DCHECK_GE(count, 0);
1226 uint64_t size = count * unit_size;
1233 DCHECK_EQ(size % 16, 0);
1236 void TurboAssembler::Drop(
const Register& count, uint64_t unit_size) {
1237 if (unit_size == 0)
return;
1238 DCHECK(base::bits::IsPowerOfTwo(unit_size));
1240 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1241 const Operand size(count, LSL, shift);
1243 if (size.IsZero()) {
1247 AssertPositiveOrZero(count);
1251 void TurboAssembler::DropArguments(
const Register& count,
1252 ArgumentsCountMode mode) {
1253 int extra_slots = 1;
1254 if (mode == kCountExcludesReceiver) {
1258 UseScratchRegisterScope temps(
this);
1259 Register tmp = temps.AcquireX();
1260 Add(tmp, count, extra_slots);
1262 Drop(tmp, kXRegSize);
1265 void TurboAssembler::DropArguments(
int64_t count, ArgumentsCountMode mode) {
1266 if (mode == kCountExcludesReceiver) {
1270 Drop(RoundUp(count, 2), kXRegSize);
1273 void TurboAssembler::DropSlots(
int64_t count) {
1274 Drop(RoundUp(count, 2), kXRegSize);
1277 void TurboAssembler::PushArgument(
const Register& arg) { Push(padreg, arg); }
1279 void MacroAssembler::DropBySMI(
const Register& count_smi, uint64_t unit_size) {
1280 DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo(unit_size));
1281 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
1282 const Operand size(count_smi,
1283 (shift >= 0) ? (LSL) : (LSR),
1284 (shift >= 0) ? (shift) : (-shift));
1286 if (size.IsZero()) {
1294 void MacroAssembler::CompareAndBranch(
const Register& lhs,
1298 if (rhs.IsImmediate() && (rhs.ImmediateValue() == 0) &&
1299 ((cond == eq) || (cond == ne))) {
1311 void TurboAssembler::TestAndBranchIfAnySet(
const Register& reg,
1312 const uint64_t bit_pattern,
1314 int bits = reg.SizeInBits();
1315 DCHECK_GT(CountSetBits(bit_pattern, bits), 0);
1316 if (CountSetBits(bit_pattern, bits) == 1) {
1317 Tbnz(reg, MaskToBit(bit_pattern), label);
1319 Tst(reg, bit_pattern);
1324 void TurboAssembler::TestAndBranchIfAllClear(
const Register& reg,
1325 const uint64_t bit_pattern,
1327 int bits = reg.SizeInBits();
1328 DCHECK_GT(CountSetBits(bit_pattern, bits), 0);
1329 if (CountSetBits(bit_pattern, bits) == 1) {
1330 Tbz(reg, MaskToBit(bit_pattern), label);
1332 Tst(reg, bit_pattern);
1338 void MacroAssembler::InlineData(uint64_t data) {
1339 DCHECK(is_uint16(data));
1340 InstructionAccurateScope scope(
this, 1);
1345 void MacroAssembler::EnableInstrumentation() {
1346 InstructionAccurateScope scope(
this, 1);
1347 movn(xzr, InstrumentStateEnable);
1351 void MacroAssembler::DisableInstrumentation() {
1352 InstructionAccurateScope scope(
this, 1);
1353 movn(xzr, InstrumentStateDisable);
1357 void MacroAssembler::AnnotateInstrumentation(
const char* marker_name) {
1358 DCHECK_EQ(strlen(marker_name), 2);
1362 DCHECK(isprint(marker_name[0]) && isprint(marker_name[1]));
1364 InstructionAccurateScope scope(
this, 1);
1365 movn(xzr, (marker_name[1] << 8) | marker_name[0]);
1371 #endif // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_