V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
macro-assembler-arm64-inl.h
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_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
6 #define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
7 
8 #include <ctype.h>
9 
10 #include "src/globals.h"
11 
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"
17 
18 namespace v8 {
19 namespace internal {
20 
21 
22 MemOperand FieldMemOperand(Register object, int offset) {
23  return MemOperand(object, offset - kHeapObjectTag);
24 }
25 
26 
27 void TurboAssembler::And(const Register& rd, const Register& rn,
28  const Operand& operand) {
29  DCHECK(allow_macro_instructions());
30  DCHECK(!rd.IsZero());
31  LogicalMacro(rd, rn, operand, AND);
32 }
33 
34 void TurboAssembler::Ands(const Register& rd, const Register& rn,
35  const Operand& operand) {
36  DCHECK(allow_macro_instructions());
37  DCHECK(!rd.IsZero());
38  LogicalMacro(rd, rn, operand, ANDS);
39 }
40 
41 void TurboAssembler::Tst(const Register& rn, const Operand& operand) {
42  DCHECK(allow_macro_instructions());
43  LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS);
44 }
45 
46 void TurboAssembler::Bic(const Register& rd, const Register& rn,
47  const Operand& operand) {
48  DCHECK(allow_macro_instructions());
49  DCHECK(!rd.IsZero());
50  LogicalMacro(rd, rn, operand, BIC);
51 }
52 
53 
54 void MacroAssembler::Bics(const Register& rd,
55  const Register& rn,
56  const Operand& operand) {
57  DCHECK(allow_macro_instructions());
58  DCHECK(!rd.IsZero());
59  LogicalMacro(rd, rn, operand, BICS);
60 }
61 
62 void TurboAssembler::Orr(const Register& rd, const Register& rn,
63  const Operand& operand) {
64  DCHECK(allow_macro_instructions());
65  DCHECK(!rd.IsZero());
66  LogicalMacro(rd, rn, operand, ORR);
67 }
68 
69 void TurboAssembler::Orn(const Register& rd, const Register& rn,
70  const Operand& operand) {
71  DCHECK(allow_macro_instructions());
72  DCHECK(!rd.IsZero());
73  LogicalMacro(rd, rn, operand, ORN);
74 }
75 
76 void TurboAssembler::Eor(const Register& rd, const Register& rn,
77  const Operand& operand) {
78  DCHECK(allow_macro_instructions());
79  DCHECK(!rd.IsZero());
80  LogicalMacro(rd, rn, operand, EOR);
81 }
82 
83 void TurboAssembler::Eon(const Register& rd, const Register& rn,
84  const Operand& operand) {
85  DCHECK(allow_macro_instructions());
86  DCHECK(!rd.IsZero());
87  LogicalMacro(rd, rn, operand, EON);
88 }
89 
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);
95  } else {
96  ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
97  }
98 }
99 
100 
101 void MacroAssembler::Ccmn(const Register& rn,
102  const Operand& operand,
103  StatusFlags nzcv,
104  Condition cond) {
105  DCHECK(allow_macro_instructions());
106  if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
107  ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP);
108  } else {
109  ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
110  }
111 }
112 
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);
119  } else {
120  AddSubMacro(rd, rn, operand, LeaveFlags, ADD);
121  }
122 }
123 
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);
130  } else {
131  AddSubMacro(rd, rn, operand, SetFlags, ADD);
132  }
133 }
134 
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);
141  } else {
142  AddSubMacro(rd, rn, operand, LeaveFlags, SUB);
143  }
144 }
145 
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);
152  } else {
153  AddSubMacro(rd, rn, operand, SetFlags, SUB);
154  }
155 }
156 
157 void TurboAssembler::Cmn(const Register& rn, const Operand& operand) {
158  DCHECK(allow_macro_instructions());
159  Adds(AppropriateZeroRegFor(rn), rn, operand);
160 }
161 
162 void TurboAssembler::Cmp(const Register& rn, const Operand& operand) {
163  DCHECK(allow_macro_instructions());
164  Subs(AppropriateZeroRegFor(rn), rn, operand);
165 }
166 
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());
172  } else {
173  Sub(rd, AppropriateZeroRegFor(rd), operand);
174  }
175 }
176 
177 void TurboAssembler::Negs(const Register& rd, const Operand& operand) {
178  DCHECK(allow_macro_instructions());
179  Subs(rd, AppropriateZeroRegFor(rd), operand);
180 }
181 
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);
187 }
188 
189 
190 void MacroAssembler::Adcs(const Register& rd,
191  const Register& rn,
192  const Operand& operand) {
193  DCHECK(allow_macro_instructions());
194  DCHECK(!rd.IsZero());
195  AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC);
196 }
197 
198 
199 void MacroAssembler::Sbc(const Register& rd,
200  const Register& rn,
201  const Operand& operand) {
202  DCHECK(allow_macro_instructions());
203  DCHECK(!rd.IsZero());
204  AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC);
205 }
206 
207 
208 void MacroAssembler::Sbcs(const Register& rd,
209  const Register& rn,
210  const Operand& operand) {
211  DCHECK(allow_macro_instructions());
212  DCHECK(!rd.IsZero());
213  AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC);
214 }
215 
216 
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);
223 }
224 
225 
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);
232 }
233 
234 void TurboAssembler::Mvn(const Register& rd, uint64_t imm) {
235  DCHECK(allow_macro_instructions());
236  DCHECK(!rd.IsZero());
237  Mov(rd, ~imm);
238 }
239 
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); \
244  }
245 LS_MACRO_LIST(DEFINE_FUNCTION)
246 #undef DEFINE_FUNCTION
247 
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); \
253  }
254 LSPAIR_MACRO_LIST(DEFINE_FUNCTION)
255 #undef DEFINE_FUNCTION
256 
257 #define DECLARE_FUNCTION(FN, OP) \
258  void TurboAssembler::FN(const Register& rt, const Register& rn) { \
259  DCHECK(allow_macro_instructions()); \
260  OP(rt, rn); \
261  }
262 LDA_STL_MACRO_LIST(DECLARE_FUNCTION)
263 #undef DECLARE_FUNCTION
264 
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()); \
269  OP(rs, rt, rn); \
270  }
271 STLX_MACRO_LIST(DECLARE_FUNCTION)
272 #undef DECLARE_FUNCTION
273 
274 void TurboAssembler::Asr(const Register& rd, const Register& rn,
275  unsigned shift) {
276  DCHECK(allow_macro_instructions());
277  DCHECK(!rd.IsZero());
278  asr(rd, rn, shift);
279 }
280 
281 void TurboAssembler::Asr(const Register& rd, const Register& rn,
282  const Register& rm) {
283  DCHECK(allow_macro_instructions());
284  DCHECK(!rd.IsZero());
285  asrv(rd, rn, rm);
286 }
287 
288 void TurboAssembler::B(Label* label) {
289  DCHECK(allow_macro_instructions());
290  b(label);
291  CheckVeneerPool(false, false);
292 }
293 
294 void TurboAssembler::B(Condition cond, Label* label) {
295  DCHECK(allow_macro_instructions());
296  B(label, cond);
297 }
298 
299 void TurboAssembler::Bfi(const Register& rd, const Register& rn, unsigned lsb,
300  unsigned width) {
301  DCHECK(allow_macro_instructions());
302  DCHECK(!rd.IsZero());
303  bfi(rd, rn, lsb, width);
304 }
305 
306 
307 void MacroAssembler::Bfxil(const Register& rd,
308  const Register& rn,
309  unsigned lsb,
310  unsigned width) {
311  DCHECK(allow_macro_instructions());
312  DCHECK(!rd.IsZero());
313  bfxil(rd, rn, lsb, width);
314 }
315 
316 void TurboAssembler::Bind(Label* label) {
317  DCHECK(allow_macro_instructions());
318  bind(label);
319 }
320 
321 void TurboAssembler::Bl(Label* label) {
322  DCHECK(allow_macro_instructions());
323  bl(label);
324 }
325 
326 void TurboAssembler::Blr(const Register& xn) {
327  DCHECK(allow_macro_instructions());
328  DCHECK(!xn.IsZero());
329  blr(xn);
330 }
331 
332 void TurboAssembler::Br(const Register& xn) {
333  DCHECK(allow_macro_instructions());
334  DCHECK(!xn.IsZero());
335  br(xn);
336 }
337 
338 void TurboAssembler::Brk(int code) {
339  DCHECK(allow_macro_instructions());
340  brk(code);
341 }
342 
343 
344 void MacroAssembler::Cinc(const Register& rd,
345  const Register& rn,
346  Condition cond) {
347  DCHECK(allow_macro_instructions());
348  DCHECK(!rd.IsZero());
349  DCHECK((cond != al) && (cond != nv));
350  cinc(rd, rn, cond);
351 }
352 
353 
354 void MacroAssembler::Cinv(const Register& rd,
355  const Register& rn,
356  Condition cond) {
357  DCHECK(allow_macro_instructions());
358  DCHECK(!rd.IsZero());
359  DCHECK((cond != al) && (cond != nv));
360  cinv(rd, rn, cond);
361 }
362 
363 void TurboAssembler::Cls(const Register& rd, const Register& rn) {
364  DCHECK(allow_macro_instructions());
365  DCHECK(!rd.IsZero());
366  cls(rd, rn);
367 }
368 
369 void TurboAssembler::Clz(const Register& rd, const Register& rn) {
370  DCHECK(allow_macro_instructions());
371  DCHECK(!rd.IsZero());
372  clz(rd, rn);
373 }
374 
375 void TurboAssembler::Cneg(const Register& rd, const Register& rn,
376  Condition cond) {
377  DCHECK(allow_macro_instructions());
378  DCHECK(!rd.IsZero());
379  DCHECK((cond != al) && (cond != nv));
380  cneg(rd, rn, cond);
381 }
382 
383 
384 // Conditionally zero the destination register. Only X registers are supported
385 // due to the truncation side-effect when used on W registers.
386 void MacroAssembler::CzeroX(const Register& rd,
387  Condition cond) {
388  DCHECK(allow_macro_instructions());
389  DCHECK(!rd.IsSP() && rd.Is64Bits());
390  DCHECK((cond != al) && (cond != nv));
391  csel(rd, xzr, rd, cond);
392 }
393 
394 
395 // Conditionally move a value into the destination register. Only X registers
396 // are supported due to the truncation side-effect when used on W registers.
397 void TurboAssembler::CmovX(const Register& rd, const Register& rn,
398  Condition cond) {
399  DCHECK(allow_macro_instructions());
400  DCHECK(!rd.IsSP());
401  DCHECK(rd.Is64Bits() && rn.Is64Bits());
402  DCHECK((cond != al) && (cond != nv));
403  if (!rd.is(rn)) {
404  csel(rd, rn, rd, cond);
405  }
406 }
407 
408 void TurboAssembler::Csdb() {
409  DCHECK(allow_macro_instructions());
410  csdb();
411 }
412 
413 void TurboAssembler::Cset(const Register& rd, Condition cond) {
414  DCHECK(allow_macro_instructions());
415  DCHECK(!rd.IsZero());
416  DCHECK((cond != al) && (cond != nv));
417  cset(rd, cond);
418 }
419 
420 void TurboAssembler::Csetm(const Register& rd, Condition cond) {
421  DCHECK(allow_macro_instructions());
422  DCHECK(!rd.IsZero());
423  DCHECK((cond != al) && (cond != nv));
424  csetm(rd, cond);
425 }
426 
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);
433 }
434 
435 
436 void MacroAssembler::Csinv(const Register& rd,
437  const Register& rn,
438  const Register& rm,
439  Condition cond) {
440  DCHECK(allow_macro_instructions());
441  DCHECK(!rd.IsZero());
442  DCHECK((cond != al) && (cond != nv));
443  csinv(rd, rn, rm, cond);
444 }
445 
446 
447 void MacroAssembler::Csneg(const Register& rd,
448  const Register& rn,
449  const Register& rm,
450  Condition cond) {
451  DCHECK(allow_macro_instructions());
452  DCHECK(!rd.IsZero());
453  DCHECK((cond != al) && (cond != nv));
454  csneg(rd, rn, rm, cond);
455 }
456 
457 void TurboAssembler::Dmb(BarrierDomain domain, BarrierType type) {
458  DCHECK(allow_macro_instructions());
459  dmb(domain, type);
460 }
461 
462 void TurboAssembler::Dsb(BarrierDomain domain, BarrierType type) {
463  DCHECK(allow_macro_instructions());
464  dsb(domain, type);
465 }
466 
467 void TurboAssembler::Debug(const char* message, uint32_t code, Instr params) {
468  DCHECK(allow_macro_instructions());
469  debug(message, code, params);
470 }
471 
472 
473 void MacroAssembler::Extr(const Register& rd,
474  const Register& rn,
475  const Register& rm,
476  unsigned lsb) {
477  DCHECK(allow_macro_instructions());
478  DCHECK(!rd.IsZero());
479  extr(rd, rn, rm, lsb);
480 }
481 
482 void TurboAssembler::Fabs(const VRegister& fd, const VRegister& fn) {
483  DCHECK(allow_macro_instructions());
484  fabs(fd, fn);
485 }
486 
487 void TurboAssembler::Fadd(const VRegister& fd, const VRegister& fn,
488  const VRegister& fm) {
489  DCHECK(allow_macro_instructions());
490  fadd(fd, fn, fm);
491 }
492 
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);
498 }
499 
500 void TurboAssembler::Fcmp(const VRegister& fn, const VRegister& fm) {
501  DCHECK(allow_macro_instructions());
502  fcmp(fn, fm);
503 }
504 
505 void TurboAssembler::Fcmp(const VRegister& fn, double value) {
506  DCHECK(allow_macro_instructions());
507  if (value != 0.0) {
508  UseScratchRegisterScope temps(this);
509  VRegister tmp = temps.AcquireSameSizeAs(fn);
510  Fmov(tmp, value);
511  fcmp(fn, tmp);
512  } else {
513  fcmp(fn, value);
514  }
515 }
516 
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);
522 }
523 
524 void TurboAssembler::Fcvt(const VRegister& fd, const VRegister& fn) {
525  DCHECK(allow_macro_instructions());
526  fcvt(fd, fn);
527 }
528 
529 void TurboAssembler::Fcvtas(const Register& rd, const VRegister& fn) {
530  DCHECK(allow_macro_instructions());
531  DCHECK(!rd.IsZero());
532  fcvtas(rd, fn);
533 }
534 
535 void TurboAssembler::Fcvtau(const Register& rd, const VRegister& fn) {
536  DCHECK(allow_macro_instructions());
537  DCHECK(!rd.IsZero());
538  fcvtau(rd, fn);
539 }
540 
541 void TurboAssembler::Fcvtms(const Register& rd, const VRegister& fn) {
542  DCHECK(allow_macro_instructions());
543  DCHECK(!rd.IsZero());
544  fcvtms(rd, fn);
545 }
546 
547 void TurboAssembler::Fcvtmu(const Register& rd, const VRegister& fn) {
548  DCHECK(allow_macro_instructions());
549  DCHECK(!rd.IsZero());
550  fcvtmu(rd, fn);
551 }
552 
553 void TurboAssembler::Fcvtns(const Register& rd, const VRegister& fn) {
554  DCHECK(allow_macro_instructions());
555  DCHECK(!rd.IsZero());
556  fcvtns(rd, fn);
557 }
558 
559 void TurboAssembler::Fcvtnu(const Register& rd, const VRegister& fn) {
560  DCHECK(allow_macro_instructions());
561  DCHECK(!rd.IsZero());
562  fcvtnu(rd, fn);
563 }
564 
565 void TurboAssembler::Fcvtzs(const Register& rd, const VRegister& fn) {
566  DCHECK(allow_macro_instructions());
567  DCHECK(!rd.IsZero());
568  fcvtzs(rd, fn);
569 }
570 void TurboAssembler::Fcvtzu(const Register& rd, const VRegister& fn) {
571  DCHECK(allow_macro_instructions());
572  DCHECK(!rd.IsZero());
573  fcvtzu(rd, fn);
574 }
575 
576 void TurboAssembler::Fdiv(const VRegister& fd, const VRegister& fn,
577  const VRegister& fm) {
578  DCHECK(allow_macro_instructions());
579  fdiv(fd, fn, fm);
580 }
581 
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);
586 }
587 
588 void TurboAssembler::Fmax(const VRegister& fd, const VRegister& fn,
589  const VRegister& fm) {
590  DCHECK(allow_macro_instructions());
591  fmax(fd, fn, fm);
592 }
593 
594 void MacroAssembler::Fmaxnm(const VRegister& fd, const VRegister& fn,
595  const VRegister& fm) {
596  DCHECK(allow_macro_instructions());
597  fmaxnm(fd, fn, fm);
598 }
599 
600 void TurboAssembler::Fmin(const VRegister& fd, const VRegister& fn,
601  const VRegister& fm) {
602  DCHECK(allow_macro_instructions());
603  fmin(fd, fn, fm);
604 }
605 
606 void MacroAssembler::Fminnm(const VRegister& fd, const VRegister& fn,
607  const VRegister& fm) {
608  DCHECK(allow_macro_instructions());
609  fminnm(fd, fn, fm);
610 }
611 
612 void TurboAssembler::Fmov(VRegister fd, VRegister fn) {
613  DCHECK(allow_macro_instructions());
614  // Only emit an instruction if fd and fn are different, and they are both D
615  // registers. fmov(s0, s0) is not a no-op because it clears the top word of
616  // d0. Technically, fmov(d0, d0) is not a no-op either because it clears the
617  // top of q0, but VRegister does not currently support Q registers.
618  if (!fd.Is(fn) || !fd.Is64Bits()) {
619  fmov(fd, fn);
620  }
621 }
622 
623 void TurboAssembler::Fmov(VRegister fd, Register rn) {
624  DCHECK(allow_macro_instructions());
625  fmov(fd, rn);
626 }
627 
628 void TurboAssembler::Fmov(VRegister vd, double imm) {
629  DCHECK(allow_macro_instructions());
630 
631  if (vd.Is1S() || vd.Is2S() || vd.Is4S()) {
632  Fmov(vd, static_cast<float>(imm));
633  return;
634  }
635 
636  DCHECK(vd.Is1D() || vd.Is2D());
637  if (IsImmFP64(imm)) {
638  fmov(vd, imm);
639  } else {
640  uint64_t bits = bit_cast<uint64_t>(imm);
641  if (vd.IsScalar()) {
642  if (bits == 0) {
643  fmov(vd, xzr);
644  } else {
645  UseScratchRegisterScope temps(this);
646  Register tmp = temps.AcquireX();
647  Mov(tmp, bits);
648  fmov(vd, tmp);
649  }
650  } else {
651  Movi(vd, bits);
652  }
653  }
654 }
655 
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));
660  return;
661  }
662 
663  DCHECK(vd.Is1S() || vd.Is2S() || vd.Is4S());
664  if (IsImmFP32(imm)) {
665  fmov(vd, imm);
666  } else {
667  uint32_t bits = bit_cast<uint32_t>(imm);
668  if (vd.IsScalar()) {
669  if (bits == 0) {
670  fmov(vd, wzr);
671  } else {
672  UseScratchRegisterScope temps(this);
673  Register tmp = temps.AcquireW();
674  Mov(tmp, bit_cast<uint32_t>(imm));
675  Fmov(vd, tmp);
676  }
677  } else {
678  Movi(vd, bits);
679  }
680  }
681 }
682 
683 void TurboAssembler::Fmov(Register rd, VRegister fn) {
684  DCHECK(allow_macro_instructions());
685  DCHECK(!rd.IsZero());
686  fmov(rd, fn);
687 }
688 
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);
693 }
694 
695 void TurboAssembler::Fmul(const VRegister& fd, const VRegister& fn,
696  const VRegister& fm) {
697  DCHECK(allow_macro_instructions());
698  fmul(fd, fn, fm);
699 }
700 
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);
705 }
706 
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);
711 }
712 
713 void TurboAssembler::Fsub(const VRegister& fd, const VRegister& fn,
714  const VRegister& fm) {
715  DCHECK(allow_macro_instructions());
716  fsub(fd, fn, fm);
717 }
718 
719 
720 void MacroAssembler::Hint(SystemHint code) {
721  DCHECK(allow_macro_instructions());
722  hint(code);
723 }
724 
725 
726 void MacroAssembler::Hlt(int code) {
727  DCHECK(allow_macro_instructions());
728  hlt(code);
729 }
730 
731 void TurboAssembler::Isb() {
732  DCHECK(allow_macro_instructions());
733  isb();
734 }
735 
736 void TurboAssembler::Ldr(const CPURegister& rt, const Operand& operand) {
737  DCHECK(allow_macro_instructions());
738  ldr(rt, operand);
739 }
740 
741 void TurboAssembler::Lsl(const Register& rd, const Register& rn,
742  unsigned shift) {
743  DCHECK(allow_macro_instructions());
744  DCHECK(!rd.IsZero());
745  lsl(rd, rn, shift);
746 }
747 
748 void TurboAssembler::Lsl(const Register& rd, const Register& rn,
749  const Register& rm) {
750  DCHECK(allow_macro_instructions());
751  DCHECK(!rd.IsZero());
752  lslv(rd, rn, rm);
753 }
754 
755 void TurboAssembler::Lsr(const Register& rd, const Register& rn,
756  unsigned shift) {
757  DCHECK(allow_macro_instructions());
758  DCHECK(!rd.IsZero());
759  lsr(rd, rn, shift);
760 }
761 
762 void TurboAssembler::Lsr(const Register& rd, const Register& rn,
763  const Register& rm) {
764  DCHECK(allow_macro_instructions());
765  DCHECK(!rd.IsZero());
766  lsrv(rd, rn, rm);
767 }
768 
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);
774 }
775 
776 void TurboAssembler::Mneg(const Register& rd, const Register& rn,
777  const Register& rm) {
778  DCHECK(allow_macro_instructions());
779  DCHECK(!rd.IsZero());
780  mneg(rd, rn, rm);
781 }
782 
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);
787 }
788 
789 void TurboAssembler::Mrs(const Register& rt, SystemRegister sysreg) {
790  DCHECK(allow_macro_instructions());
791  DCHECK(!rt.IsZero());
792  mrs(rt, sysreg);
793 }
794 
795 
796 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
797  DCHECK(allow_macro_instructions());
798  msr(sysreg, rt);
799 }
800 
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);
806 }
807 
808 void TurboAssembler::Mul(const Register& rd, const Register& rn,
809  const Register& rm) {
810  DCHECK(allow_macro_instructions());
811  DCHECK(!rd.IsZero());
812  mul(rd, rn, rm);
813 }
814 
815 void TurboAssembler::Rbit(const Register& rd, const Register& rn) {
816  DCHECK(allow_macro_instructions());
817  DCHECK(!rd.IsZero());
818  rbit(rd, rn);
819 }
820 
821 void TurboAssembler::Rev(const Register& rd, const Register& rn) {
822  DCHECK(allow_macro_instructions());
823  DCHECK(!rd.IsZero());
824  rev(rd, rn);
825 }
826 
827 void TurboAssembler::Ret(const Register& xn) {
828  DCHECK(allow_macro_instructions());
829  DCHECK(!xn.IsZero());
830  ret(xn);
831  CheckVeneerPool(false, false);
832 }
833 
834 
835 void MacroAssembler::Rev(const Register& rd, const Register& rn) {
836  DCHECK(allow_macro_instructions());
837  DCHECK(!rd.IsZero());
838  rev(rd, rn);
839 }
840 
841 void TurboAssembler::Rev16(const Register& rd, const Register& rn) {
842  DCHECK(allow_macro_instructions());
843  DCHECK(!rd.IsZero());
844  rev16(rd, rn);
845 }
846 
847 void TurboAssembler::Rev32(const Register& rd, const Register& rn) {
848  DCHECK(allow_macro_instructions());
849  DCHECK(!rd.IsZero());
850  rev32(rd, rn);
851 }
852 
853 void TurboAssembler::Ror(const Register& rd, const Register& rs,
854  unsigned shift) {
855  DCHECK(allow_macro_instructions());
856  DCHECK(!rd.IsZero());
857  ror(rd, rs, shift);
858 }
859 
860 void TurboAssembler::Ror(const Register& rd, const Register& rn,
861  const Register& rm) {
862  DCHECK(allow_macro_instructions());
863  DCHECK(!rd.IsZero());
864  rorv(rd, rn, rm);
865 }
866 
867 
868 void MacroAssembler::Sbfiz(const Register& rd,
869  const Register& rn,
870  unsigned lsb,
871  unsigned width) {
872  DCHECK(allow_macro_instructions());
873  DCHECK(!rd.IsZero());
874  sbfiz(rd, rn, lsb, width);
875 }
876 
877 void TurboAssembler::Sbfx(const Register& rd, const Register& rn, unsigned lsb,
878  unsigned width) {
879  DCHECK(allow_macro_instructions());
880  DCHECK(!rd.IsZero());
881  sbfx(rd, rn, lsb, width);
882 }
883 
884 void TurboAssembler::Scvtf(const VRegister& fd, const Register& rn,
885  unsigned fbits) {
886  DCHECK(allow_macro_instructions());
887  scvtf(fd, rn, fbits);
888 }
889 
890 void TurboAssembler::Sdiv(const Register& rd, const Register& rn,
891  const Register& rm) {
892  DCHECK(allow_macro_instructions());
893  DCHECK(!rd.IsZero());
894  sdiv(rd, rn, rm);
895 }
896 
897 
898 void MacroAssembler::Smaddl(const Register& rd,
899  const Register& rn,
900  const Register& rm,
901  const Register& ra) {
902  DCHECK(allow_macro_instructions());
903  DCHECK(!rd.IsZero());
904  smaddl(rd, rn, rm, ra);
905 }
906 
907 
908 void MacroAssembler::Smsubl(const Register& rd,
909  const Register& rn,
910  const Register& rm,
911  const Register& ra) {
912  DCHECK(allow_macro_instructions());
913  DCHECK(!rd.IsZero());
914  smsubl(rd, rn, rm, ra);
915 }
916 
917 void TurboAssembler::Smull(const Register& rd, const Register& rn,
918  const Register& rm) {
919  DCHECK(allow_macro_instructions());
920  DCHECK(!rd.IsZero());
921  smull(rd, rn, rm);
922 }
923 
924 
925 void MacroAssembler::Smulh(const Register& rd,
926  const Register& rn,
927  const Register& rm) {
928  DCHECK(allow_macro_instructions());
929  DCHECK(!rd.IsZero());
930  smulh(rd, rn, rm);
931 }
932 
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);
938 }
939 
940 void TurboAssembler::Sxtb(const Register& rd, const Register& rn) {
941  DCHECK(allow_macro_instructions());
942  DCHECK(!rd.IsZero());
943  sxtb(rd, rn);
944 }
945 
946 void TurboAssembler::Sxth(const Register& rd, const Register& rn) {
947  DCHECK(allow_macro_instructions());
948  DCHECK(!rd.IsZero());
949  sxth(rd, rn);
950 }
951 
952 void TurboAssembler::Sxtw(const Register& rd, const Register& rn) {
953  DCHECK(allow_macro_instructions());
954  DCHECK(!rd.IsZero());
955  sxtw(rd, rn);
956 }
957 
958 void TurboAssembler::Ubfiz(const Register& rd, const Register& rn, unsigned lsb,
959  unsigned width) {
960  DCHECK(allow_macro_instructions());
961  DCHECK(!rd.IsZero());
962  ubfiz(rd, rn, lsb, width);
963 }
964 
965 void TurboAssembler::Ubfx(const Register& rd, const Register& rn, unsigned lsb,
966  unsigned width) {
967  DCHECK(allow_macro_instructions());
968  DCHECK(!rd.IsZero());
969  ubfx(rd, rn, lsb, width);
970 }
971 
972 void TurboAssembler::Ucvtf(const VRegister& fd, const Register& rn,
973  unsigned fbits) {
974  DCHECK(allow_macro_instructions());
975  ucvtf(fd, rn, fbits);
976 }
977 
978 void TurboAssembler::Udiv(const Register& rd, const Register& rn,
979  const Register& rm) {
980  DCHECK(allow_macro_instructions());
981  DCHECK(!rd.IsZero());
982  udiv(rd, rn, rm);
983 }
984 
985 
986 void MacroAssembler::Umaddl(const Register& rd,
987  const Register& rn,
988  const Register& rm,
989  const Register& ra) {
990  DCHECK(allow_macro_instructions());
991  DCHECK(!rd.IsZero());
992  umaddl(rd, rn, rm, ra);
993 }
994 
995 
996 void MacroAssembler::Umsubl(const Register& rd,
997  const Register& rn,
998  const Register& rm,
999  const Register& ra) {
1000  DCHECK(allow_macro_instructions());
1001  DCHECK(!rd.IsZero());
1002  umsubl(rd, rn, rm, ra);
1003 }
1004 
1005 void TurboAssembler::Uxtb(const Register& rd, const Register& rn) {
1006  DCHECK(allow_macro_instructions());
1007  DCHECK(!rd.IsZero());
1008  uxtb(rd, rn);
1009 }
1010 
1011 void TurboAssembler::Uxth(const Register& rd, const Register& rn) {
1012  DCHECK(allow_macro_instructions());
1013  DCHECK(!rd.IsZero());
1014  uxth(rd, rn);
1015 }
1016 
1017 void TurboAssembler::Uxtw(const Register& rd, const Register& rn) {
1018  DCHECK(allow_macro_instructions());
1019  DCHECK(!rd.IsZero());
1020  uxtw(rd, rn);
1021 }
1022 
1023 void TurboAssembler::InitializeRootRegister() {
1024  ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
1025  Mov(kRootRegister, Operand(isolate_root));
1026 }
1027 
1028 
1029 void MacroAssembler::SmiTag(Register dst, Register src) {
1030  DCHECK(dst.Is64Bits() && src.Is64Bits());
1031  DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
1032  Lsl(dst, src, kSmiShift);
1033 }
1034 
1035 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); }
1036 
1037 void TurboAssembler::SmiUntag(Register dst, Register src) {
1038  DCHECK(dst.Is64Bits() && src.Is64Bits());
1039  if (FLAG_enable_slow_asserts) {
1040  AssertSmi(src);
1041  }
1042  DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
1043  Asr(dst, src, kSmiShift);
1044 }
1045 
1046 void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) {
1047  DCHECK(dst.Is64Bits());
1048  if (SmiValuesAre32Bits()) {
1049  if (src.IsImmediateOffset() && src.shift_amount() == 0) {
1050  // Load value directly from the upper half-word.
1051  // Assumes that Smis are shifted by 32 bits and little endianness.
1052  DCHECK_EQ(kSmiShift, 32);
1053  Ldrsw(dst,
1054  MemOperand(src.base(), src.offset() + (kSmiShift / kBitsPerByte),
1055  src.addrmode()));
1056 
1057  } else {
1058  Ldr(dst, src);
1059  SmiUntag(dst);
1060  }
1061  } else {
1062  DCHECK(SmiValuesAre31Bits());
1063  Ldr(dst, src);
1064  SmiUntag(dst);
1065  }
1066 }
1067 
1068 void TurboAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); }
1069 
1070 void TurboAssembler::JumpIfSmi(Register value, Label* smi_label,
1071  Label* not_smi_label) {
1072  STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1073  // Check if the tag bit is set.
1074  if (smi_label) {
1075  Tbz(value, 0, smi_label);
1076  if (not_smi_label) {
1077  B(not_smi_label);
1078  }
1079  } else {
1080  DCHECK(not_smi_label);
1081  Tbnz(value, 0, not_smi_label);
1082  }
1083 }
1084 
1085 void TurboAssembler::JumpIfEqual(Register x, int32_t y, Label* dest) {
1086  Cmp(x, y);
1087  B(eq, dest);
1088 }
1089 
1090 void TurboAssembler::JumpIfLessThan(Register x, int32_t y, Label* dest) {
1091  Cmp(x, y);
1092  B(lt, dest);
1093 }
1094 
1095 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) {
1096  JumpIfSmi(value, nullptr, not_smi_label);
1097 }
1098 
1099 
1100 void MacroAssembler::JumpIfBothSmi(Register value1,
1101  Register value2,
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();
1107  // Check if both tag bits are clear.
1108  Orr(tmp, value1, value2);
1109  JumpIfSmi(tmp, both_smi_label, not_smi_label);
1110 }
1111 
1112 
1113 void MacroAssembler::JumpIfEitherSmi(Register value1,
1114  Register value2,
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();
1120  // Check if either tag bit is clear.
1121  And(tmp, value1, value2);
1122  JumpIfSmi(tmp, either_smi_label, not_smi_label);
1123 }
1124 
1125 
1126 void MacroAssembler::JumpIfEitherNotSmi(Register value1,
1127  Register value2,
1128  Label* not_smi_label) {
1129  JumpIfBothSmi(value1, value2, nullptr, not_smi_label);
1130 }
1131 
1132 
1133 void MacroAssembler::JumpIfBothNotSmi(Register value1,
1134  Register value2,
1135  Label* not_smi_label) {
1136  JumpIfEitherSmi(value1, value2, nullptr, not_smi_label);
1137 }
1138 
1139 
1140 void MacroAssembler::ObjectTag(Register tagged_obj, Register obj) {
1141  STATIC_ASSERT(kHeapObjectTag == 1);
1142  if (emit_debug_code()) {
1143  Label ok;
1144  Tbz(obj, 0, &ok);
1145  Abort(AbortReason::kObjectTagged);
1146  Bind(&ok);
1147  }
1148  Orr(tagged_obj, obj, kHeapObjectTag);
1149 }
1150 
1151 
1152 void MacroAssembler::ObjectUntag(Register untagged_obj, Register obj) {
1153  STATIC_ASSERT(kHeapObjectTag == 1);
1154  if (emit_debug_code()) {
1155  Label ok;
1156  Tbnz(obj, 0, &ok);
1157  Abort(AbortReason::kObjectNotTagged);
1158  Bind(&ok);
1159  }
1160  Bic(untagged_obj, obj, kHeapObjectTag);
1161 }
1162 
1163 void TurboAssembler::jmp(Label* L) { B(L); }
1164 
1165 void TurboAssembler::Push(Handle<HeapObject> handle) {
1166  UseScratchRegisterScope temps(this);
1167  Register tmp = temps.AcquireX();
1168  Mov(tmp, Operand(handle));
1169  // This is only used in test-heap.cc, for generating code that is not
1170  // executed. Push a padding slot together with the handle here, to
1171  // satisfy the alignment requirement.
1172  Push(padreg, tmp);
1173 }
1174 
1175 void TurboAssembler::Push(Smi smi) {
1176  UseScratchRegisterScope temps(this);
1177  Register tmp = temps.AcquireX();
1178  Mov(tmp, Operand(smi));
1179  Push(tmp);
1180 }
1181 
1182 void TurboAssembler::Claim(int64_t count, uint64_t unit_size) {
1183  DCHECK_GE(count, 0);
1184  uint64_t size = count * unit_size;
1185 
1186  if (size == 0) {
1187  return;
1188  }
1189  DCHECK_EQ(size % 16, 0);
1190 
1191  Sub(sp, sp, size);
1192 }
1193 
1194 void TurboAssembler::Claim(const Register& count, uint64_t unit_size) {
1195  if (unit_size == 0) return;
1196  DCHECK(base::bits::IsPowerOfTwo(unit_size));
1197 
1198  const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1199  const Operand size(count, LSL, shift);
1200 
1201  if (size.IsZero()) {
1202  return;
1203  }
1204  AssertPositiveOrZero(count);
1205 
1206  Sub(sp, sp, size);
1207 }
1208 
1209 
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));
1216 
1217  if (size.IsZero()) {
1218  return;
1219  }
1220 
1221  Sub(sp, sp, size);
1222 }
1223 
1224 void TurboAssembler::Drop(int64_t count, uint64_t unit_size) {
1225  DCHECK_GE(count, 0);
1226  uint64_t size = count * unit_size;
1227 
1228  if (size == 0) {
1229  return;
1230  }
1231 
1232  Add(sp, sp, size);
1233  DCHECK_EQ(size % 16, 0);
1234 }
1235 
1236 void TurboAssembler::Drop(const Register& count, uint64_t unit_size) {
1237  if (unit_size == 0) return;
1238  DCHECK(base::bits::IsPowerOfTwo(unit_size));
1239 
1240  const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1241  const Operand size(count, LSL, shift);
1242 
1243  if (size.IsZero()) {
1244  return;
1245  }
1246 
1247  AssertPositiveOrZero(count);
1248  Add(sp, sp, size);
1249 }
1250 
1251 void TurboAssembler::DropArguments(const Register& count,
1252  ArgumentsCountMode mode) {
1253  int extra_slots = 1; // Padding slot.
1254  if (mode == kCountExcludesReceiver) {
1255  // Add a slot for the receiver.
1256  ++extra_slots;
1257  }
1258  UseScratchRegisterScope temps(this);
1259  Register tmp = temps.AcquireX();
1260  Add(tmp, count, extra_slots);
1261  Bic(tmp, tmp, 1);
1262  Drop(tmp, kXRegSize);
1263 }
1264 
1265 void TurboAssembler::DropArguments(int64_t count, ArgumentsCountMode mode) {
1266  if (mode == kCountExcludesReceiver) {
1267  // Add a slot for the receiver.
1268  ++count;
1269  }
1270  Drop(RoundUp(count, 2), kXRegSize);
1271 }
1272 
1273 void TurboAssembler::DropSlots(int64_t count) {
1274  Drop(RoundUp(count, 2), kXRegSize);
1275 }
1276 
1277 void TurboAssembler::PushArgument(const Register& arg) { Push(padreg, arg); }
1278 
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));
1285 
1286  if (size.IsZero()) {
1287  return;
1288  }
1289 
1290  Add(sp, sp, size);
1291 }
1292 
1293 
1294 void MacroAssembler::CompareAndBranch(const Register& lhs,
1295  const Operand& rhs,
1296  Condition cond,
1297  Label* label) {
1298  if (rhs.IsImmediate() && (rhs.ImmediateValue() == 0) &&
1299  ((cond == eq) || (cond == ne))) {
1300  if (cond == eq) {
1301  Cbz(lhs, label);
1302  } else {
1303  Cbnz(lhs, label);
1304  }
1305  } else {
1306  Cmp(lhs, rhs);
1307  B(cond, label);
1308  }
1309 }
1310 
1311 void TurboAssembler::TestAndBranchIfAnySet(const Register& reg,
1312  const uint64_t bit_pattern,
1313  Label* label) {
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);
1318  } else {
1319  Tst(reg, bit_pattern);
1320  B(ne, label);
1321  }
1322 }
1323 
1324 void TurboAssembler::TestAndBranchIfAllClear(const Register& reg,
1325  const uint64_t bit_pattern,
1326  Label* label) {
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);
1331  } else {
1332  Tst(reg, bit_pattern);
1333  B(eq, label);
1334  }
1335 }
1336 
1337 
1338 void MacroAssembler::InlineData(uint64_t data) {
1339  DCHECK(is_uint16(data));
1340  InstructionAccurateScope scope(this, 1);
1341  movz(xzr, data);
1342 }
1343 
1344 
1345 void MacroAssembler::EnableInstrumentation() {
1346  InstructionAccurateScope scope(this, 1);
1347  movn(xzr, InstrumentStateEnable);
1348 }
1349 
1350 
1351 void MacroAssembler::DisableInstrumentation() {
1352  InstructionAccurateScope scope(this, 1);
1353  movn(xzr, InstrumentStateDisable);
1354 }
1355 
1356 
1357 void MacroAssembler::AnnotateInstrumentation(const char* marker_name) {
1358  DCHECK_EQ(strlen(marker_name), 2);
1359 
1360  // We allow only printable characters in the marker names. Unprintable
1361  // characters are reserved for controlling features of the instrumentation.
1362  DCHECK(isprint(marker_name[0]) && isprint(marker_name[1]));
1363 
1364  InstructionAccurateScope scope(this, 1);
1365  movn(xzr, (marker_name[1] << 8) | marker_name[0]);
1366 }
1367 
1368 } // namespace internal
1369 } // namespace v8
1370 
1371 #endif // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
Definition: libplatform.h:13