• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/arm64/macro-assembler-arm64.h"
16 #include "src/base/bits.h"
17 
18 
19 namespace v8 {
20 namespace internal {
21 
22 
FieldMemOperand(Register object,int offset)23 MemOperand FieldMemOperand(Register object, int offset) {
24   return MemOperand(object, offset - kHeapObjectTag);
25 }
26 
27 
UntagSmiFieldMemOperand(Register object,int offset)28 MemOperand UntagSmiFieldMemOperand(Register object, int offset) {
29   return UntagSmiMemOperand(object, offset - kHeapObjectTag);
30 }
31 
32 
UntagSmiMemOperand(Register object,int offset)33 MemOperand UntagSmiMemOperand(Register object, int offset) {
34   // Assumes that Smis are shifted by 32 bits and little endianness.
35   STATIC_ASSERT(kSmiShift == 32);
36   return MemOperand(object, offset + (kSmiShift / kBitsPerByte));
37 }
38 
39 
CodeObject()40 Handle<Object> MacroAssembler::CodeObject() {
41   DCHECK(!code_object_.is_null());
42   return code_object_;
43 }
44 
45 
And(const Register & rd,const Register & rn,const Operand & operand)46 void MacroAssembler::And(const Register& rd,
47                          const Register& rn,
48                          const Operand& operand) {
49   DCHECK(allow_macro_instructions_);
50   DCHECK(!rd.IsZero());
51   LogicalMacro(rd, rn, operand, AND);
52 }
53 
54 
Ands(const Register & rd,const Register & rn,const Operand & operand)55 void MacroAssembler::Ands(const Register& rd,
56                           const Register& rn,
57                           const Operand& operand) {
58   DCHECK(allow_macro_instructions_);
59   DCHECK(!rd.IsZero());
60   LogicalMacro(rd, rn, operand, ANDS);
61 }
62 
63 
Tst(const Register & rn,const Operand & operand)64 void MacroAssembler::Tst(const Register& rn,
65                          const Operand& operand) {
66   DCHECK(allow_macro_instructions_);
67   LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS);
68 }
69 
70 
Bic(const Register & rd,const Register & rn,const Operand & operand)71 void MacroAssembler::Bic(const Register& rd,
72                          const Register& rn,
73                          const Operand& operand) {
74   DCHECK(allow_macro_instructions_);
75   DCHECK(!rd.IsZero());
76   LogicalMacro(rd, rn, operand, BIC);
77 }
78 
79 
Bics(const Register & rd,const Register & rn,const Operand & operand)80 void MacroAssembler::Bics(const Register& rd,
81                           const Register& rn,
82                           const Operand& operand) {
83   DCHECK(allow_macro_instructions_);
84   DCHECK(!rd.IsZero());
85   LogicalMacro(rd, rn, operand, BICS);
86 }
87 
88 
Orr(const Register & rd,const Register & rn,const Operand & operand)89 void MacroAssembler::Orr(const Register& rd,
90                          const Register& rn,
91                          const Operand& operand) {
92   DCHECK(allow_macro_instructions_);
93   DCHECK(!rd.IsZero());
94   LogicalMacro(rd, rn, operand, ORR);
95 }
96 
97 
Orn(const Register & rd,const Register & rn,const Operand & operand)98 void MacroAssembler::Orn(const Register& rd,
99                          const Register& rn,
100                          const Operand& operand) {
101   DCHECK(allow_macro_instructions_);
102   DCHECK(!rd.IsZero());
103   LogicalMacro(rd, rn, operand, ORN);
104 }
105 
106 
Eor(const Register & rd,const Register & rn,const Operand & operand)107 void MacroAssembler::Eor(const Register& rd,
108                          const Register& rn,
109                          const Operand& operand) {
110   DCHECK(allow_macro_instructions_);
111   DCHECK(!rd.IsZero());
112   LogicalMacro(rd, rn, operand, EOR);
113 }
114 
115 
Eon(const Register & rd,const Register & rn,const Operand & operand)116 void MacroAssembler::Eon(const Register& rd,
117                          const Register& rn,
118                          const Operand& operand) {
119   DCHECK(allow_macro_instructions_);
120   DCHECK(!rd.IsZero());
121   LogicalMacro(rd, rn, operand, EON);
122 }
123 
124 
Ccmp(const Register & rn,const Operand & operand,StatusFlags nzcv,Condition cond)125 void MacroAssembler::Ccmp(const Register& rn,
126                           const Operand& operand,
127                           StatusFlags nzcv,
128                           Condition cond) {
129   DCHECK(allow_macro_instructions_);
130   if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
131     ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMN);
132   } else {
133     ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
134   }
135 }
136 
137 
Ccmn(const Register & rn,const Operand & operand,StatusFlags nzcv,Condition cond)138 void MacroAssembler::Ccmn(const Register& rn,
139                           const Operand& operand,
140                           StatusFlags nzcv,
141                           Condition cond) {
142   DCHECK(allow_macro_instructions_);
143   if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) {
144     ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP);
145   } else {
146     ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
147   }
148 }
149 
150 
Add(const Register & rd,const Register & rn,const Operand & operand)151 void MacroAssembler::Add(const Register& rd,
152                          const Register& rn,
153                          const Operand& operand) {
154   DCHECK(allow_macro_instructions_);
155   if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
156       IsImmAddSub(-operand.ImmediateValue())) {
157     AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, SUB);
158   } else {
159     AddSubMacro(rd, rn, operand, LeaveFlags, ADD);
160   }
161 }
162 
Adds(const Register & rd,const Register & rn,const Operand & operand)163 void MacroAssembler::Adds(const Register& rd,
164                           const Register& rn,
165                           const Operand& operand) {
166   DCHECK(allow_macro_instructions_);
167   if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
168       IsImmAddSub(-operand.ImmediateValue())) {
169     AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, SUB);
170   } else {
171     AddSubMacro(rd, rn, operand, SetFlags, ADD);
172   }
173 }
174 
175 
Sub(const Register & rd,const Register & rn,const Operand & operand)176 void MacroAssembler::Sub(const Register& rd,
177                          const Register& rn,
178                          const Operand& operand) {
179   DCHECK(allow_macro_instructions_);
180   if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
181       IsImmAddSub(-operand.ImmediateValue())) {
182     AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, ADD);
183   } else {
184     AddSubMacro(rd, rn, operand, LeaveFlags, SUB);
185   }
186 }
187 
188 
Subs(const Register & rd,const Register & rn,const Operand & operand)189 void MacroAssembler::Subs(const Register& rd,
190                           const Register& rn,
191                           const Operand& operand) {
192   DCHECK(allow_macro_instructions_);
193   if (operand.IsImmediate() && (operand.ImmediateValue() < 0) &&
194       IsImmAddSub(-operand.ImmediateValue())) {
195     AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, ADD);
196   } else {
197     AddSubMacro(rd, rn, operand, SetFlags, SUB);
198   }
199 }
200 
201 
Cmn(const Register & rn,const Operand & operand)202 void MacroAssembler::Cmn(const Register& rn, const Operand& operand) {
203   DCHECK(allow_macro_instructions_);
204   Adds(AppropriateZeroRegFor(rn), rn, operand);
205 }
206 
207 
Cmp(const Register & rn,const Operand & operand)208 void MacroAssembler::Cmp(const Register& rn, const Operand& operand) {
209   DCHECK(allow_macro_instructions_);
210   Subs(AppropriateZeroRegFor(rn), rn, operand);
211 }
212 
213 
Neg(const Register & rd,const Operand & operand)214 void MacroAssembler::Neg(const Register& rd,
215                          const Operand& operand) {
216   DCHECK(allow_macro_instructions_);
217   DCHECK(!rd.IsZero());
218   if (operand.IsImmediate()) {
219     Mov(rd, -operand.ImmediateValue());
220   } else {
221     Sub(rd, AppropriateZeroRegFor(rd), operand);
222   }
223 }
224 
225 
Negs(const Register & rd,const Operand & operand)226 void MacroAssembler::Negs(const Register& rd,
227                           const Operand& operand) {
228   DCHECK(allow_macro_instructions_);
229   Subs(rd, AppropriateZeroRegFor(rd), operand);
230 }
231 
232 
Adc(const Register & rd,const Register & rn,const Operand & operand)233 void MacroAssembler::Adc(const Register& rd,
234                          const Register& rn,
235                          const Operand& operand) {
236   DCHECK(allow_macro_instructions_);
237   DCHECK(!rd.IsZero());
238   AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, ADC);
239 }
240 
241 
Adcs(const Register & rd,const Register & rn,const Operand & operand)242 void MacroAssembler::Adcs(const Register& rd,
243                           const Register& rn,
244                           const Operand& operand) {
245   DCHECK(allow_macro_instructions_);
246   DCHECK(!rd.IsZero());
247   AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC);
248 }
249 
250 
Sbc(const Register & rd,const Register & rn,const Operand & operand)251 void MacroAssembler::Sbc(const Register& rd,
252                          const Register& rn,
253                          const Operand& operand) {
254   DCHECK(allow_macro_instructions_);
255   DCHECK(!rd.IsZero());
256   AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC);
257 }
258 
259 
Sbcs(const Register & rd,const Register & rn,const Operand & operand)260 void MacroAssembler::Sbcs(const Register& rd,
261                           const Register& rn,
262                           const Operand& operand) {
263   DCHECK(allow_macro_instructions_);
264   DCHECK(!rd.IsZero());
265   AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC);
266 }
267 
268 
Ngc(const Register & rd,const Operand & operand)269 void MacroAssembler::Ngc(const Register& rd,
270                          const Operand& operand) {
271   DCHECK(allow_macro_instructions_);
272   DCHECK(!rd.IsZero());
273   Register zr = AppropriateZeroRegFor(rd);
274   Sbc(rd, zr, operand);
275 }
276 
277 
Ngcs(const Register & rd,const Operand & operand)278 void MacroAssembler::Ngcs(const Register& rd,
279                           const Operand& operand) {
280   DCHECK(allow_macro_instructions_);
281   DCHECK(!rd.IsZero());
282   Register zr = AppropriateZeroRegFor(rd);
283   Sbcs(rd, zr, operand);
284 }
285 
286 
Mvn(const Register & rd,uint64_t imm)287 void MacroAssembler::Mvn(const Register& rd, uint64_t imm) {
288   DCHECK(allow_macro_instructions_);
289   DCHECK(!rd.IsZero());
290   Mov(rd, ~imm);
291 }
292 
293 
294 #define DEFINE_FUNCTION(FN, REGTYPE, REG, OP)                         \
295 void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) {  \
296   DCHECK(allow_macro_instructions_);                                  \
297   LoadStoreMacro(REG, addr, OP);                                      \
298 }
299 LS_MACRO_LIST(DEFINE_FUNCTION)
300 #undef DEFINE_FUNCTION
301 
302 
303 #define DEFINE_FUNCTION(FN, REGTYPE, REG, REG2, OP)              \
304   void MacroAssembler::FN(const REGTYPE REG, const REGTYPE REG2, \
305                           const MemOperand& addr) {              \
306     DCHECK(allow_macro_instructions_);                           \
307     LoadStorePairMacro(REG, REG2, addr, OP);                     \
308   }
LSPAIR_MACRO_LIST(DEFINE_FUNCTION)309 LSPAIR_MACRO_LIST(DEFINE_FUNCTION)
310 #undef DEFINE_FUNCTION
311 
312 #define DECLARE_FUNCTION(FN, OP)                                    \
313   void MacroAssembler::FN(const Register& rt, const Register& rn) { \
314     DCHECK(allow_macro_instructions_);                              \
315     OP(rt, rn);                                                     \
316   }
317 LDA_STL_MACRO_LIST(DECLARE_FUNCTION)
318 #undef DECLARE_FUNCTION
319 
320 #define DECLARE_FUNCTION(FN, OP)                                  \
321   void MacroAssembler::FN(const Register& rs, const Register& rt, \
322                           const Register& rn) {                   \
323     DCHECK(allow_macro_instructions_);                            \
324     OP(rs, rt, rn);                                               \
325   }
326 STLX_MACRO_LIST(DECLARE_FUNCTION)
327 #undef DECLARE_FUNCTION
328 
329 void MacroAssembler::Asr(const Register& rd,
330                          const Register& rn,
331                          unsigned shift) {
332   DCHECK(allow_macro_instructions_);
333   DCHECK(!rd.IsZero());
334   asr(rd, rn, shift);
335 }
336 
337 
Asr(const Register & rd,const Register & rn,const Register & rm)338 void MacroAssembler::Asr(const Register& rd,
339                          const Register& rn,
340                          const Register& rm) {
341   DCHECK(allow_macro_instructions_);
342   DCHECK(!rd.IsZero());
343   asrv(rd, rn, rm);
344 }
345 
346 
B(Label * label)347 void MacroAssembler::B(Label* label) {
348   b(label);
349   CheckVeneerPool(false, false);
350 }
351 
352 
B(Condition cond,Label * label)353 void MacroAssembler::B(Condition cond, Label* label) {
354   DCHECK(allow_macro_instructions_);
355   B(label, cond);
356 }
357 
358 
Bfi(const Register & rd,const Register & rn,unsigned lsb,unsigned width)359 void MacroAssembler::Bfi(const Register& rd,
360                          const Register& rn,
361                          unsigned lsb,
362                          unsigned width) {
363   DCHECK(allow_macro_instructions_);
364   DCHECK(!rd.IsZero());
365   bfi(rd, rn, lsb, width);
366 }
367 
368 
Bfxil(const Register & rd,const Register & rn,unsigned lsb,unsigned width)369 void MacroAssembler::Bfxil(const Register& rd,
370                            const Register& rn,
371                            unsigned lsb,
372                            unsigned width) {
373   DCHECK(allow_macro_instructions_);
374   DCHECK(!rd.IsZero());
375   bfxil(rd, rn, lsb, width);
376 }
377 
378 
Bind(Label * label)379 void MacroAssembler::Bind(Label* label) {
380   DCHECK(allow_macro_instructions_);
381   bind(label);
382 }
383 
384 
Bl(Label * label)385 void MacroAssembler::Bl(Label* label) {
386   DCHECK(allow_macro_instructions_);
387   bl(label);
388 }
389 
390 
Blr(const Register & xn)391 void MacroAssembler::Blr(const Register& xn) {
392   DCHECK(allow_macro_instructions_);
393   DCHECK(!xn.IsZero());
394   blr(xn);
395 }
396 
397 
Br(const Register & xn)398 void MacroAssembler::Br(const Register& xn) {
399   DCHECK(allow_macro_instructions_);
400   DCHECK(!xn.IsZero());
401   br(xn);
402 }
403 
404 
Brk(int code)405 void MacroAssembler::Brk(int code) {
406   DCHECK(allow_macro_instructions_);
407   brk(code);
408 }
409 
410 
Cinc(const Register & rd,const Register & rn,Condition cond)411 void MacroAssembler::Cinc(const Register& rd,
412                           const Register& rn,
413                           Condition cond) {
414   DCHECK(allow_macro_instructions_);
415   DCHECK(!rd.IsZero());
416   DCHECK((cond != al) && (cond != nv));
417   cinc(rd, rn, cond);
418 }
419 
420 
Cinv(const Register & rd,const Register & rn,Condition cond)421 void MacroAssembler::Cinv(const Register& rd,
422                           const Register& rn,
423                           Condition cond) {
424   DCHECK(allow_macro_instructions_);
425   DCHECK(!rd.IsZero());
426   DCHECK((cond != al) && (cond != nv));
427   cinv(rd, rn, cond);
428 }
429 
430 
Cls(const Register & rd,const Register & rn)431 void MacroAssembler::Cls(const Register& rd, const Register& rn) {
432   DCHECK(allow_macro_instructions_);
433   DCHECK(!rd.IsZero());
434   cls(rd, rn);
435 }
436 
437 
Clz(const Register & rd,const Register & rn)438 void MacroAssembler::Clz(const Register& rd, const Register& rn) {
439   DCHECK(allow_macro_instructions_);
440   DCHECK(!rd.IsZero());
441   clz(rd, rn);
442 }
443 
444 
Cneg(const Register & rd,const Register & rn,Condition cond)445 void MacroAssembler::Cneg(const Register& rd,
446                           const Register& rn,
447                           Condition cond) {
448   DCHECK(allow_macro_instructions_);
449   DCHECK(!rd.IsZero());
450   DCHECK((cond != al) && (cond != nv));
451   cneg(rd, rn, cond);
452 }
453 
454 
455 // Conditionally zero the destination register. Only X registers are supported
456 // due to the truncation side-effect when used on W registers.
CzeroX(const Register & rd,Condition cond)457 void MacroAssembler::CzeroX(const Register& rd,
458                             Condition cond) {
459   DCHECK(allow_macro_instructions_);
460   DCHECK(!rd.IsSP() && rd.Is64Bits());
461   DCHECK((cond != al) && (cond != nv));
462   csel(rd, xzr, rd, cond);
463 }
464 
465 
466 // Conditionally move a value into the destination register. Only X registers
467 // are supported due to the truncation side-effect when used on W registers.
CmovX(const Register & rd,const Register & rn,Condition cond)468 void MacroAssembler::CmovX(const Register& rd,
469                            const Register& rn,
470                            Condition cond) {
471   DCHECK(allow_macro_instructions_);
472   DCHECK(!rd.IsSP());
473   DCHECK(rd.Is64Bits() && rn.Is64Bits());
474   DCHECK((cond != al) && (cond != nv));
475   if (!rd.is(rn)) {
476     csel(rd, rn, rd, cond);
477   }
478 }
479 
480 
Cset(const Register & rd,Condition cond)481 void MacroAssembler::Cset(const Register& rd, Condition cond) {
482   DCHECK(allow_macro_instructions_);
483   DCHECK(!rd.IsZero());
484   DCHECK((cond != al) && (cond != nv));
485   cset(rd, cond);
486 }
487 
488 
Csetm(const Register & rd,Condition cond)489 void MacroAssembler::Csetm(const Register& rd, Condition cond) {
490   DCHECK(allow_macro_instructions_);
491   DCHECK(!rd.IsZero());
492   DCHECK((cond != al) && (cond != nv));
493   csetm(rd, cond);
494 }
495 
496 
Csinc(const Register & rd,const Register & rn,const Register & rm,Condition cond)497 void MacroAssembler::Csinc(const Register& rd,
498                            const Register& rn,
499                            const Register& rm,
500                            Condition cond) {
501   DCHECK(allow_macro_instructions_);
502   DCHECK(!rd.IsZero());
503   DCHECK((cond != al) && (cond != nv));
504   csinc(rd, rn, rm, cond);
505 }
506 
507 
Csinv(const Register & rd,const Register & rn,const Register & rm,Condition cond)508 void MacroAssembler::Csinv(const Register& rd,
509                            const Register& rn,
510                            const Register& rm,
511                            Condition cond) {
512   DCHECK(allow_macro_instructions_);
513   DCHECK(!rd.IsZero());
514   DCHECK((cond != al) && (cond != nv));
515   csinv(rd, rn, rm, cond);
516 }
517 
518 
Csneg(const Register & rd,const Register & rn,const Register & rm,Condition cond)519 void MacroAssembler::Csneg(const Register& rd,
520                            const Register& rn,
521                            const Register& rm,
522                            Condition cond) {
523   DCHECK(allow_macro_instructions_);
524   DCHECK(!rd.IsZero());
525   DCHECK((cond != al) && (cond != nv));
526   csneg(rd, rn, rm, cond);
527 }
528 
529 
Dmb(BarrierDomain domain,BarrierType type)530 void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) {
531   DCHECK(allow_macro_instructions_);
532   dmb(domain, type);
533 }
534 
535 
Dsb(BarrierDomain domain,BarrierType type)536 void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) {
537   DCHECK(allow_macro_instructions_);
538   dsb(domain, type);
539 }
540 
541 
Debug(const char * message,uint32_t code,Instr params)542 void MacroAssembler::Debug(const char* message, uint32_t code, Instr params) {
543   DCHECK(allow_macro_instructions_);
544   debug(message, code, params);
545 }
546 
547 
Extr(const Register & rd,const Register & rn,const Register & rm,unsigned lsb)548 void MacroAssembler::Extr(const Register& rd,
549                           const Register& rn,
550                           const Register& rm,
551                           unsigned lsb) {
552   DCHECK(allow_macro_instructions_);
553   DCHECK(!rd.IsZero());
554   extr(rd, rn, rm, lsb);
555 }
556 
557 
Fabs(const FPRegister & fd,const FPRegister & fn)558 void MacroAssembler::Fabs(const FPRegister& fd, const FPRegister& fn) {
559   DCHECK(allow_macro_instructions_);
560   fabs(fd, fn);
561 }
562 
563 
Fadd(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)564 void MacroAssembler::Fadd(const FPRegister& fd,
565                           const FPRegister& fn,
566                           const FPRegister& fm) {
567   DCHECK(allow_macro_instructions_);
568   fadd(fd, fn, fm);
569 }
570 
571 
Fccmp(const FPRegister & fn,const FPRegister & fm,StatusFlags nzcv,Condition cond)572 void MacroAssembler::Fccmp(const FPRegister& fn,
573                            const FPRegister& fm,
574                            StatusFlags nzcv,
575                            Condition cond) {
576   DCHECK(allow_macro_instructions_);
577   DCHECK((cond != al) && (cond != nv));
578   fccmp(fn, fm, nzcv, cond);
579 }
580 
581 
Fcmp(const FPRegister & fn,const FPRegister & fm)582 void MacroAssembler::Fcmp(const FPRegister& fn, const FPRegister& fm) {
583   DCHECK(allow_macro_instructions_);
584   fcmp(fn, fm);
585 }
586 
587 
Fcmp(const FPRegister & fn,double value)588 void MacroAssembler::Fcmp(const FPRegister& fn, double value) {
589   DCHECK(allow_macro_instructions_);
590   if (value != 0.0) {
591     UseScratchRegisterScope temps(this);
592     FPRegister tmp = temps.AcquireSameSizeAs(fn);
593     Fmov(tmp, value);
594     fcmp(fn, tmp);
595   } else {
596     fcmp(fn, value);
597   }
598 }
599 
600 
Fcsel(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm,Condition cond)601 void MacroAssembler::Fcsel(const FPRegister& fd,
602                            const FPRegister& fn,
603                            const FPRegister& fm,
604                            Condition cond) {
605   DCHECK(allow_macro_instructions_);
606   DCHECK((cond != al) && (cond != nv));
607   fcsel(fd, fn, fm, cond);
608 }
609 
610 
Fcvt(const FPRegister & fd,const FPRegister & fn)611 void MacroAssembler::Fcvt(const FPRegister& fd, const FPRegister& fn) {
612   DCHECK(allow_macro_instructions_);
613   fcvt(fd, fn);
614 }
615 
616 
Fcvtas(const Register & rd,const FPRegister & fn)617 void MacroAssembler::Fcvtas(const Register& rd, const FPRegister& fn) {
618   DCHECK(allow_macro_instructions_);
619   DCHECK(!rd.IsZero());
620   fcvtas(rd, fn);
621 }
622 
623 
Fcvtau(const Register & rd,const FPRegister & fn)624 void MacroAssembler::Fcvtau(const Register& rd, const FPRegister& fn) {
625   DCHECK(allow_macro_instructions_);
626   DCHECK(!rd.IsZero());
627   fcvtau(rd, fn);
628 }
629 
630 
Fcvtms(const Register & rd,const FPRegister & fn)631 void MacroAssembler::Fcvtms(const Register& rd, const FPRegister& fn) {
632   DCHECK(allow_macro_instructions_);
633   DCHECK(!rd.IsZero());
634   fcvtms(rd, fn);
635 }
636 
637 
Fcvtmu(const Register & rd,const FPRegister & fn)638 void MacroAssembler::Fcvtmu(const Register& rd, const FPRegister& fn) {
639   DCHECK(allow_macro_instructions_);
640   DCHECK(!rd.IsZero());
641   fcvtmu(rd, fn);
642 }
643 
644 
Fcvtns(const Register & rd,const FPRegister & fn)645 void MacroAssembler::Fcvtns(const Register& rd, const FPRegister& fn) {
646   DCHECK(allow_macro_instructions_);
647   DCHECK(!rd.IsZero());
648   fcvtns(rd, fn);
649 }
650 
651 
Fcvtnu(const Register & rd,const FPRegister & fn)652 void MacroAssembler::Fcvtnu(const Register& rd, const FPRegister& fn) {
653   DCHECK(allow_macro_instructions_);
654   DCHECK(!rd.IsZero());
655   fcvtnu(rd, fn);
656 }
657 
658 
Fcvtzs(const Register & rd,const FPRegister & fn)659 void MacroAssembler::Fcvtzs(const Register& rd, const FPRegister& fn) {
660   DCHECK(allow_macro_instructions_);
661   DCHECK(!rd.IsZero());
662   fcvtzs(rd, fn);
663 }
Fcvtzu(const Register & rd,const FPRegister & fn)664 void MacroAssembler::Fcvtzu(const Register& rd, const FPRegister& fn) {
665   DCHECK(allow_macro_instructions_);
666   DCHECK(!rd.IsZero());
667   fcvtzu(rd, fn);
668 }
669 
670 
Fdiv(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)671 void MacroAssembler::Fdiv(const FPRegister& fd,
672                           const FPRegister& fn,
673                           const FPRegister& fm) {
674   DCHECK(allow_macro_instructions_);
675   fdiv(fd, fn, fm);
676 }
677 
678 
Fmadd(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm,const FPRegister & fa)679 void MacroAssembler::Fmadd(const FPRegister& fd,
680                            const FPRegister& fn,
681                            const FPRegister& fm,
682                            const FPRegister& fa) {
683   DCHECK(allow_macro_instructions_);
684   fmadd(fd, fn, fm, fa);
685 }
686 
687 
Fmax(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)688 void MacroAssembler::Fmax(const FPRegister& fd,
689                           const FPRegister& fn,
690                           const FPRegister& fm) {
691   DCHECK(allow_macro_instructions_);
692   fmax(fd, fn, fm);
693 }
694 
695 
Fmaxnm(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)696 void MacroAssembler::Fmaxnm(const FPRegister& fd,
697                             const FPRegister& fn,
698                             const FPRegister& fm) {
699   DCHECK(allow_macro_instructions_);
700   fmaxnm(fd, fn, fm);
701 }
702 
703 
Fmin(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)704 void MacroAssembler::Fmin(const FPRegister& fd,
705                           const FPRegister& fn,
706                           const FPRegister& fm) {
707   DCHECK(allow_macro_instructions_);
708   fmin(fd, fn, fm);
709 }
710 
711 
Fminnm(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)712 void MacroAssembler::Fminnm(const FPRegister& fd,
713                             const FPRegister& fn,
714                             const FPRegister& fm) {
715   DCHECK(allow_macro_instructions_);
716   fminnm(fd, fn, fm);
717 }
718 
719 
Fmov(FPRegister fd,FPRegister fn)720 void MacroAssembler::Fmov(FPRegister fd, FPRegister fn) {
721   DCHECK(allow_macro_instructions_);
722   // Only emit an instruction if fd and fn are different, and they are both D
723   // registers. fmov(s0, s0) is not a no-op because it clears the top word of
724   // d0. Technically, fmov(d0, d0) is not a no-op either because it clears the
725   // top of q0, but FPRegister does not currently support Q registers.
726   if (!fd.Is(fn) || !fd.Is64Bits()) {
727     fmov(fd, fn);
728   }
729 }
730 
731 
Fmov(FPRegister fd,Register rn)732 void MacroAssembler::Fmov(FPRegister fd, Register rn) {
733   DCHECK(allow_macro_instructions_);
734   fmov(fd, rn);
735 }
736 
737 
Fmov(FPRegister fd,double imm)738 void MacroAssembler::Fmov(FPRegister fd, double imm) {
739   DCHECK(allow_macro_instructions_);
740   if (fd.Is32Bits()) {
741     Fmov(fd, static_cast<float>(imm));
742     return;
743   }
744 
745   DCHECK(fd.Is64Bits());
746   if (IsImmFP64(imm)) {
747     fmov(fd, imm);
748   } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
749     fmov(fd, xzr);
750   } else {
751     Ldr(fd, imm);
752   }
753 }
754 
755 
Fmov(FPRegister fd,float imm)756 void MacroAssembler::Fmov(FPRegister fd, float imm) {
757   DCHECK(allow_macro_instructions_);
758   if (fd.Is64Bits()) {
759     Fmov(fd, static_cast<double>(imm));
760     return;
761   }
762 
763   DCHECK(fd.Is32Bits());
764   if (IsImmFP32(imm)) {
765     fmov(fd, imm);
766   } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
767     fmov(fd, wzr);
768   } else {
769     UseScratchRegisterScope temps(this);
770     Register tmp = temps.AcquireW();
771     // TODO(all): Use Assembler::ldr(const FPRegister& ft, float imm).
772     Mov(tmp, float_to_rawbits(imm));
773     Fmov(fd, tmp);
774   }
775 }
776 
777 
Fmov(Register rd,FPRegister fn)778 void MacroAssembler::Fmov(Register rd, FPRegister fn) {
779   DCHECK(allow_macro_instructions_);
780   DCHECK(!rd.IsZero());
781   fmov(rd, fn);
782 }
783 
784 
Fmsub(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm,const FPRegister & fa)785 void MacroAssembler::Fmsub(const FPRegister& fd,
786                            const FPRegister& fn,
787                            const FPRegister& fm,
788                            const FPRegister& fa) {
789   DCHECK(allow_macro_instructions_);
790   fmsub(fd, fn, fm, fa);
791 }
792 
793 
Fmul(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)794 void MacroAssembler::Fmul(const FPRegister& fd,
795                           const FPRegister& fn,
796                           const FPRegister& fm) {
797   DCHECK(allow_macro_instructions_);
798   fmul(fd, fn, fm);
799 }
800 
801 
Fneg(const FPRegister & fd,const FPRegister & fn)802 void MacroAssembler::Fneg(const FPRegister& fd, const FPRegister& fn) {
803   DCHECK(allow_macro_instructions_);
804   fneg(fd, fn);
805 }
806 
807 
Fnmadd(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm,const FPRegister & fa)808 void MacroAssembler::Fnmadd(const FPRegister& fd,
809                             const FPRegister& fn,
810                             const FPRegister& fm,
811                             const FPRegister& fa) {
812   DCHECK(allow_macro_instructions_);
813   fnmadd(fd, fn, fm, fa);
814 }
815 
816 
Fnmsub(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm,const FPRegister & fa)817 void MacroAssembler::Fnmsub(const FPRegister& fd,
818                             const FPRegister& fn,
819                             const FPRegister& fm,
820                             const FPRegister& fa) {
821   DCHECK(allow_macro_instructions_);
822   fnmsub(fd, fn, fm, fa);
823 }
824 
825 
Frinta(const FPRegister & fd,const FPRegister & fn)826 void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) {
827   DCHECK(allow_macro_instructions_);
828   frinta(fd, fn);
829 }
830 
831 
Frintm(const FPRegister & fd,const FPRegister & fn)832 void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) {
833   DCHECK(allow_macro_instructions_);
834   frintm(fd, fn);
835 }
836 
837 
Frintn(const FPRegister & fd,const FPRegister & fn)838 void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) {
839   DCHECK(allow_macro_instructions_);
840   frintn(fd, fn);
841 }
842 
843 
Frintp(const FPRegister & fd,const FPRegister & fn)844 void MacroAssembler::Frintp(const FPRegister& fd, const FPRegister& fn) {
845   DCHECK(allow_macro_instructions_);
846   frintp(fd, fn);
847 }
848 
849 
Frintz(const FPRegister & fd,const FPRegister & fn)850 void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) {
851   DCHECK(allow_macro_instructions_);
852   frintz(fd, fn);
853 }
854 
855 
Fsqrt(const FPRegister & fd,const FPRegister & fn)856 void MacroAssembler::Fsqrt(const FPRegister& fd, const FPRegister& fn) {
857   DCHECK(allow_macro_instructions_);
858   fsqrt(fd, fn);
859 }
860 
861 
Fsub(const FPRegister & fd,const FPRegister & fn,const FPRegister & fm)862 void MacroAssembler::Fsub(const FPRegister& fd,
863                           const FPRegister& fn,
864                           const FPRegister& fm) {
865   DCHECK(allow_macro_instructions_);
866   fsub(fd, fn, fm);
867 }
868 
869 
Hint(SystemHint code)870 void MacroAssembler::Hint(SystemHint code) {
871   DCHECK(allow_macro_instructions_);
872   hint(code);
873 }
874 
875 
Hlt(int code)876 void MacroAssembler::Hlt(int code) {
877   DCHECK(allow_macro_instructions_);
878   hlt(code);
879 }
880 
881 
Isb()882 void MacroAssembler::Isb() {
883   DCHECK(allow_macro_instructions_);
884   isb();
885 }
886 
887 
Ldr(const CPURegister & rt,const Immediate & imm)888 void MacroAssembler::Ldr(const CPURegister& rt, const Immediate& imm) {
889   DCHECK(allow_macro_instructions_);
890   ldr(rt, imm);
891 }
892 
893 
Ldr(const CPURegister & rt,double imm)894 void MacroAssembler::Ldr(const CPURegister& rt, double imm) {
895   DCHECK(allow_macro_instructions_);
896   DCHECK(rt.Is64Bits());
897   ldr(rt, Immediate(double_to_rawbits(imm)));
898 }
899 
900 
Lsl(const Register & rd,const Register & rn,unsigned shift)901 void MacroAssembler::Lsl(const Register& rd,
902                          const Register& rn,
903                          unsigned shift) {
904   DCHECK(allow_macro_instructions_);
905   DCHECK(!rd.IsZero());
906   lsl(rd, rn, shift);
907 }
908 
909 
Lsl(const Register & rd,const Register & rn,const Register & rm)910 void MacroAssembler::Lsl(const Register& rd,
911                          const Register& rn,
912                          const Register& rm) {
913   DCHECK(allow_macro_instructions_);
914   DCHECK(!rd.IsZero());
915   lslv(rd, rn, rm);
916 }
917 
918 
Lsr(const Register & rd,const Register & rn,unsigned shift)919 void MacroAssembler::Lsr(const Register& rd,
920                          const Register& rn,
921                          unsigned shift) {
922   DCHECK(allow_macro_instructions_);
923   DCHECK(!rd.IsZero());
924   lsr(rd, rn, shift);
925 }
926 
927 
Lsr(const Register & rd,const Register & rn,const Register & rm)928 void MacroAssembler::Lsr(const Register& rd,
929                          const Register& rn,
930                          const Register& rm) {
931   DCHECK(allow_macro_instructions_);
932   DCHECK(!rd.IsZero());
933   lsrv(rd, rn, rm);
934 }
935 
936 
Madd(const Register & rd,const Register & rn,const Register & rm,const Register & ra)937 void MacroAssembler::Madd(const Register& rd,
938                           const Register& rn,
939                           const Register& rm,
940                           const Register& ra) {
941   DCHECK(allow_macro_instructions_);
942   DCHECK(!rd.IsZero());
943   madd(rd, rn, rm, ra);
944 }
945 
946 
Mneg(const Register & rd,const Register & rn,const Register & rm)947 void MacroAssembler::Mneg(const Register& rd,
948                           const Register& rn,
949                           const Register& rm) {
950   DCHECK(allow_macro_instructions_);
951   DCHECK(!rd.IsZero());
952   mneg(rd, rn, rm);
953 }
954 
955 
Mov(const Register & rd,const Register & rn)956 void MacroAssembler::Mov(const Register& rd, const Register& rn) {
957   DCHECK(allow_macro_instructions_);
958   DCHECK(!rd.IsZero());
959   // Emit a register move only if the registers are distinct, or if they are
960   // not X registers. Note that mov(w0, w0) is not a no-op because it clears
961   // the top word of x0.
962   if (!rd.Is(rn) || !rd.Is64Bits()) {
963     Assembler::mov(rd, rn);
964   }
965 }
966 
967 
Movk(const Register & rd,uint64_t imm,int shift)968 void MacroAssembler::Movk(const Register& rd, uint64_t imm, int shift) {
969   DCHECK(allow_macro_instructions_);
970   DCHECK(!rd.IsZero());
971   movk(rd, imm, shift);
972 }
973 
974 
Mrs(const Register & rt,SystemRegister sysreg)975 void MacroAssembler::Mrs(const Register& rt, SystemRegister sysreg) {
976   DCHECK(allow_macro_instructions_);
977   DCHECK(!rt.IsZero());
978   mrs(rt, sysreg);
979 }
980 
981 
Msr(SystemRegister sysreg,const Register & rt)982 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
983   DCHECK(allow_macro_instructions_);
984   msr(sysreg, rt);
985 }
986 
987 
Msub(const Register & rd,const Register & rn,const Register & rm,const Register & ra)988 void MacroAssembler::Msub(const Register& rd,
989                           const Register& rn,
990                           const Register& rm,
991                           const Register& ra) {
992   DCHECK(allow_macro_instructions_);
993   DCHECK(!rd.IsZero());
994   msub(rd, rn, rm, ra);
995 }
996 
997 
Mul(const Register & rd,const Register & rn,const Register & rm)998 void MacroAssembler::Mul(const Register& rd,
999                          const Register& rn,
1000                          const Register& rm) {
1001   DCHECK(allow_macro_instructions_);
1002   DCHECK(!rd.IsZero());
1003   mul(rd, rn, rm);
1004 }
1005 
1006 
Rbit(const Register & rd,const Register & rn)1007 void MacroAssembler::Rbit(const Register& rd, const Register& rn) {
1008   DCHECK(allow_macro_instructions_);
1009   DCHECK(!rd.IsZero());
1010   rbit(rd, rn);
1011 }
1012 
1013 
Ret(const Register & xn)1014 void MacroAssembler::Ret(const Register& xn) {
1015   DCHECK(allow_macro_instructions_);
1016   DCHECK(!xn.IsZero());
1017   ret(xn);
1018   CheckVeneerPool(false, false);
1019 }
1020 
1021 
Rev(const Register & rd,const Register & rn)1022 void MacroAssembler::Rev(const Register& rd, const Register& rn) {
1023   DCHECK(allow_macro_instructions_);
1024   DCHECK(!rd.IsZero());
1025   rev(rd, rn);
1026 }
1027 
1028 
Rev16(const Register & rd,const Register & rn)1029 void MacroAssembler::Rev16(const Register& rd, const Register& rn) {
1030   DCHECK(allow_macro_instructions_);
1031   DCHECK(!rd.IsZero());
1032   rev16(rd, rn);
1033 }
1034 
1035 
Rev32(const Register & rd,const Register & rn)1036 void MacroAssembler::Rev32(const Register& rd, const Register& rn) {
1037   DCHECK(allow_macro_instructions_);
1038   DCHECK(!rd.IsZero());
1039   rev32(rd, rn);
1040 }
1041 
1042 
Ror(const Register & rd,const Register & rs,unsigned shift)1043 void MacroAssembler::Ror(const Register& rd,
1044                          const Register& rs,
1045                          unsigned shift) {
1046   DCHECK(allow_macro_instructions_);
1047   DCHECK(!rd.IsZero());
1048   ror(rd, rs, shift);
1049 }
1050 
1051 
Ror(const Register & rd,const Register & rn,const Register & rm)1052 void MacroAssembler::Ror(const Register& rd,
1053                          const Register& rn,
1054                          const Register& rm) {
1055   DCHECK(allow_macro_instructions_);
1056   DCHECK(!rd.IsZero());
1057   rorv(rd, rn, rm);
1058 }
1059 
1060 
Sbfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1061 void MacroAssembler::Sbfiz(const Register& rd,
1062                            const Register& rn,
1063                            unsigned lsb,
1064                            unsigned width) {
1065   DCHECK(allow_macro_instructions_);
1066   DCHECK(!rd.IsZero());
1067   sbfiz(rd, rn, lsb, width);
1068 }
1069 
1070 
Sbfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1071 void MacroAssembler::Sbfx(const Register& rd,
1072                           const Register& rn,
1073                           unsigned lsb,
1074                           unsigned width) {
1075   DCHECK(allow_macro_instructions_);
1076   DCHECK(!rd.IsZero());
1077   sbfx(rd, rn, lsb, width);
1078 }
1079 
1080 
Scvtf(const FPRegister & fd,const Register & rn,unsigned fbits)1081 void MacroAssembler::Scvtf(const FPRegister& fd,
1082                            const Register& rn,
1083                            unsigned fbits) {
1084   DCHECK(allow_macro_instructions_);
1085   scvtf(fd, rn, fbits);
1086 }
1087 
1088 
Sdiv(const Register & rd,const Register & rn,const Register & rm)1089 void MacroAssembler::Sdiv(const Register& rd,
1090                           const Register& rn,
1091                           const Register& rm) {
1092   DCHECK(allow_macro_instructions_);
1093   DCHECK(!rd.IsZero());
1094   sdiv(rd, rn, rm);
1095 }
1096 
1097 
Smaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1098 void MacroAssembler::Smaddl(const Register& rd,
1099                             const Register& rn,
1100                             const Register& rm,
1101                             const Register& ra) {
1102   DCHECK(allow_macro_instructions_);
1103   DCHECK(!rd.IsZero());
1104   smaddl(rd, rn, rm, ra);
1105 }
1106 
1107 
Smsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1108 void MacroAssembler::Smsubl(const Register& rd,
1109                             const Register& rn,
1110                             const Register& rm,
1111                             const Register& ra) {
1112   DCHECK(allow_macro_instructions_);
1113   DCHECK(!rd.IsZero());
1114   smsubl(rd, rn, rm, ra);
1115 }
1116 
1117 
Smull(const Register & rd,const Register & rn,const Register & rm)1118 void MacroAssembler::Smull(const Register& rd,
1119                            const Register& rn,
1120                            const Register& rm) {
1121   DCHECK(allow_macro_instructions_);
1122   DCHECK(!rd.IsZero());
1123   smull(rd, rn, rm);
1124 }
1125 
1126 
Smulh(const Register & rd,const Register & rn,const Register & rm)1127 void MacroAssembler::Smulh(const Register& rd,
1128                            const Register& rn,
1129                            const Register& rm) {
1130   DCHECK(allow_macro_instructions_);
1131   DCHECK(!rd.IsZero());
1132   smulh(rd, rn, rm);
1133 }
1134 
1135 
Umull(const Register & rd,const Register & rn,const Register & rm)1136 void MacroAssembler::Umull(const Register& rd, const Register& rn,
1137                            const Register& rm) {
1138   DCHECK(allow_macro_instructions_);
1139   DCHECK(!rd.IsZero());
1140   umaddl(rd, rn, rm, xzr);
1141 }
1142 
1143 
Sxtb(const Register & rd,const Register & rn)1144 void MacroAssembler::Sxtb(const Register& rd, const Register& rn) {
1145   DCHECK(allow_macro_instructions_);
1146   DCHECK(!rd.IsZero());
1147   sxtb(rd, rn);
1148 }
1149 
1150 
Sxth(const Register & rd,const Register & rn)1151 void MacroAssembler::Sxth(const Register& rd, const Register& rn) {
1152   DCHECK(allow_macro_instructions_);
1153   DCHECK(!rd.IsZero());
1154   sxth(rd, rn);
1155 }
1156 
1157 
Sxtw(const Register & rd,const Register & rn)1158 void MacroAssembler::Sxtw(const Register& rd, const Register& rn) {
1159   DCHECK(allow_macro_instructions_);
1160   DCHECK(!rd.IsZero());
1161   sxtw(rd, rn);
1162 }
1163 
1164 
Ubfiz(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1165 void MacroAssembler::Ubfiz(const Register& rd,
1166                            const Register& rn,
1167                            unsigned lsb,
1168                            unsigned width) {
1169   DCHECK(allow_macro_instructions_);
1170   DCHECK(!rd.IsZero());
1171   ubfiz(rd, rn, lsb, width);
1172 }
1173 
1174 
Ubfx(const Register & rd,const Register & rn,unsigned lsb,unsigned width)1175 void MacroAssembler::Ubfx(const Register& rd,
1176                           const Register& rn,
1177                           unsigned lsb,
1178                           unsigned width) {
1179   DCHECK(allow_macro_instructions_);
1180   DCHECK(!rd.IsZero());
1181   ubfx(rd, rn, lsb, width);
1182 }
1183 
1184 
Ucvtf(const FPRegister & fd,const Register & rn,unsigned fbits)1185 void MacroAssembler::Ucvtf(const FPRegister& fd,
1186                            const Register& rn,
1187                            unsigned fbits) {
1188   DCHECK(allow_macro_instructions_);
1189   ucvtf(fd, rn, fbits);
1190 }
1191 
1192 
Udiv(const Register & rd,const Register & rn,const Register & rm)1193 void MacroAssembler::Udiv(const Register& rd,
1194                           const Register& rn,
1195                           const Register& rm) {
1196   DCHECK(allow_macro_instructions_);
1197   DCHECK(!rd.IsZero());
1198   udiv(rd, rn, rm);
1199 }
1200 
1201 
Umaddl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1202 void MacroAssembler::Umaddl(const Register& rd,
1203                             const Register& rn,
1204                             const Register& rm,
1205                             const Register& ra) {
1206   DCHECK(allow_macro_instructions_);
1207   DCHECK(!rd.IsZero());
1208   umaddl(rd, rn, rm, ra);
1209 }
1210 
1211 
Umsubl(const Register & rd,const Register & rn,const Register & rm,const Register & ra)1212 void MacroAssembler::Umsubl(const Register& rd,
1213                             const Register& rn,
1214                             const Register& rm,
1215                             const Register& ra) {
1216   DCHECK(allow_macro_instructions_);
1217   DCHECK(!rd.IsZero());
1218   umsubl(rd, rn, rm, ra);
1219 }
1220 
1221 
Uxtb(const Register & rd,const Register & rn)1222 void MacroAssembler::Uxtb(const Register& rd, const Register& rn) {
1223   DCHECK(allow_macro_instructions_);
1224   DCHECK(!rd.IsZero());
1225   uxtb(rd, rn);
1226 }
1227 
1228 
Uxth(const Register & rd,const Register & rn)1229 void MacroAssembler::Uxth(const Register& rd, const Register& rn) {
1230   DCHECK(allow_macro_instructions_);
1231   DCHECK(!rd.IsZero());
1232   uxth(rd, rn);
1233 }
1234 
1235 
Uxtw(const Register & rd,const Register & rn)1236 void MacroAssembler::Uxtw(const Register& rd, const Register& rn) {
1237   DCHECK(allow_macro_instructions_);
1238   DCHECK(!rd.IsZero());
1239   uxtw(rd, rn);
1240 }
1241 
1242 
BumpSystemStackPointer(const Operand & space)1243 void MacroAssembler::BumpSystemStackPointer(const Operand& space) {
1244   DCHECK(!csp.Is(sp_));
1245   if (!TmpList()->IsEmpty()) {
1246     Sub(csp, StackPointer(), space);
1247   } else {
1248     // TODO(jbramley): Several callers rely on this not using scratch
1249     // registers, so we use the assembler directly here. However, this means
1250     // that large immediate values of 'space' cannot be handled cleanly. (Only
1251     // 24-bits immediates or values of 'space' that can be encoded in one
1252     // instruction are accepted.) Once we implement our flexible scratch
1253     // register idea, we could greatly simplify this function.
1254     InstructionAccurateScope scope(this);
1255     DCHECK(space.IsImmediate());
1256     // Align to 16 bytes.
1257     uint64_t imm = RoundUp(space.ImmediateValue(), 0x10);
1258     DCHECK(is_uint24(imm));
1259 
1260     Register source = StackPointer();
1261     if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
1262       bic(csp, source, 0xf);
1263       source = csp;
1264     }
1265     if (!is_uint12(imm)) {
1266       int64_t imm_top_12_bits = imm >> 12;
1267       sub(csp, source, imm_top_12_bits << 12);
1268       source = csp;
1269       imm -= imm_top_12_bits << 12;
1270     }
1271     if (imm > 0) {
1272       sub(csp, source, imm);
1273     }
1274   }
1275   AssertStackConsistency();
1276 }
1277 
1278 
SyncSystemStackPointer()1279 void MacroAssembler::SyncSystemStackPointer() {
1280   DCHECK(emit_debug_code());
1281   DCHECK(!csp.Is(sp_));
1282   { InstructionAccurateScope scope(this);
1283     mov(csp, StackPointer());
1284   }
1285   AssertStackConsistency();
1286 }
1287 
1288 
InitializeRootRegister()1289 void MacroAssembler::InitializeRootRegister() {
1290   ExternalReference roots_array_start =
1291       ExternalReference::roots_array_start(isolate());
1292   Mov(root, Operand(roots_array_start));
1293 }
1294 
1295 
SmiTag(Register dst,Register src)1296 void MacroAssembler::SmiTag(Register dst, Register src) {
1297   STATIC_ASSERT(kXRegSizeInBits ==
1298                 static_cast<unsigned>(kSmiShift + kSmiValueSize));
1299   DCHECK(dst.Is64Bits() && src.Is64Bits());
1300   Lsl(dst, src, kSmiShift);
1301 }
1302 
1303 
SmiTag(Register smi)1304 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); }
1305 
1306 
SmiUntag(Register dst,Register src)1307 void MacroAssembler::SmiUntag(Register dst, Register src) {
1308   STATIC_ASSERT(kXRegSizeInBits ==
1309                 static_cast<unsigned>(kSmiShift + kSmiValueSize));
1310   DCHECK(dst.Is64Bits() && src.Is64Bits());
1311   if (FLAG_enable_slow_asserts) {
1312     AssertSmi(src);
1313   }
1314   Asr(dst, src, kSmiShift);
1315 }
1316 
1317 
SmiUntag(Register smi)1318 void MacroAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); }
1319 
1320 
SmiUntagToDouble(FPRegister dst,Register src,UntagMode mode)1321 void MacroAssembler::SmiUntagToDouble(FPRegister dst,
1322                                       Register src,
1323                                       UntagMode mode) {
1324   DCHECK(dst.Is64Bits() && src.Is64Bits());
1325   if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) {
1326     AssertSmi(src);
1327   }
1328   Scvtf(dst, src, kSmiShift);
1329 }
1330 
1331 
SmiUntagToFloat(FPRegister dst,Register src,UntagMode mode)1332 void MacroAssembler::SmiUntagToFloat(FPRegister dst,
1333                                      Register src,
1334                                      UntagMode mode) {
1335   DCHECK(dst.Is32Bits() && src.Is64Bits());
1336   if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) {
1337     AssertSmi(src);
1338   }
1339   Scvtf(dst, src, kSmiShift);
1340 }
1341 
1342 
SmiTagAndPush(Register src)1343 void MacroAssembler::SmiTagAndPush(Register src) {
1344   STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) &&
1345                 (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) &&
1346                 (kSmiTag == 0));
1347   Push(src.W(), wzr);
1348 }
1349 
1350 
SmiTagAndPush(Register src1,Register src2)1351 void MacroAssembler::SmiTagAndPush(Register src1, Register src2) {
1352   STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) &&
1353                 (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) &&
1354                 (kSmiTag == 0));
1355   Push(src1.W(), wzr, src2.W(), wzr);
1356 }
1357 
1358 
JumpIfSmi(Register value,Label * smi_label,Label * not_smi_label)1359 void MacroAssembler::JumpIfSmi(Register value,
1360                                Label* smi_label,
1361                                Label* not_smi_label) {
1362   STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1363   // Check if the tag bit is set.
1364   if (smi_label) {
1365     Tbz(value, 0, smi_label);
1366     if (not_smi_label) {
1367       B(not_smi_label);
1368     }
1369   } else {
1370     DCHECK(not_smi_label);
1371     Tbnz(value, 0, not_smi_label);
1372   }
1373 }
1374 
1375 
JumpIfNotSmi(Register value,Label * not_smi_label)1376 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) {
1377   JumpIfSmi(value, NULL, not_smi_label);
1378 }
1379 
1380 
JumpIfBothSmi(Register value1,Register value2,Label * both_smi_label,Label * not_smi_label)1381 void MacroAssembler::JumpIfBothSmi(Register value1,
1382                                    Register value2,
1383                                    Label* both_smi_label,
1384                                    Label* not_smi_label) {
1385   STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1386   UseScratchRegisterScope temps(this);
1387   Register tmp = temps.AcquireX();
1388   // Check if both tag bits are clear.
1389   Orr(tmp, value1, value2);
1390   JumpIfSmi(tmp, both_smi_label, not_smi_label);
1391 }
1392 
1393 
JumpIfEitherSmi(Register value1,Register value2,Label * either_smi_label,Label * not_smi_label)1394 void MacroAssembler::JumpIfEitherSmi(Register value1,
1395                                      Register value2,
1396                                      Label* either_smi_label,
1397                                      Label* not_smi_label) {
1398   STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0));
1399   UseScratchRegisterScope temps(this);
1400   Register tmp = temps.AcquireX();
1401   // Check if either tag bit is clear.
1402   And(tmp, value1, value2);
1403   JumpIfSmi(tmp, either_smi_label, not_smi_label);
1404 }
1405 
1406 
JumpIfEitherNotSmi(Register value1,Register value2,Label * not_smi_label)1407 void MacroAssembler::JumpIfEitherNotSmi(Register value1,
1408                                         Register value2,
1409                                         Label* not_smi_label) {
1410   JumpIfBothSmi(value1, value2, NULL, not_smi_label);
1411 }
1412 
1413 
JumpIfBothNotSmi(Register value1,Register value2,Label * not_smi_label)1414 void MacroAssembler::JumpIfBothNotSmi(Register value1,
1415                                       Register value2,
1416                                       Label* not_smi_label) {
1417   JumpIfEitherSmi(value1, value2, NULL, not_smi_label);
1418 }
1419 
1420 
ObjectTag(Register tagged_obj,Register obj)1421 void MacroAssembler::ObjectTag(Register tagged_obj, Register obj) {
1422   STATIC_ASSERT(kHeapObjectTag == 1);
1423   if (emit_debug_code()) {
1424     Label ok;
1425     Tbz(obj, 0, &ok);
1426     Abort(kObjectTagged);
1427     Bind(&ok);
1428   }
1429   Orr(tagged_obj, obj, kHeapObjectTag);
1430 }
1431 
1432 
ObjectUntag(Register untagged_obj,Register obj)1433 void MacroAssembler::ObjectUntag(Register untagged_obj, Register obj) {
1434   STATIC_ASSERT(kHeapObjectTag == 1);
1435   if (emit_debug_code()) {
1436     Label ok;
1437     Tbnz(obj, 0, &ok);
1438     Abort(kObjectNotTagged);
1439     Bind(&ok);
1440   }
1441   Bic(untagged_obj, obj, kHeapObjectTag);
1442 }
1443 
1444 
IsObjectNameType(Register object,Register type,Label * fail)1445 void MacroAssembler::IsObjectNameType(Register object,
1446                                       Register type,
1447                                       Label* fail) {
1448   CompareObjectType(object, type, type, LAST_NAME_TYPE);
1449   B(hi, fail);
1450 }
1451 
1452 
IsObjectJSStringType(Register object,Register type,Label * not_string,Label * string)1453 void MacroAssembler::IsObjectJSStringType(Register object,
1454                                           Register type,
1455                                           Label* not_string,
1456                                           Label* string) {
1457   Ldr(type, FieldMemOperand(object, HeapObject::kMapOffset));
1458   Ldrb(type.W(), FieldMemOperand(type, Map::kInstanceTypeOffset));
1459 
1460   STATIC_ASSERT(kStringTag == 0);
1461   DCHECK((string != NULL) || (not_string != NULL));
1462   if (string == NULL) {
1463     TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string);
1464   } else if (not_string == NULL) {
1465     TestAndBranchIfAllClear(type.W(), kIsNotStringMask, string);
1466   } else {
1467     TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string);
1468     B(string);
1469   }
1470 }
1471 
1472 
Push(Handle<Object> handle)1473 void MacroAssembler::Push(Handle<Object> handle) {
1474   UseScratchRegisterScope temps(this);
1475   Register tmp = temps.AcquireX();
1476   Mov(tmp, Operand(handle));
1477   Push(tmp);
1478 }
1479 
1480 
Claim(int64_t count,uint64_t unit_size)1481 void MacroAssembler::Claim(int64_t count, uint64_t unit_size) {
1482   DCHECK(count >= 0);
1483   uint64_t size = count * unit_size;
1484 
1485   if (size == 0) {
1486     return;
1487   }
1488 
1489   if (csp.Is(StackPointer())) {
1490     DCHECK(size % 16 == 0);
1491   } else {
1492     BumpSystemStackPointer(size);
1493   }
1494 
1495   Sub(StackPointer(), StackPointer(), size);
1496 }
1497 
1498 
Claim(const Register & count,uint64_t unit_size)1499 void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
1500   if (unit_size == 0) return;
1501   DCHECK(base::bits::IsPowerOfTwo64(unit_size));
1502 
1503   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1504   const Operand size(count, LSL, shift);
1505 
1506   if (size.IsZero()) {
1507     return;
1508   }
1509 
1510   AssertPositiveOrZero(count);
1511   if (!csp.Is(StackPointer())) {
1512     BumpSystemStackPointer(size);
1513   }
1514 
1515   Sub(StackPointer(), StackPointer(), size);
1516 }
1517 
1518 
ClaimBySMI(const Register & count_smi,uint64_t unit_size)1519 void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) {
1520   DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
1521   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
1522   const Operand size(count_smi,
1523                      (shift >= 0) ? (LSL) : (LSR),
1524                      (shift >= 0) ? (shift) : (-shift));
1525 
1526   if (size.IsZero()) {
1527     return;
1528   }
1529 
1530   if (!csp.Is(StackPointer())) {
1531     BumpSystemStackPointer(size);
1532   }
1533 
1534   Sub(StackPointer(), StackPointer(), size);
1535 }
1536 
1537 
Drop(int64_t count,uint64_t unit_size)1538 void MacroAssembler::Drop(int64_t count, uint64_t unit_size) {
1539   DCHECK(count >= 0);
1540   uint64_t size = count * unit_size;
1541 
1542   if (size == 0) {
1543     return;
1544   }
1545 
1546   Add(StackPointer(), StackPointer(), size);
1547 
1548   if (csp.Is(StackPointer())) {
1549     DCHECK(size % 16 == 0);
1550   } else if (emit_debug_code()) {
1551     // It is safe to leave csp where it is when unwinding the JavaScript stack,
1552     // but if we keep it matching StackPointer, the simulator can detect memory
1553     // accesses in the now-free part of the stack.
1554     SyncSystemStackPointer();
1555   }
1556 }
1557 
1558 
Drop(const Register & count,uint64_t unit_size)1559 void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
1560   if (unit_size == 0) return;
1561   DCHECK(base::bits::IsPowerOfTwo64(unit_size));
1562 
1563   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
1564   const Operand size(count, LSL, shift);
1565 
1566   if (size.IsZero()) {
1567     return;
1568   }
1569 
1570   AssertPositiveOrZero(count);
1571   Add(StackPointer(), StackPointer(), size);
1572 
1573   if (!csp.Is(StackPointer()) && emit_debug_code()) {
1574     // It is safe to leave csp where it is when unwinding the JavaScript stack,
1575     // but if we keep it matching StackPointer, the simulator can detect memory
1576     // accesses in the now-free part of the stack.
1577     SyncSystemStackPointer();
1578   }
1579 }
1580 
1581 
DropBySMI(const Register & count_smi,uint64_t unit_size)1582 void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) {
1583   DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
1584   const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
1585   const Operand size(count_smi,
1586                      (shift >= 0) ? (LSL) : (LSR),
1587                      (shift >= 0) ? (shift) : (-shift));
1588 
1589   if (size.IsZero()) {
1590     return;
1591   }
1592 
1593   Add(StackPointer(), StackPointer(), size);
1594 
1595   if (!csp.Is(StackPointer()) && emit_debug_code()) {
1596     // It is safe to leave csp where it is when unwinding the JavaScript stack,
1597     // but if we keep it matching StackPointer, the simulator can detect memory
1598     // accesses in the now-free part of the stack.
1599     SyncSystemStackPointer();
1600   }
1601 }
1602 
1603 
CompareAndBranch(const Register & lhs,const Operand & rhs,Condition cond,Label * label)1604 void MacroAssembler::CompareAndBranch(const Register& lhs,
1605                                       const Operand& rhs,
1606                                       Condition cond,
1607                                       Label* label) {
1608   if (rhs.IsImmediate() && (rhs.ImmediateValue() == 0) &&
1609       ((cond == eq) || (cond == ne))) {
1610     if (cond == eq) {
1611       Cbz(lhs, label);
1612     } else {
1613       Cbnz(lhs, label);
1614     }
1615   } else {
1616     Cmp(lhs, rhs);
1617     B(cond, label);
1618   }
1619 }
1620 
1621 
TestAndBranchIfAnySet(const Register & reg,const uint64_t bit_pattern,Label * label)1622 void MacroAssembler::TestAndBranchIfAnySet(const Register& reg,
1623                                            const uint64_t bit_pattern,
1624                                            Label* label) {
1625   int bits = reg.SizeInBits();
1626   DCHECK(CountSetBits(bit_pattern, bits) > 0);
1627   if (CountSetBits(bit_pattern, bits) == 1) {
1628     Tbnz(reg, MaskToBit(bit_pattern), label);
1629   } else {
1630     Tst(reg, bit_pattern);
1631     B(ne, label);
1632   }
1633 }
1634 
1635 
TestAndBranchIfAllClear(const Register & reg,const uint64_t bit_pattern,Label * label)1636 void MacroAssembler::TestAndBranchIfAllClear(const Register& reg,
1637                                              const uint64_t bit_pattern,
1638                                              Label* label) {
1639   int bits = reg.SizeInBits();
1640   DCHECK(CountSetBits(bit_pattern, bits) > 0);
1641   if (CountSetBits(bit_pattern, bits) == 1) {
1642     Tbz(reg, MaskToBit(bit_pattern), label);
1643   } else {
1644     Tst(reg, bit_pattern);
1645     B(eq, label);
1646   }
1647 }
1648 
1649 
InlineData(uint64_t data)1650 void MacroAssembler::InlineData(uint64_t data) {
1651   DCHECK(is_uint16(data));
1652   InstructionAccurateScope scope(this, 1);
1653   movz(xzr, data);
1654 }
1655 
1656 
EnableInstrumentation()1657 void MacroAssembler::EnableInstrumentation() {
1658   InstructionAccurateScope scope(this, 1);
1659   movn(xzr, InstrumentStateEnable);
1660 }
1661 
1662 
DisableInstrumentation()1663 void MacroAssembler::DisableInstrumentation() {
1664   InstructionAccurateScope scope(this, 1);
1665   movn(xzr, InstrumentStateDisable);
1666 }
1667 
1668 
AnnotateInstrumentation(const char * marker_name)1669 void MacroAssembler::AnnotateInstrumentation(const char* marker_name) {
1670   DCHECK(strlen(marker_name) == 2);
1671 
1672   // We allow only printable characters in the marker names. Unprintable
1673   // characters are reserved for controlling features of the instrumentation.
1674   DCHECK(isprint(marker_name[0]) && isprint(marker_name[1]));
1675 
1676   InstructionAccurateScope scope(this, 1);
1677   movn(xzr, (marker_name[1] << 8) | marker_name[0]);
1678 }
1679 
1680 }  // namespace internal
1681 }  // namespace v8
1682 
1683 #endif  // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
1684