Home | History | Annotate | Download | only in arm64
      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 
     23 MemOperand FieldMemOperand(Register object, int offset) {
     24   return MemOperand(object, offset - kHeapObjectTag);
     25 }
     26 
     27 
     28 MemOperand UntagSmiFieldMemOperand(Register object, int offset) {
     29   return UntagSmiMemOperand(object, offset - kHeapObjectTag);
     30 }
     31 
     32 
     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 
     40 Handle<Object> MacroAssembler::CodeObject() {
     41   DCHECK(!code_object_.is_null());
     42   return code_object_;
     43 }
     44 
     45 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    202 void MacroAssembler::Cmn(const Register& rn, const Operand& operand) {
    203   DCHECK(allow_macro_instructions_);
    204   Adds(AppropriateZeroRegFor(rn), rn, operand);
    205 }
    206 
    207 
    208 void MacroAssembler::Cmp(const Register& rn, const Operand& operand) {
    209   DCHECK(allow_macro_instructions_);
    210   Subs(AppropriateZeroRegFor(rn), rn, operand);
    211 }
    212 
    213 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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   }
    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 
    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 
    347 void MacroAssembler::B(Label* label) {
    348   b(label);
    349   CheckVeneerPool(false, false);
    350 }
    351 
    352 
    353 void MacroAssembler::B(Condition cond, Label* label) {
    354   DCHECK(allow_macro_instructions_);
    355   B(label, cond);
    356 }
    357 
    358 
    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 
    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 
    379 void MacroAssembler::Bind(Label* label) {
    380   DCHECK(allow_macro_instructions_);
    381   bind(label);
    382 }
    383 
    384 
    385 void MacroAssembler::Bl(Label* label) {
    386   DCHECK(allow_macro_instructions_);
    387   bl(label);
    388 }
    389 
    390 
    391 void MacroAssembler::Blr(const Register& xn) {
    392   DCHECK(allow_macro_instructions_);
    393   DCHECK(!xn.IsZero());
    394   blr(xn);
    395 }
    396 
    397 
    398 void MacroAssembler::Br(const Register& xn) {
    399   DCHECK(allow_macro_instructions_);
    400   DCHECK(!xn.IsZero());
    401   br(xn);
    402 }
    403 
    404 
    405 void MacroAssembler::Brk(int code) {
    406   DCHECK(allow_macro_instructions_);
    407   brk(code);
    408 }
    409 
    410 
    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 
    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 
    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 
    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 
    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.
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    530 void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) {
    531   DCHECK(allow_macro_instructions_);
    532   dmb(domain, type);
    533 }
    534 
    535 
    536 void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) {
    537   DCHECK(allow_macro_instructions_);
    538   dsb(domain, type);
    539 }
    540 
    541 
    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 
    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 
    558 void MacroAssembler::Fabs(const FPRegister& fd, const FPRegister& fn) {
    559   DCHECK(allow_macro_instructions_);
    560   fabs(fd, fn);
    561 }
    562 
    563 
    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 
    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 
    582 void MacroAssembler::Fcmp(const FPRegister& fn, const FPRegister& fm) {
    583   DCHECK(allow_macro_instructions_);
    584   fcmp(fn, fm);
    585 }
    586 
    587 
    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 
    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 
    611 void MacroAssembler::Fcvt(const FPRegister& fd, const FPRegister& fn) {
    612   DCHECK(allow_macro_instructions_);
    613   fcvt(fd, fn);
    614 }
    615 
    616 
    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 
    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 
    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 
    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 
    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 
    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 
    659 void MacroAssembler::Fcvtzs(const Register& rd, const FPRegister& fn) {
    660   DCHECK(allow_macro_instructions_);
    661   DCHECK(!rd.IsZero());
    662   fcvtzs(rd, fn);
    663 }
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    732 void MacroAssembler::Fmov(FPRegister fd, Register rn) {
    733   DCHECK(allow_macro_instructions_);
    734   fmov(fd, rn);
    735 }
    736 
    737 
    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 
    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 
    778 void MacroAssembler::Fmov(Register rd, FPRegister fn) {
    779   DCHECK(allow_macro_instructions_);
    780   DCHECK(!rd.IsZero());
    781   fmov(rd, fn);
    782 }
    783 
    784 
    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 
    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 
    802 void MacroAssembler::Fneg(const FPRegister& fd, const FPRegister& fn) {
    803   DCHECK(allow_macro_instructions_);
    804   fneg(fd, fn);
    805 }
    806 
    807 
    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 
    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 
    826 void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) {
    827   DCHECK(allow_macro_instructions_);
    828   frinta(fd, fn);
    829 }
    830 
    831 
    832 void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) {
    833   DCHECK(allow_macro_instructions_);
    834   frintm(fd, fn);
    835 }
    836 
    837 
    838 void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) {
    839   DCHECK(allow_macro_instructions_);
    840   frintn(fd, fn);
    841 }
    842 
    843 
    844 void MacroAssembler::Frintp(const FPRegister& fd, const FPRegister& fn) {
    845   DCHECK(allow_macro_instructions_);
    846   frintp(fd, fn);
    847 }
    848 
    849 
    850 void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) {
    851   DCHECK(allow_macro_instructions_);
    852   frintz(fd, fn);
    853 }
    854 
    855 
    856 void MacroAssembler::Fsqrt(const FPRegister& fd, const FPRegister& fn) {
    857   DCHECK(allow_macro_instructions_);
    858   fsqrt(fd, fn);
    859 }
    860 
    861 
    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 
    870 void MacroAssembler::Hint(SystemHint code) {
    871   DCHECK(allow_macro_instructions_);
    872   hint(code);
    873 }
    874 
    875 
    876 void MacroAssembler::Hlt(int code) {
    877   DCHECK(allow_macro_instructions_);
    878   hlt(code);
    879 }
    880 
    881 
    882 void MacroAssembler::Isb() {
    883   DCHECK(allow_macro_instructions_);
    884   isb();
    885 }
    886 
    887 
    888 void MacroAssembler::Ldr(const CPURegister& rt, const Immediate& imm) {
    889   DCHECK(allow_macro_instructions_);
    890   ldr(rt, imm);
    891 }
    892 
    893 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    982 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
    983   DCHECK(allow_macro_instructions_);
    984   msr(sysreg, rt);
    985 }
    986 
    987 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1304 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); }
   1305 
   1306 
   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 
   1318 void MacroAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); }
   1319 
   1320 
   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 
   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 
   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 
   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 
   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 
   1376 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) {
   1377   JumpIfSmi(value, NULL, not_smi_label);
   1378 }
   1379 
   1380 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1650 void MacroAssembler::InlineData(uint64_t data) {
   1651   DCHECK(is_uint16(data));
   1652   InstructionAccurateScope scope(this, 1);
   1653   movz(xzr, data);
   1654 }
   1655 
   1656 
   1657 void MacroAssembler::EnableInstrumentation() {
   1658   InstructionAccurateScope scope(this, 1);
   1659   movn(xzr, InstrumentStateEnable);
   1660 }
   1661 
   1662 
   1663 void MacroAssembler::DisableInstrumentation() {
   1664   InstructionAccurateScope scope(this, 1);
   1665   movn(xzr, InstrumentStateDisable);
   1666 }
   1667 
   1668 
   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