Home | History | Annotate | Download | only in mips64
      1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 // - Redistributions of source code must retain the above copyright notice,
      9 // this list of conditions and the following disclaimer.
     10 //
     11 // - Redistribution in binary form must reproduce the above copyright
     12 // notice, this list of conditions and the following disclaimer in the
     13 // documentation and/or other materials provided with the distribution.
     14 //
     15 // - Neither the name of Sun Microsystems or the names of contributors may
     16 // be used to endorse or promote products derived from this software without
     17 // specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // The original source code covered by the above license above has been
     32 // modified significantly by Google Inc.
     33 // Copyright 2012 the V8 project authors. All rights reserved.
     34 
     35 #include "src/mips64/assembler-mips64.h"
     36 
     37 #if V8_TARGET_ARCH_MIPS64
     38 
     39 #include "src/base/cpu.h"
     40 #include "src/mips64/assembler-mips64-inl.h"
     41 
     42 namespace v8 {
     43 namespace internal {
     44 
     45 
     46 // Get the CPU features enabled by the build. For cross compilation the
     47 // preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
     48 // can be defined to enable FPU instructions when building the
     49 // snapshot.
     50 static unsigned CpuFeaturesImpliedByCompiler() {
     51   unsigned answer = 0;
     52 #ifdef CAN_USE_FPU_INSTRUCTIONS
     53   answer |= 1u << FPU;
     54 #endif  // def CAN_USE_FPU_INSTRUCTIONS
     55 
     56   // If the compiler is allowed to use FPU then we can use FPU too in our code
     57   // generation even when generating snapshots.  This won't work for cross
     58   // compilation.
     59 #if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
     60   answer |= 1u << FPU;
     61 #endif
     62 
     63   return answer;
     64 }
     65 
     66 
     67 void CpuFeatures::ProbeImpl(bool cross_compile) {
     68   supported_ |= CpuFeaturesImpliedByCompiler();
     69 
     70   // Only use statically determined features for cross compile (snapshot).
     71   if (cross_compile) return;
     72 
     73   // If the compiler is allowed to use fpu then we can use fpu too in our
     74   // code generation.
     75 #ifndef __mips__
     76   // For the simulator build, use FPU.
     77   supported_ |= 1u << FPU;
     78 #else
     79   // Probe for additional features at runtime.
     80   base::CPU cpu;
     81   if (cpu.has_fpu()) supported_ |= 1u << FPU;
     82 #endif
     83 }
     84 
     85 
     86 void CpuFeatures::PrintTarget() { }
     87 void CpuFeatures::PrintFeatures() { }
     88 
     89 
     90 int ToNumber(Register reg) {
     91   DCHECK(reg.is_valid());
     92   const int kNumbers[] = {
     93     0,    // zero_reg
     94     1,    // at
     95     2,    // v0
     96     3,    // v1
     97     4,    // a0
     98     5,    // a1
     99     6,    // a2
    100     7,    // a3
    101     8,    // a4
    102     9,    // a5
    103     10,   // a6
    104     11,   // a7
    105     12,   // t0
    106     13,   // t1
    107     14,   // t2
    108     15,   // t3
    109     16,   // s0
    110     17,   // s1
    111     18,   // s2
    112     19,   // s3
    113     20,   // s4
    114     21,   // s5
    115     22,   // s6
    116     23,   // s7
    117     24,   // t8
    118     25,   // t9
    119     26,   // k0
    120     27,   // k1
    121     28,   // gp
    122     29,   // sp
    123     30,   // fp
    124     31,   // ra
    125   };
    126   return kNumbers[reg.code()];
    127 }
    128 
    129 
    130 Register ToRegister(int num) {
    131   DCHECK(num >= 0 && num < kNumRegisters);
    132   const Register kRegisters[] = {
    133     zero_reg,
    134     at,
    135     v0, v1,
    136     a0, a1, a2, a3, a4, a5, a6, a7,
    137     t0, t1, t2, t3,
    138     s0, s1, s2, s3, s4, s5, s6, s7,
    139     t8, t9,
    140     k0, k1,
    141     gp,
    142     sp,
    143     fp,
    144     ra
    145   };
    146   return kRegisters[num];
    147 }
    148 
    149 
    150 // -----------------------------------------------------------------------------
    151 // Implementation of RelocInfo.
    152 
    153 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
    154                                   1 << RelocInfo::INTERNAL_REFERENCE |
    155                                   1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
    156 
    157 
    158 bool RelocInfo::IsCodedSpecially() {
    159   // The deserializer needs to know whether a pointer is specially coded.  Being
    160   // specially coded on MIPS means that it is a lui/ori instruction, and that is
    161   // always the case inside code objects.
    162   return true;
    163 }
    164 
    165 
    166 bool RelocInfo::IsInConstantPool() {
    167   return false;
    168 }
    169 
    170 Address RelocInfo::wasm_memory_reference() {
    171   DCHECK(IsWasmMemoryReference(rmode_));
    172   return Assembler::target_address_at(pc_, host_);
    173 }
    174 
    175 Address RelocInfo::wasm_global_reference() {
    176   DCHECK(IsWasmGlobalReference(rmode_));
    177   return Assembler::target_address_at(pc_, host_);
    178 }
    179 
    180 uint32_t RelocInfo::wasm_memory_size_reference() {
    181   DCHECK(IsWasmMemorySizeReference(rmode_));
    182   return static_cast<uint32_t>(
    183       reinterpret_cast<intptr_t>((Assembler::target_address_at(pc_, host_))));
    184 }
    185 
    186 void RelocInfo::unchecked_update_wasm_memory_reference(
    187     Address address, ICacheFlushMode flush_mode) {
    188   Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode);
    189 }
    190 
    191 void RelocInfo::unchecked_update_wasm_memory_size(uint32_t size,
    192                                                   ICacheFlushMode flush_mode) {
    193   Assembler::set_target_address_at(isolate_, pc_, host_,
    194                                    reinterpret_cast<Address>(size), flush_mode);
    195 }
    196 
    197 // -----------------------------------------------------------------------------
    198 // Implementation of Operand and MemOperand.
    199 // See assembler-mips-inl.h for inlined constructors.
    200 
    201 Operand::Operand(Handle<Object> handle) {
    202   AllowDeferredHandleDereference using_raw_address;
    203   rm_ = no_reg;
    204   // Verify all Objects referred by code are NOT in new space.
    205   Object* obj = *handle;
    206   if (obj->IsHeapObject()) {
    207     imm64_ = reinterpret_cast<intptr_t>(handle.location());
    208     rmode_ = RelocInfo::EMBEDDED_OBJECT;
    209   } else {
    210     // No relocation needed.
    211     imm64_ = reinterpret_cast<intptr_t>(obj);
    212     rmode_ = RelocInfo::NONE64;
    213   }
    214 }
    215 
    216 
    217 MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
    218   offset_ = offset;
    219 }
    220 
    221 
    222 MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
    223                        OffsetAddend offset_addend)
    224     : Operand(rm) {
    225   offset_ = unit * multiplier + offset_addend;
    226 }
    227 
    228 
    229 // -----------------------------------------------------------------------------
    230 // Specific instructions, constants, and masks.
    231 
    232 static const int kNegOffset = 0x00008000;
    233 // daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
    234 // operations as post-increment of sp.
    235 const Instr kPopInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
    236                               (Register::kCode_sp << kRtShift) |
    237                               (kPointerSize & kImm16Mask);  // NOLINT
    238 // daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
    239 const Instr kPushInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
    240                                (Register::kCode_sp << kRtShift) |
    241                                (-kPointerSize & kImm16Mask);  // NOLINT
    242 // sd(r, MemOperand(sp, 0))
    243 const Instr kPushRegPattern =
    244     SD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
    245 //  ld(r, MemOperand(sp, 0))
    246 const Instr kPopRegPattern =
    247     LD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
    248 
    249 const Instr kLwRegFpOffsetPattern =
    250     LW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
    251 
    252 const Instr kSwRegFpOffsetPattern =
    253     SW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
    254 
    255 const Instr kLwRegFpNegOffsetPattern = LW | (Register::kCode_fp << kRsShift) |
    256                                        (kNegOffset & kImm16Mask);  // NOLINT
    257 
    258 const Instr kSwRegFpNegOffsetPattern = SW | (Register::kCode_fp << kRsShift) |
    259                                        (kNegOffset & kImm16Mask);  // NOLINT
    260 // A mask for the Rt register for push, pop, lw, sw instructions.
    261 const Instr kRtMask = kRtFieldMask;
    262 const Instr kLwSwInstrTypeMask = 0xffe00000;
    263 const Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
    264 const Instr kLwSwOffsetMask = kImm16Mask;
    265 
    266 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
    267     : AssemblerBase(isolate, buffer, buffer_size),
    268       recorded_ast_id_(TypeFeedbackId::None()) {
    269   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
    270 
    271   last_trampoline_pool_end_ = 0;
    272   no_trampoline_pool_before_ = 0;
    273   trampoline_pool_blocked_nesting_ = 0;
    274   // We leave space (16 * kTrampolineSlotsSize)
    275   // for BlockTrampolinePoolScope buffer.
    276   next_buffer_check_ = FLAG_force_long_branches
    277       ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
    278   internal_trampoline_exception_ = false;
    279   last_bound_pos_ = 0;
    280 
    281   trampoline_emitted_ = FLAG_force_long_branches;
    282   unbound_labels_count_ = 0;
    283   block_buffer_growth_ = false;
    284 
    285   ClearRecordedAstId();
    286 }
    287 
    288 
    289 void Assembler::GetCode(CodeDesc* desc) {
    290   EmitForbiddenSlotInstruction();
    291   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
    292   // Set up code descriptor.
    293   desc->buffer = buffer_;
    294   desc->buffer_size = buffer_size_;
    295   desc->instr_size = pc_offset();
    296   desc->reloc_size =
    297       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
    298   desc->origin = this;
    299   desc->constant_pool_size = 0;
    300   desc->unwinding_info_size = 0;
    301   desc->unwinding_info = nullptr;
    302 }
    303 
    304 
    305 void Assembler::Align(int m) {
    306   DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
    307   EmitForbiddenSlotInstruction();
    308   while ((pc_offset() & (m - 1)) != 0) {
    309     nop();
    310   }
    311 }
    312 
    313 
    314 void Assembler::CodeTargetAlign() {
    315   // No advantage to aligning branch/call targets to more than
    316   // single instruction, that I am aware of.
    317   Align(4);
    318 }
    319 
    320 
    321 Register Assembler::GetRtReg(Instr instr) {
    322   Register rt;
    323   rt.reg_code = (instr & kRtFieldMask) >> kRtShift;
    324   return rt;
    325 }
    326 
    327 
    328 Register Assembler::GetRsReg(Instr instr) {
    329   Register rs;
    330   rs.reg_code = (instr & kRsFieldMask) >> kRsShift;
    331   return rs;
    332 }
    333 
    334 
    335 Register Assembler::GetRdReg(Instr instr) {
    336   Register rd;
    337   rd.reg_code = (instr & kRdFieldMask) >> kRdShift;
    338   return rd;
    339 }
    340 
    341 
    342 uint32_t Assembler::GetRt(Instr instr) {
    343   return (instr & kRtFieldMask) >> kRtShift;
    344 }
    345 
    346 
    347 uint32_t Assembler::GetRtField(Instr instr) {
    348   return instr & kRtFieldMask;
    349 }
    350 
    351 
    352 uint32_t Assembler::GetRs(Instr instr) {
    353   return (instr & kRsFieldMask) >> kRsShift;
    354 }
    355 
    356 
    357 uint32_t Assembler::GetRsField(Instr instr) {
    358   return instr & kRsFieldMask;
    359 }
    360 
    361 
    362 uint32_t Assembler::GetRd(Instr instr) {
    363   return  (instr & kRdFieldMask) >> kRdShift;
    364 }
    365 
    366 
    367 uint32_t Assembler::GetRdField(Instr instr) {
    368   return  instr & kRdFieldMask;
    369 }
    370 
    371 
    372 uint32_t Assembler::GetSa(Instr instr) {
    373   return (instr & kSaFieldMask) >> kSaShift;
    374 }
    375 
    376 
    377 uint32_t Assembler::GetSaField(Instr instr) {
    378   return instr & kSaFieldMask;
    379 }
    380 
    381 
    382 uint32_t Assembler::GetOpcodeField(Instr instr) {
    383   return instr & kOpcodeMask;
    384 }
    385 
    386 
    387 uint32_t Assembler::GetFunction(Instr instr) {
    388   return (instr & kFunctionFieldMask) >> kFunctionShift;
    389 }
    390 
    391 
    392 uint32_t Assembler::GetFunctionField(Instr instr) {
    393   return instr & kFunctionFieldMask;
    394 }
    395 
    396 
    397 uint32_t Assembler::GetImmediate16(Instr instr) {
    398   return instr & kImm16Mask;
    399 }
    400 
    401 
    402 uint32_t Assembler::GetLabelConst(Instr instr) {
    403   return instr & ~kImm16Mask;
    404 }
    405 
    406 
    407 bool Assembler::IsPop(Instr instr) {
    408   return (instr & ~kRtMask) == kPopRegPattern;
    409 }
    410 
    411 
    412 bool Assembler::IsPush(Instr instr) {
    413   return (instr & ~kRtMask) == kPushRegPattern;
    414 }
    415 
    416 
    417 bool Assembler::IsSwRegFpOffset(Instr instr) {
    418   return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
    419 }
    420 
    421 
    422 bool Assembler::IsLwRegFpOffset(Instr instr) {
    423   return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
    424 }
    425 
    426 
    427 bool Assembler::IsSwRegFpNegOffset(Instr instr) {
    428   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
    429           kSwRegFpNegOffsetPattern);
    430 }
    431 
    432 
    433 bool Assembler::IsLwRegFpNegOffset(Instr instr) {
    434   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
    435           kLwRegFpNegOffsetPattern);
    436 }
    437 
    438 
    439 // Labels refer to positions in the (to be) generated code.
    440 // There are bound, linked, and unused labels.
    441 //
    442 // Bound labels refer to known positions in the already
    443 // generated code. pos() is the position the label refers to.
    444 //
    445 // Linked labels refer to unknown positions in the code
    446 // to be generated; pos() is the position of the last
    447 // instruction using the label.
    448 
    449 // The link chain is terminated by a value in the instruction of -1,
    450 // which is an otherwise illegal value (branch -1 is inf loop).
    451 // The instruction 16-bit offset field addresses 32-bit words, but in
    452 // code is conv to an 18-bit value addressing bytes, hence the -4 value.
    453 
    454 const int kEndOfChain = -4;
    455 // Determines the end of the Jump chain (a subset of the label link chain).
    456 const int kEndOfJumpChain = 0;
    457 
    458 
    459 bool Assembler::IsBranch(Instr instr) {
    460   uint32_t opcode   = GetOpcodeField(instr);
    461   uint32_t rt_field = GetRtField(instr);
    462   uint32_t rs_field = GetRsField(instr);
    463   // Checks if the instruction is a branch.
    464   bool isBranch =
    465       opcode == BEQ || opcode == BNE || opcode == BLEZ || opcode == BGTZ ||
    466       opcode == BEQL || opcode == BNEL || opcode == BLEZL || opcode == BGTZL ||
    467       (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
    468                             rt_field == BLTZAL || rt_field == BGEZAL)) ||
    469       (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
    470       (opcode == COP1 && rs_field == BC1EQZ) ||
    471       (opcode == COP1 && rs_field == BC1NEZ);
    472   if (!isBranch && kArchVariant == kMips64r6) {
    473     // All the 3 variants of POP10 (BOVC, BEQC, BEQZALC) and
    474     // POP30 (BNVC, BNEC, BNEZALC) are branch ops.
    475     isBranch |= opcode == POP10 || opcode == POP30 || opcode == BC ||
    476                 opcode == BALC ||
    477                 (opcode == POP66 && rs_field != 0) ||  // BEQZC
    478                 (opcode == POP76 && rs_field != 0);    // BNEZC
    479   }
    480   return isBranch;
    481 }
    482 
    483 
    484 bool Assembler::IsBc(Instr instr) {
    485   uint32_t opcode = GetOpcodeField(instr);
    486   // Checks if the instruction is a BC or BALC.
    487   return opcode == BC || opcode == BALC;
    488 }
    489 
    490 
    491 bool Assembler::IsBzc(Instr instr) {
    492   uint32_t opcode = GetOpcodeField(instr);
    493   // Checks if the instruction is BEQZC or BNEZC.
    494   return (opcode == POP66 && GetRsField(instr) != 0) ||
    495          (opcode == POP76 && GetRsField(instr) != 0);
    496 }
    497 
    498 
    499 bool Assembler::IsEmittedConstant(Instr instr) {
    500   uint32_t label_constant = GetLabelConst(instr);
    501   return label_constant == 0;  // Emitted label const in reg-exp engine.
    502 }
    503 
    504 
    505 bool Assembler::IsBeq(Instr instr) {
    506   return GetOpcodeField(instr) == BEQ;
    507 }
    508 
    509 
    510 bool Assembler::IsBne(Instr instr) {
    511   return GetOpcodeField(instr) == BNE;
    512 }
    513 
    514 
    515 bool Assembler::IsBeqzc(Instr instr) {
    516   uint32_t opcode = GetOpcodeField(instr);
    517   return opcode == POP66 && GetRsField(instr) != 0;
    518 }
    519 
    520 
    521 bool Assembler::IsBnezc(Instr instr) {
    522   uint32_t opcode = GetOpcodeField(instr);
    523   return opcode == POP76 && GetRsField(instr) != 0;
    524 }
    525 
    526 
    527 bool Assembler::IsBeqc(Instr instr) {
    528   uint32_t opcode = GetOpcodeField(instr);
    529   uint32_t rs = GetRsField(instr);
    530   uint32_t rt = GetRtField(instr);
    531   return opcode == POP10 && rs != 0 && rs < rt;  // && rt != 0
    532 }
    533 
    534 
    535 bool Assembler::IsBnec(Instr instr) {
    536   uint32_t opcode = GetOpcodeField(instr);
    537   uint32_t rs = GetRsField(instr);
    538   uint32_t rt = GetRtField(instr);
    539   return opcode == POP30 && rs != 0 && rs < rt;  // && rt != 0
    540 }
    541 
    542 
    543 bool Assembler::IsJump(Instr instr) {
    544   uint32_t opcode   = GetOpcodeField(instr);
    545   uint32_t rt_field = GetRtField(instr);
    546   uint32_t rd_field = GetRdField(instr);
    547   uint32_t function_field = GetFunctionField(instr);
    548   // Checks if the instruction is a jump.
    549   return opcode == J || opcode == JAL ||
    550       (opcode == SPECIAL && rt_field == 0 &&
    551       ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
    552 }
    553 
    554 
    555 bool Assembler::IsJ(Instr instr) {
    556   uint32_t opcode = GetOpcodeField(instr);
    557   // Checks if the instruction is a jump.
    558   return opcode == J;
    559 }
    560 
    561 
    562 bool Assembler::IsJal(Instr instr) {
    563   return GetOpcodeField(instr) == JAL;
    564 }
    565 
    566 
    567 bool Assembler::IsJr(Instr instr) {
    568   return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
    569 }
    570 
    571 
    572 bool Assembler::IsJalr(Instr instr) {
    573   return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR;
    574 }
    575 
    576 
    577 bool Assembler::IsLui(Instr instr) {
    578   uint32_t opcode = GetOpcodeField(instr);
    579   // Checks if the instruction is a load upper immediate.
    580   return opcode == LUI;
    581 }
    582 
    583 
    584 bool Assembler::IsOri(Instr instr) {
    585   uint32_t opcode = GetOpcodeField(instr);
    586   // Checks if the instruction is a load upper immediate.
    587   return opcode == ORI;
    588 }
    589 
    590 
    591 bool Assembler::IsNop(Instr instr, unsigned int type) {
    592   // See Assembler::nop(type).
    593   DCHECK(type < 32);
    594   uint32_t opcode = GetOpcodeField(instr);
    595   uint32_t function = GetFunctionField(instr);
    596   uint32_t rt = GetRt(instr);
    597   uint32_t rd = GetRd(instr);
    598   uint32_t sa = GetSa(instr);
    599 
    600   // Traditional mips nop == sll(zero_reg, zero_reg, 0)
    601   // When marking non-zero type, use sll(zero_reg, at, type)
    602   // to avoid use of mips ssnop and ehb special encodings
    603   // of the sll instruction.
    604 
    605   Register nop_rt_reg = (type == 0) ? zero_reg : at;
    606   bool ret = (opcode == SPECIAL && function == SLL &&
    607               rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
    608               rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
    609               sa == type);
    610 
    611   return ret;
    612 }
    613 
    614 
    615 int32_t Assembler::GetBranchOffset(Instr instr) {
    616   DCHECK(IsBranch(instr));
    617   return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
    618 }
    619 
    620 
    621 bool Assembler::IsLw(Instr instr) {
    622   return (static_cast<uint32_t>(instr & kOpcodeMask) == LW);
    623 }
    624 
    625 
    626 int16_t Assembler::GetLwOffset(Instr instr) {
    627   DCHECK(IsLw(instr));
    628   return ((instr & kImm16Mask));
    629 }
    630 
    631 
    632 Instr Assembler::SetLwOffset(Instr instr, int16_t offset) {
    633   DCHECK(IsLw(instr));
    634 
    635   // We actually create a new lw instruction based on the original one.
    636   Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
    637       | (offset & kImm16Mask);
    638 
    639   return temp_instr;
    640 }
    641 
    642 
    643 bool Assembler::IsSw(Instr instr) {
    644   return (static_cast<uint32_t>(instr & kOpcodeMask) == SW);
    645 }
    646 
    647 
    648 Instr Assembler::SetSwOffset(Instr instr, int16_t offset) {
    649   DCHECK(IsSw(instr));
    650   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
    651 }
    652 
    653 
    654 bool Assembler::IsAddImmediate(Instr instr) {
    655   return ((instr & kOpcodeMask) == ADDIU || (instr & kOpcodeMask) == DADDIU);
    656 }
    657 
    658 
    659 Instr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
    660   DCHECK(IsAddImmediate(instr));
    661   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
    662 }
    663 
    664 
    665 bool Assembler::IsAndImmediate(Instr instr) {
    666   return GetOpcodeField(instr) == ANDI;
    667 }
    668 
    669 
    670 static Assembler::OffsetSize OffsetSizeInBits(Instr instr) {
    671   if (kArchVariant == kMips64r6) {
    672     if (Assembler::IsBc(instr)) {
    673       return Assembler::OffsetSize::kOffset26;
    674     } else if (Assembler::IsBzc(instr)) {
    675       return Assembler::OffsetSize::kOffset21;
    676     }
    677   }
    678   return Assembler::OffsetSize::kOffset16;
    679 }
    680 
    681 
    682 static inline int32_t AddBranchOffset(int pos, Instr instr) {
    683   int bits = OffsetSizeInBits(instr);
    684   const int32_t mask = (1 << bits) - 1;
    685   bits = 32 - bits;
    686 
    687   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
    688   // the compiler uses arithmetic shifts for signed integers.
    689   int32_t imm = ((instr & mask) << bits) >> (bits - 2);
    690 
    691   if (imm == kEndOfChain) {
    692     // EndOfChain sentinel is returned directly, not relative to pc or pos.
    693     return kEndOfChain;
    694   } else {
    695     return pos + Assembler::kBranchPCOffset + imm;
    696   }
    697 }
    698 
    699 
    700 int Assembler::target_at(int pos, bool is_internal) {
    701   if (is_internal) {
    702     int64_t* p = reinterpret_cast<int64_t*>(buffer_ + pos);
    703     int64_t address = *p;
    704     if (address == kEndOfJumpChain) {
    705       return kEndOfChain;
    706     } else {
    707       int64_t instr_address = reinterpret_cast<int64_t>(p);
    708       DCHECK(instr_address - address < INT_MAX);
    709       int delta = static_cast<int>(instr_address - address);
    710       DCHECK(pos > delta);
    711       return pos - delta;
    712     }
    713   }
    714   Instr instr = instr_at(pos);
    715   if ((instr & ~kImm16Mask) == 0) {
    716     // Emitted label constant, not part of a branch.
    717     if (instr == 0) {
    718        return kEndOfChain;
    719      } else {
    720        int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
    721        return (imm18 + pos);
    722      }
    723   }
    724   // Check we have a branch or jump instruction.
    725   DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
    726   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
    727   // the compiler uses arithmetic shifts for signed integers.
    728   if (IsBranch(instr)) {
    729     return AddBranchOffset(pos, instr);
    730   } else if (IsLui(instr)) {
    731     Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
    732     Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
    733     Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
    734     DCHECK(IsOri(instr_ori));
    735     DCHECK(IsOri(instr_ori2));
    736 
    737     // TODO(plind) create named constants for shift values.
    738     int64_t imm = static_cast<int64_t>(instr_lui & kImm16Mask) << 48;
    739     imm |= static_cast<int64_t>(instr_ori & kImm16Mask) << 32;
    740     imm |= static_cast<int64_t>(instr_ori2 & kImm16Mask) << 16;
    741     // Sign extend address;
    742     imm >>= 16;
    743 
    744     if (imm == kEndOfJumpChain) {
    745       // EndOfChain sentinel is returned directly, not relative to pc or pos.
    746       return kEndOfChain;
    747     } else {
    748       uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
    749       DCHECK(instr_address - imm < INT_MAX);
    750       int delta = static_cast<int>(instr_address - imm);
    751       DCHECK(pos > delta);
    752       return pos - delta;
    753     }
    754   } else {
    755     DCHECK(IsJ(instr) || IsJal(instr));
    756     int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
    757     if (imm28 == kEndOfJumpChain) {
    758       // EndOfChain sentinel is returned directly, not relative to pc or pos.
    759       return kEndOfChain;
    760     } else {
    761       // Sign extend 28-bit offset.
    762       int32_t delta = static_cast<int32_t>((imm28 << 4) >> 4);
    763       return pos + delta;
    764     }
    765   }
    766 }
    767 
    768 
    769 static inline Instr SetBranchOffset(int32_t pos, int32_t target_pos,
    770                                     Instr instr) {
    771   int32_t bits = OffsetSizeInBits(instr);
    772   int32_t imm = target_pos - (pos + Assembler::kBranchPCOffset);
    773   DCHECK((imm & 3) == 0);
    774   imm >>= 2;
    775 
    776   const int32_t mask = (1 << bits) - 1;
    777   instr &= ~mask;
    778   DCHECK(is_intn(imm, bits));
    779 
    780   return instr | (imm & mask);
    781 }
    782 
    783 
    784 void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
    785   if (is_internal) {
    786     uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
    787     *reinterpret_cast<uint64_t*>(buffer_ + pos) = imm;
    788     return;
    789   }
    790   Instr instr = instr_at(pos);
    791   if ((instr & ~kImm16Mask) == 0) {
    792     DCHECK(target_pos == kEndOfChain || target_pos >= 0);
    793     // Emitted label constant, not part of a branch.
    794     // Make label relative to Code* of generated Code object.
    795     instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
    796     return;
    797   }
    798 
    799   if (IsBranch(instr)) {
    800     instr = SetBranchOffset(pos, target_pos, instr);
    801     instr_at_put(pos, instr);
    802   } else if (IsLui(instr)) {
    803     Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
    804     Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
    805     Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
    806     DCHECK(IsOri(instr_ori));
    807     DCHECK(IsOri(instr_ori2));
    808 
    809     uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
    810     DCHECK((imm & 3) == 0);
    811 
    812     instr_lui &= ~kImm16Mask;
    813     instr_ori &= ~kImm16Mask;
    814     instr_ori2 &= ~kImm16Mask;
    815 
    816     instr_at_put(pos + 0 * Assembler::kInstrSize,
    817                  instr_lui | ((imm >> 32) & kImm16Mask));
    818     instr_at_put(pos + 1 * Assembler::kInstrSize,
    819                  instr_ori | ((imm >> 16) & kImm16Mask));
    820     instr_at_put(pos + 3 * Assembler::kInstrSize,
    821                  instr_ori2 | (imm & kImm16Mask));
    822   } else if (IsJ(instr) || IsJal(instr)) {
    823     int32_t imm28 = target_pos - pos;
    824     DCHECK((imm28 & 3) == 0);
    825 
    826     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
    827     DCHECK(is_uint26(imm26));
    828     // Place 26-bit signed offset with markings.
    829     // When code is committed it will be resolved to j/jal.
    830     int32_t mark = IsJ(instr) ? kJRawMark : kJalRawMark;
    831     instr_at_put(pos, mark | (imm26 & kImm26Mask));
    832   } else {
    833     int32_t imm28 = target_pos - pos;
    834     DCHECK((imm28 & 3) == 0);
    835 
    836     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
    837     DCHECK(is_uint26(imm26));
    838     // Place raw 26-bit signed offset.
    839     // When code is committed it will be resolved to j/jal.
    840     instr &= ~kImm26Mask;
    841     instr_at_put(pos, instr | (imm26 & kImm26Mask));
    842   }
    843 }
    844 
    845 
    846 void Assembler::print(Label* L) {
    847   if (L->is_unused()) {
    848     PrintF("unused label\n");
    849   } else if (L->is_bound()) {
    850     PrintF("bound label to %d\n", L->pos());
    851   } else if (L->is_linked()) {
    852     Label l = *L;
    853     PrintF("unbound label");
    854     while (l.is_linked()) {
    855       PrintF("@ %d ", l.pos());
    856       Instr instr = instr_at(l.pos());
    857       if ((instr & ~kImm16Mask) == 0) {
    858         PrintF("value\n");
    859       } else {
    860         PrintF("%d\n", instr);
    861       }
    862       next(&l, internal_reference_positions_.find(l.pos()) !=
    863                    internal_reference_positions_.end());
    864     }
    865   } else {
    866     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
    867   }
    868 }
    869 
    870 
    871 void Assembler::bind_to(Label* L, int pos) {
    872   DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
    873   int trampoline_pos = kInvalidSlotPos;
    874   bool is_internal = false;
    875   if (L->is_linked() && !trampoline_emitted_) {
    876     unbound_labels_count_--;
    877     next_buffer_check_ += kTrampolineSlotsSize;
    878   }
    879 
    880   while (L->is_linked()) {
    881     int fixup_pos = L->pos();
    882     int dist = pos - fixup_pos;
    883     is_internal = internal_reference_positions_.find(fixup_pos) !=
    884                   internal_reference_positions_.end();
    885     next(L, is_internal);  // Call next before overwriting link with target at
    886                            // fixup_pos.
    887     Instr instr = instr_at(fixup_pos);
    888     if (is_internal) {
    889       target_at_put(fixup_pos, pos, is_internal);
    890     } else {
    891       if (IsBranch(instr)) {
    892         int branch_offset = BranchOffset(instr);
    893         if (dist > branch_offset) {
    894           if (trampoline_pos == kInvalidSlotPos) {
    895             trampoline_pos = get_trampoline_entry(fixup_pos);
    896             CHECK(trampoline_pos != kInvalidSlotPos);
    897           }
    898           CHECK((trampoline_pos - fixup_pos) <= branch_offset);
    899           target_at_put(fixup_pos, trampoline_pos, false);
    900           fixup_pos = trampoline_pos;
    901           dist = pos - fixup_pos;
    902         }
    903         target_at_put(fixup_pos, pos, false);
    904       } else {
    905         DCHECK(IsJ(instr) || IsJal(instr) || IsLui(instr) ||
    906                IsEmittedConstant(instr));
    907         target_at_put(fixup_pos, pos, false);
    908       }
    909     }
    910   }
    911   L->bind_to(pos);
    912 
    913   // Keep track of the last bound label so we don't eliminate any instructions
    914   // before a bound label.
    915   if (pos > last_bound_pos_)
    916     last_bound_pos_ = pos;
    917 }
    918 
    919 
    920 void Assembler::bind(Label* L) {
    921   DCHECK(!L->is_bound());  // Label can only be bound once.
    922   bind_to(L, pc_offset());
    923 }
    924 
    925 
    926 void Assembler::next(Label* L, bool is_internal) {
    927   DCHECK(L->is_linked());
    928   int link = target_at(L->pos(), is_internal);
    929   if (link == kEndOfChain) {
    930     L->Unuse();
    931   } else {
    932     DCHECK(link >= 0);
    933     L->link_to(link);
    934   }
    935 }
    936 
    937 
    938 bool Assembler::is_near(Label* L) {
    939   DCHECK(L->is_bound());
    940   return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize;
    941 }
    942 
    943 
    944 bool Assembler::is_near(Label* L, OffsetSize bits) {
    945   if (L == nullptr || !L->is_bound()) return true;
    946   return ((pc_offset() - L->pos()) <
    947           (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize);
    948 }
    949 
    950 
    951 bool Assembler::is_near_branch(Label* L) {
    952   DCHECK(L->is_bound());
    953   return kArchVariant == kMips64r6 ? is_near_r6(L) : is_near_pre_r6(L);
    954 }
    955 
    956 
    957 int Assembler::BranchOffset(Instr instr) {
    958   // At pre-R6 and for other R6 branches the offset is 16 bits.
    959   int bits = OffsetSize::kOffset16;
    960 
    961   if (kArchVariant == kMips64r6) {
    962     uint32_t opcode = GetOpcodeField(instr);
    963     switch (opcode) {
    964       // Checks BC or BALC.
    965       case BC:
    966       case BALC:
    967         bits = OffsetSize::kOffset26;
    968         break;
    969 
    970       // Checks BEQZC or BNEZC.
    971       case POP66:
    972       case POP76:
    973         if (GetRsField(instr) != 0) bits = OffsetSize::kOffset21;
    974         break;
    975       default:
    976         break;
    977     }
    978   }
    979 
    980   return (1 << (bits + 2 - 1)) - 1;
    981 }
    982 
    983 
    984 // We have to use a temporary register for things that can be relocated even
    985 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
    986 // space.  There is no guarantee that the relocated location can be similarly
    987 // encoded.
    988 bool Assembler::MustUseReg(RelocInfo::Mode rmode) {
    989   return !RelocInfo::IsNone(rmode);
    990 }
    991 
    992 void Assembler::GenInstrRegister(Opcode opcode,
    993                                  Register rs,
    994                                  Register rt,
    995                                  Register rd,
    996                                  uint16_t sa,
    997                                  SecondaryField func) {
    998   DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
    999   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1000       | (rd.code() << kRdShift) | (sa << kSaShift) | func;
   1001   emit(instr);
   1002 }
   1003 
   1004 
   1005 void Assembler::GenInstrRegister(Opcode opcode,
   1006                                  Register rs,
   1007                                  Register rt,
   1008                                  uint16_t msb,
   1009                                  uint16_t lsb,
   1010                                  SecondaryField func) {
   1011   DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
   1012   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1013       | (msb << kRdShift) | (lsb << kSaShift) | func;
   1014   emit(instr);
   1015 }
   1016 
   1017 
   1018 void Assembler::GenInstrRegister(Opcode opcode,
   1019                                  SecondaryField fmt,
   1020                                  FPURegister ft,
   1021                                  FPURegister fs,
   1022                                  FPURegister fd,
   1023                                  SecondaryField func) {
   1024   DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
   1025   Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
   1026       | (fd.code() << kFdShift) | func;
   1027   emit(instr);
   1028 }
   1029 
   1030 
   1031 void Assembler::GenInstrRegister(Opcode opcode,
   1032                                  FPURegister fr,
   1033                                  FPURegister ft,
   1034                                  FPURegister fs,
   1035                                  FPURegister fd,
   1036                                  SecondaryField func) {
   1037   DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
   1038   Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
   1039       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
   1040   emit(instr);
   1041 }
   1042 
   1043 
   1044 void Assembler::GenInstrRegister(Opcode opcode,
   1045                                  SecondaryField fmt,
   1046                                  Register rt,
   1047                                  FPURegister fs,
   1048                                  FPURegister fd,
   1049                                  SecondaryField func) {
   1050   DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
   1051   Instr instr = opcode | fmt | (rt.code() << kRtShift)
   1052       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
   1053   emit(instr);
   1054 }
   1055 
   1056 
   1057 void Assembler::GenInstrRegister(Opcode opcode,
   1058                                  SecondaryField fmt,
   1059                                  Register rt,
   1060                                  FPUControlRegister fs,
   1061                                  SecondaryField func) {
   1062   DCHECK(fs.is_valid() && rt.is_valid());
   1063   Instr instr =
   1064       opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
   1065   emit(instr);
   1066 }
   1067 
   1068 
   1069 // Instructions with immediate value.
   1070 // Registers are in the order of the instruction encoding, from left to right.
   1071 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, Register rt,
   1072                                   int32_t j,
   1073                                   CompactBranchType is_compact_branch) {
   1074   DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
   1075   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1076       | (j & kImm16Mask);
   1077   emit(instr, is_compact_branch);
   1078 }
   1079 
   1080 
   1081 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, SecondaryField SF,
   1082                                   int32_t j,
   1083                                   CompactBranchType is_compact_branch) {
   1084   DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
   1085   Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
   1086   emit(instr, is_compact_branch);
   1087 }
   1088 
   1089 
   1090 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, FPURegister ft,
   1091                                   int32_t j,
   1092                                   CompactBranchType is_compact_branch) {
   1093   DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
   1094   Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
   1095       | (j & kImm16Mask);
   1096   emit(instr, is_compact_branch);
   1097 }
   1098 
   1099 
   1100 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t offset21,
   1101                                   CompactBranchType is_compact_branch) {
   1102   DCHECK(rs.is_valid() && (is_int21(offset21)));
   1103   Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
   1104   emit(instr, is_compact_branch);
   1105 }
   1106 
   1107 
   1108 void Assembler::GenInstrImmediate(Opcode opcode, Register rs,
   1109                                   uint32_t offset21) {
   1110   DCHECK(rs.is_valid() && (is_uint21(offset21)));
   1111   Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
   1112   emit(instr);
   1113 }
   1114 
   1115 
   1116 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26,
   1117                                   CompactBranchType is_compact_branch) {
   1118   DCHECK(is_int26(offset26));
   1119   Instr instr = opcode | (offset26 & kImm26Mask);
   1120   emit(instr, is_compact_branch);
   1121 }
   1122 
   1123 
   1124 void Assembler::GenInstrJump(Opcode opcode,
   1125                              uint32_t address) {
   1126   BlockTrampolinePoolScope block_trampoline_pool(this);
   1127   DCHECK(is_uint26(address));
   1128   Instr instr = opcode | address;
   1129   emit(instr);
   1130   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1131 }
   1132 
   1133 
   1134 // Returns the next free trampoline entry.
   1135 int32_t Assembler::get_trampoline_entry(int32_t pos) {
   1136   int32_t trampoline_entry = kInvalidSlotPos;
   1137   if (!internal_trampoline_exception_) {
   1138     if (trampoline_.start() > pos) {
   1139      trampoline_entry = trampoline_.take_slot();
   1140     }
   1141 
   1142     if (kInvalidSlotPos == trampoline_entry) {
   1143       internal_trampoline_exception_ = true;
   1144     }
   1145   }
   1146   return trampoline_entry;
   1147 }
   1148 
   1149 
   1150 uint64_t Assembler::jump_address(Label* L) {
   1151   int64_t target_pos;
   1152   if (L->is_bound()) {
   1153     target_pos = L->pos();
   1154   } else {
   1155     if (L->is_linked()) {
   1156       target_pos = L->pos();  // L's link.
   1157       L->link_to(pc_offset());
   1158     } else {
   1159       L->link_to(pc_offset());
   1160       return kEndOfJumpChain;
   1161     }
   1162   }
   1163   uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
   1164   DCHECK((imm & 3) == 0);
   1165 
   1166   return imm;
   1167 }
   1168 
   1169 
   1170 uint64_t Assembler::jump_offset(Label* L) {
   1171   int64_t target_pos;
   1172   int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
   1173 
   1174   if (L->is_bound()) {
   1175     target_pos = L->pos();
   1176   } else {
   1177     if (L->is_linked()) {
   1178       target_pos = L->pos();  // L's link.
   1179       L->link_to(pc_offset() + pad);
   1180     } else {
   1181       L->link_to(pc_offset() + pad);
   1182       return kEndOfJumpChain;
   1183     }
   1184   }
   1185   int64_t imm = target_pos - (pc_offset() + pad);
   1186   DCHECK((imm & 3) == 0);
   1187 
   1188   return static_cast<uint64_t>(imm);
   1189 }
   1190 
   1191 
   1192 int32_t Assembler::branch_offset_helper(Label* L, OffsetSize bits) {
   1193   int32_t target_pos;
   1194   int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
   1195 
   1196   if (L->is_bound()) {
   1197     target_pos = L->pos();
   1198   } else {
   1199     if (L->is_linked()) {
   1200       target_pos = L->pos();
   1201       L->link_to(pc_offset() + pad);
   1202     } else {
   1203       L->link_to(pc_offset() + pad);
   1204       if (!trampoline_emitted_) {
   1205         unbound_labels_count_++;
   1206         next_buffer_check_ -= kTrampolineSlotsSize;
   1207       }
   1208       return kEndOfChain;
   1209     }
   1210   }
   1211 
   1212   int32_t offset = target_pos - (pc_offset() + kBranchPCOffset + pad);
   1213   DCHECK(is_intn(offset, bits + 2));
   1214   DCHECK((offset & 3) == 0);
   1215 
   1216   return offset;
   1217 }
   1218 
   1219 
   1220 void Assembler::label_at_put(Label* L, int at_offset) {
   1221   int target_pos;
   1222   if (L->is_bound()) {
   1223     target_pos = L->pos();
   1224     instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
   1225   } else {
   1226     if (L->is_linked()) {
   1227       target_pos = L->pos();  // L's link.
   1228       int32_t imm18 = target_pos - at_offset;
   1229       DCHECK((imm18 & 3) == 0);
   1230       int32_t imm16 = imm18 >> 2;
   1231       DCHECK(is_int16(imm16));
   1232       instr_at_put(at_offset, (imm16 & kImm16Mask));
   1233     } else {
   1234       target_pos = kEndOfChain;
   1235       instr_at_put(at_offset, 0);
   1236       if (!trampoline_emitted_) {
   1237         unbound_labels_count_++;
   1238         next_buffer_check_ -= kTrampolineSlotsSize;
   1239       }
   1240     }
   1241     L->link_to(at_offset);
   1242   }
   1243 }
   1244 
   1245 
   1246 //------- Branch and jump instructions --------
   1247 
   1248 void Assembler::b(int16_t offset) {
   1249   beq(zero_reg, zero_reg, offset);
   1250 }
   1251 
   1252 
   1253 void Assembler::bal(int16_t offset) {
   1254   bgezal(zero_reg, offset);
   1255 }
   1256 
   1257 
   1258 void Assembler::bc(int32_t offset) {
   1259   DCHECK(kArchVariant == kMips64r6);
   1260   GenInstrImmediate(BC, offset, CompactBranchType::COMPACT_BRANCH);
   1261 }
   1262 
   1263 
   1264 void Assembler::balc(int32_t offset) {
   1265   DCHECK(kArchVariant == kMips64r6);
   1266   GenInstrImmediate(BALC, offset, CompactBranchType::COMPACT_BRANCH);
   1267 }
   1268 
   1269 
   1270 void Assembler::beq(Register rs, Register rt, int16_t offset) {
   1271   BlockTrampolinePoolScope block_trampoline_pool(this);
   1272   GenInstrImmediate(BEQ, rs, rt, offset);
   1273   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1274 }
   1275 
   1276 
   1277 void Assembler::bgez(Register rs, int16_t offset) {
   1278   BlockTrampolinePoolScope block_trampoline_pool(this);
   1279   GenInstrImmediate(REGIMM, rs, BGEZ, offset);
   1280   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1281 }
   1282 
   1283 
   1284 void Assembler::bgezc(Register rt, int16_t offset) {
   1285   DCHECK(kArchVariant == kMips64r6);
   1286   DCHECK(!(rt.is(zero_reg)));
   1287   GenInstrImmediate(BLEZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1288 }
   1289 
   1290 
   1291 void Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
   1292   DCHECK(kArchVariant == kMips64r6);
   1293   DCHECK(!(rs.is(zero_reg)));
   1294   DCHECK(!(rt.is(zero_reg)));
   1295   DCHECK(rs.code() != rt.code());
   1296   GenInstrImmediate(BLEZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1297 }
   1298 
   1299 
   1300 void Assembler::bgec(Register rs, Register rt, int16_t offset) {
   1301   DCHECK(kArchVariant == kMips64r6);
   1302   DCHECK(!(rs.is(zero_reg)));
   1303   DCHECK(!(rt.is(zero_reg)));
   1304   DCHECK(rs.code() != rt.code());
   1305   GenInstrImmediate(BLEZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1306 }
   1307 
   1308 
   1309 void Assembler::bgezal(Register rs, int16_t offset) {
   1310   DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
   1311   BlockTrampolinePoolScope block_trampoline_pool(this);
   1312   GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
   1313   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1314 }
   1315 
   1316 
   1317 void Assembler::bgtz(Register rs, int16_t offset) {
   1318   BlockTrampolinePoolScope block_trampoline_pool(this);
   1319   GenInstrImmediate(BGTZ, rs, zero_reg, offset);
   1320   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1321 }
   1322 
   1323 
   1324 void Assembler::bgtzc(Register rt, int16_t offset) {
   1325   DCHECK(kArchVariant == kMips64r6);
   1326   DCHECK(!(rt.is(zero_reg)));
   1327   GenInstrImmediate(BGTZL, zero_reg, rt, offset,
   1328                     CompactBranchType::COMPACT_BRANCH);
   1329 }
   1330 
   1331 
   1332 void Assembler::blez(Register rs, int16_t offset) {
   1333   BlockTrampolinePoolScope block_trampoline_pool(this);
   1334   GenInstrImmediate(BLEZ, rs, zero_reg, offset);
   1335   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1336 }
   1337 
   1338 
   1339 void Assembler::blezc(Register rt, int16_t offset) {
   1340   DCHECK(kArchVariant == kMips64r6);
   1341   DCHECK(!(rt.is(zero_reg)));
   1342   GenInstrImmediate(BLEZL, zero_reg, rt, offset,
   1343                     CompactBranchType::COMPACT_BRANCH);
   1344 }
   1345 
   1346 
   1347 void Assembler::bltzc(Register rt, int16_t offset) {
   1348   DCHECK(kArchVariant == kMips64r6);
   1349   DCHECK(!rt.is(zero_reg));
   1350   GenInstrImmediate(BGTZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1351 }
   1352 
   1353 
   1354 void Assembler::bltuc(Register rs, Register rt, int16_t offset) {
   1355   DCHECK(kArchVariant == kMips64r6);
   1356   DCHECK(!(rs.is(zero_reg)));
   1357   DCHECK(!(rt.is(zero_reg)));
   1358   DCHECK(rs.code() != rt.code());
   1359   GenInstrImmediate(BGTZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1360 }
   1361 
   1362 
   1363 void Assembler::bltc(Register rs, Register rt, int16_t offset) {
   1364   DCHECK(kArchVariant == kMips64r6);
   1365   DCHECK(!rs.is(zero_reg));
   1366   DCHECK(!rt.is(zero_reg));
   1367   DCHECK(rs.code() != rt.code());
   1368   GenInstrImmediate(BGTZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1369 }
   1370 
   1371 
   1372 void Assembler::bltz(Register rs, int16_t offset) {
   1373   BlockTrampolinePoolScope block_trampoline_pool(this);
   1374   GenInstrImmediate(REGIMM, rs, BLTZ, offset);
   1375   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1376 }
   1377 
   1378 
   1379 void Assembler::bltzal(Register rs, int16_t offset) {
   1380   DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
   1381   BlockTrampolinePoolScope block_trampoline_pool(this);
   1382   GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
   1383   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1384 }
   1385 
   1386 
   1387 void Assembler::bne(Register rs, Register rt, int16_t offset) {
   1388   BlockTrampolinePoolScope block_trampoline_pool(this);
   1389   GenInstrImmediate(BNE, rs, rt, offset);
   1390   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1391 }
   1392 
   1393 
   1394 void Assembler::bovc(Register rs, Register rt, int16_t offset) {
   1395   DCHECK(kArchVariant == kMips64r6);
   1396   if (rs.code() >= rt.code()) {
   1397     GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1398   } else {
   1399     GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1400   }
   1401 }
   1402 
   1403 
   1404 void Assembler::bnvc(Register rs, Register rt, int16_t offset) {
   1405   DCHECK(kArchVariant == kMips64r6);
   1406   if (rs.code() >= rt.code()) {
   1407     GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1408   } else {
   1409     GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1410   }
   1411 }
   1412 
   1413 
   1414 void Assembler::blezalc(Register rt, int16_t offset) {
   1415   DCHECK(kArchVariant == kMips64r6);
   1416   DCHECK(!(rt.is(zero_reg)));
   1417   GenInstrImmediate(BLEZ, zero_reg, rt, offset,
   1418                     CompactBranchType::COMPACT_BRANCH);
   1419 }
   1420 
   1421 
   1422 void Assembler::bgezalc(Register rt, int16_t offset) {
   1423   DCHECK(kArchVariant == kMips64r6);
   1424   DCHECK(!(rt.is(zero_reg)));
   1425   GenInstrImmediate(BLEZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1426 }
   1427 
   1428 
   1429 void Assembler::bgezall(Register rs, int16_t offset) {
   1430   DCHECK(kArchVariant != kMips64r6);
   1431   DCHECK(!(rs.is(zero_reg)));
   1432   BlockTrampolinePoolScope block_trampoline_pool(this);
   1433   GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
   1434   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1435 }
   1436 
   1437 
   1438 void Assembler::bltzalc(Register rt, int16_t offset) {
   1439   DCHECK(kArchVariant == kMips64r6);
   1440   DCHECK(!(rt.is(zero_reg)));
   1441   GenInstrImmediate(BGTZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1442 }
   1443 
   1444 
   1445 void Assembler::bgtzalc(Register rt, int16_t offset) {
   1446   DCHECK(kArchVariant == kMips64r6);
   1447   DCHECK(!(rt.is(zero_reg)));
   1448   GenInstrImmediate(BGTZ, zero_reg, rt, offset,
   1449                     CompactBranchType::COMPACT_BRANCH);
   1450 }
   1451 
   1452 
   1453 void Assembler::beqzalc(Register rt, int16_t offset) {
   1454   DCHECK(kArchVariant == kMips64r6);
   1455   DCHECK(!(rt.is(zero_reg)));
   1456   GenInstrImmediate(ADDI, zero_reg, rt, offset,
   1457                     CompactBranchType::COMPACT_BRANCH);
   1458 }
   1459 
   1460 
   1461 void Assembler::bnezalc(Register rt, int16_t offset) {
   1462   DCHECK(kArchVariant == kMips64r6);
   1463   DCHECK(!(rt.is(zero_reg)));
   1464   GenInstrImmediate(DADDI, zero_reg, rt, offset,
   1465                     CompactBranchType::COMPACT_BRANCH);
   1466 }
   1467 
   1468 
   1469 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
   1470   DCHECK(kArchVariant == kMips64r6);
   1471   DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
   1472   if (rs.code() < rt.code()) {
   1473     GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1474   } else {
   1475     GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1476   }
   1477 }
   1478 
   1479 
   1480 void Assembler::beqzc(Register rs, int32_t offset) {
   1481   DCHECK(kArchVariant == kMips64r6);
   1482   DCHECK(!(rs.is(zero_reg)));
   1483   GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1484 }
   1485 
   1486 
   1487 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
   1488   DCHECK(kArchVariant == kMips64r6);
   1489   DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
   1490   if (rs.code() < rt.code()) {
   1491     GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1492   } else {
   1493     GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1494   }
   1495 }
   1496 
   1497 
   1498 void Assembler::bnezc(Register rs, int32_t offset) {
   1499   DCHECK(kArchVariant == kMips64r6);
   1500   DCHECK(!(rs.is(zero_reg)));
   1501   GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1502 }
   1503 
   1504 
   1505 void Assembler::j(int64_t target) {
   1506   BlockTrampolinePoolScope block_trampoline_pool(this);
   1507   GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask);
   1508   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1509 }
   1510 
   1511 
   1512 void Assembler::j(Label* target) {
   1513   uint64_t imm = jump_offset(target);
   1514   if (target->is_bound()) {
   1515     BlockTrampolinePoolScope block_trampoline_pool(this);
   1516     GenInstrJump(static_cast<Opcode>(kJRawMark),
   1517                  static_cast<uint32_t>(imm >> 2) & kImm26Mask);
   1518     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1519   } else {
   1520     j(imm);
   1521   }
   1522 }
   1523 
   1524 
   1525 void Assembler::jal(Label* target) {
   1526   uint64_t imm = jump_offset(target);
   1527   if (target->is_bound()) {
   1528     BlockTrampolinePoolScope block_trampoline_pool(this);
   1529     GenInstrJump(static_cast<Opcode>(kJalRawMark),
   1530                  static_cast<uint32_t>(imm >> 2) & kImm26Mask);
   1531     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1532   } else {
   1533     jal(imm);
   1534   }
   1535 }
   1536 
   1537 
   1538 void Assembler::jr(Register rs) {
   1539   if (kArchVariant != kMips64r6) {
   1540     BlockTrampolinePoolScope block_trampoline_pool(this);
   1541     GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
   1542     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1543   } else {
   1544     jalr(rs, zero_reg);
   1545   }
   1546 }
   1547 
   1548 
   1549 void Assembler::jal(int64_t target) {
   1550   BlockTrampolinePoolScope block_trampoline_pool(this);
   1551   GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask);
   1552   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1553 }
   1554 
   1555 
   1556 void Assembler::jalr(Register rs, Register rd) {
   1557   DCHECK(rs.code() != rd.code());
   1558   BlockTrampolinePoolScope block_trampoline_pool(this);
   1559   GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
   1560   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1561 }
   1562 
   1563 
   1564 void Assembler::jic(Register rt, int16_t offset) {
   1565   DCHECK(kArchVariant == kMips64r6);
   1566   GenInstrImmediate(POP66, zero_reg, rt, offset);
   1567 }
   1568 
   1569 
   1570 void Assembler::jialc(Register rt, int16_t offset) {
   1571   DCHECK(kArchVariant == kMips64r6);
   1572   GenInstrImmediate(POP76, zero_reg, rt, offset);
   1573 }
   1574 
   1575 
   1576 // -------Data-processing-instructions---------
   1577 
   1578 // Arithmetic.
   1579 
   1580 void Assembler::addu(Register rd, Register rs, Register rt) {
   1581   GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
   1582 }
   1583 
   1584 
   1585 void Assembler::addiu(Register rd, Register rs, int32_t j) {
   1586   GenInstrImmediate(ADDIU, rs, rd, j);
   1587 }
   1588 
   1589 
   1590 void Assembler::subu(Register rd, Register rs, Register rt) {
   1591   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
   1592 }
   1593 
   1594 
   1595 void Assembler::mul(Register rd, Register rs, Register rt) {
   1596   if (kArchVariant == kMips64r6) {
   1597       GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
   1598   } else {
   1599       GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
   1600   }
   1601 }
   1602 
   1603 
   1604 void Assembler::muh(Register rd, Register rs, Register rt) {
   1605   DCHECK(kArchVariant == kMips64r6);
   1606   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
   1607 }
   1608 
   1609 
   1610 void Assembler::mulu(Register rd, Register rs, Register rt) {
   1611   DCHECK(kArchVariant == kMips64r6);
   1612   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
   1613 }
   1614 
   1615 
   1616 void Assembler::muhu(Register rd, Register rs, Register rt) {
   1617   DCHECK(kArchVariant == kMips64r6);
   1618   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
   1619 }
   1620 
   1621 
   1622 void Assembler::dmul(Register rd, Register rs, Register rt) {
   1623   DCHECK(kArchVariant == kMips64r6);
   1624   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH);
   1625 }
   1626 
   1627 
   1628 void Assembler::dmuh(Register rd, Register rs, Register rt) {
   1629   DCHECK(kArchVariant == kMips64r6);
   1630   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH);
   1631 }
   1632 
   1633 
   1634 void Assembler::dmulu(Register rd, Register rs, Register rt) {
   1635   DCHECK(kArchVariant == kMips64r6);
   1636   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH_U);
   1637 }
   1638 
   1639 
   1640 void Assembler::dmuhu(Register rd, Register rs, Register rt) {
   1641   DCHECK(kArchVariant == kMips64r6);
   1642   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH_U);
   1643 }
   1644 
   1645 
   1646 void Assembler::mult(Register rs, Register rt) {
   1647   DCHECK(kArchVariant != kMips64r6);
   1648   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
   1649 }
   1650 
   1651 
   1652 void Assembler::multu(Register rs, Register rt) {
   1653   DCHECK(kArchVariant != kMips64r6);
   1654   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
   1655 }
   1656 
   1657 
   1658 void Assembler::daddiu(Register rd, Register rs, int32_t j) {
   1659   GenInstrImmediate(DADDIU, rs, rd, j);
   1660 }
   1661 
   1662 
   1663 void Assembler::div(Register rs, Register rt) {
   1664   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
   1665 }
   1666 
   1667 
   1668 void Assembler::div(Register rd, Register rs, Register rt) {
   1669   DCHECK(kArchVariant == kMips64r6);
   1670   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
   1671 }
   1672 
   1673 
   1674 void Assembler::mod(Register rd, Register rs, Register rt) {
   1675   DCHECK(kArchVariant == kMips64r6);
   1676   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
   1677 }
   1678 
   1679 
   1680 void Assembler::divu(Register rs, Register rt) {
   1681   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
   1682 }
   1683 
   1684 
   1685 void Assembler::divu(Register rd, Register rs, Register rt) {
   1686   DCHECK(kArchVariant == kMips64r6);
   1687   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
   1688 }
   1689 
   1690 
   1691 void Assembler::modu(Register rd, Register rs, Register rt) {
   1692   DCHECK(kArchVariant == kMips64r6);
   1693   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
   1694 }
   1695 
   1696 
   1697 void Assembler::daddu(Register rd, Register rs, Register rt) {
   1698   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DADDU);
   1699 }
   1700 
   1701 
   1702 void Assembler::dsubu(Register rd, Register rs, Register rt) {
   1703   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSUBU);
   1704 }
   1705 
   1706 
   1707 void Assembler::dmult(Register rs, Register rt) {
   1708   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULT);
   1709 }
   1710 
   1711 
   1712 void Assembler::dmultu(Register rs, Register rt) {
   1713   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULTU);
   1714 }
   1715 
   1716 
   1717 void Assembler::ddiv(Register rs, Register rt) {
   1718   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIV);
   1719 }
   1720 
   1721 
   1722 void Assembler::ddiv(Register rd, Register rs, Register rt) {
   1723   DCHECK(kArchVariant == kMips64r6);
   1724   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD);
   1725 }
   1726 
   1727 
   1728 void Assembler::dmod(Register rd, Register rs, Register rt) {
   1729   DCHECK(kArchVariant == kMips64r6);
   1730   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD);
   1731 }
   1732 
   1733 
   1734 void Assembler::ddivu(Register rs, Register rt) {
   1735   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIVU);
   1736 }
   1737 
   1738 
   1739 void Assembler::ddivu(Register rd, Register rs, Register rt) {
   1740   DCHECK(kArchVariant == kMips64r6);
   1741   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD_U);
   1742 }
   1743 
   1744 
   1745 void Assembler::dmodu(Register rd, Register rs, Register rt) {
   1746   DCHECK(kArchVariant == kMips64r6);
   1747   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD_U);
   1748 }
   1749 
   1750 
   1751 // Logical.
   1752 
   1753 void Assembler::and_(Register rd, Register rs, Register rt) {
   1754   GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
   1755 }
   1756 
   1757 
   1758 void Assembler::andi(Register rt, Register rs, int32_t j) {
   1759   DCHECK(is_uint16(j));
   1760   GenInstrImmediate(ANDI, rs, rt, j);
   1761 }
   1762 
   1763 
   1764 void Assembler::or_(Register rd, Register rs, Register rt) {
   1765   GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
   1766 }
   1767 
   1768 
   1769 void Assembler::ori(Register rt, Register rs, int32_t j) {
   1770   DCHECK(is_uint16(j));
   1771   GenInstrImmediate(ORI, rs, rt, j);
   1772 }
   1773 
   1774 
   1775 void Assembler::xor_(Register rd, Register rs, Register rt) {
   1776   GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
   1777 }
   1778 
   1779 
   1780 void Assembler::xori(Register rt, Register rs, int32_t j) {
   1781   DCHECK(is_uint16(j));
   1782   GenInstrImmediate(XORI, rs, rt, j);
   1783 }
   1784 
   1785 
   1786 void Assembler::nor(Register rd, Register rs, Register rt) {
   1787   GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
   1788 }
   1789 
   1790 
   1791 // Shifts.
   1792 void Assembler::sll(Register rd,
   1793                     Register rt,
   1794                     uint16_t sa,
   1795                     bool coming_from_nop) {
   1796   // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
   1797   // generated using the sll instruction. They must be generated using
   1798   // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo
   1799   // instructions.
   1800   DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
   1801   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SLL);
   1802 }
   1803 
   1804 
   1805 void Assembler::sllv(Register rd, Register rt, Register rs) {
   1806   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
   1807 }
   1808 
   1809 
   1810 void Assembler::srl(Register rd, Register rt, uint16_t sa) {
   1811   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRL);
   1812 }
   1813 
   1814 
   1815 void Assembler::srlv(Register rd, Register rt, Register rs) {
   1816   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
   1817 }
   1818 
   1819 
   1820 void Assembler::sra(Register rd, Register rt, uint16_t sa) {
   1821   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRA);
   1822 }
   1823 
   1824 
   1825 void Assembler::srav(Register rd, Register rt, Register rs) {
   1826   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
   1827 }
   1828 
   1829 
   1830 void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
   1831   // Should be called via MacroAssembler::Ror.
   1832   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   1833   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   1834   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
   1835       | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
   1836   emit(instr);
   1837 }
   1838 
   1839 
   1840 void Assembler::rotrv(Register rd, Register rt, Register rs) {
   1841   // Should be called via MacroAssembler::Ror.
   1842   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   1843   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   1844   Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1845      | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
   1846   emit(instr);
   1847 }
   1848 
   1849 
   1850 void Assembler::dsll(Register rd, Register rt, uint16_t sa) {
   1851   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL);
   1852 }
   1853 
   1854 
   1855 void Assembler::dsllv(Register rd, Register rt, Register rs) {
   1856   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSLLV);
   1857 }
   1858 
   1859 
   1860 void Assembler::dsrl(Register rd, Register rt, uint16_t sa) {
   1861   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL);
   1862 }
   1863 
   1864 
   1865 void Assembler::dsrlv(Register rd, Register rt, Register rs) {
   1866   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRLV);
   1867 }
   1868 
   1869 
   1870 void Assembler::drotr(Register rd, Register rt, uint16_t sa) {
   1871   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   1872   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
   1873       | (rd.code() << kRdShift) | (sa << kSaShift) | DSRL;
   1874   emit(instr);
   1875 }
   1876 
   1877 void Assembler::drotr32(Register rd, Register rt, uint16_t sa) {
   1878   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   1879   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift) |
   1880                 (rd.code() << kRdShift) | (sa << kSaShift) | DSRL32;
   1881   emit(instr);
   1882 }
   1883 
   1884 void Assembler::drotrv(Register rd, Register rt, Register rs) {
   1885   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
   1886   Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1887       | (rd.code() << kRdShift) | (1 << kSaShift) | DSRLV;
   1888   emit(instr);
   1889 }
   1890 
   1891 
   1892 void Assembler::dsra(Register rd, Register rt, uint16_t sa) {
   1893   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA);
   1894 }
   1895 
   1896 
   1897 void Assembler::dsrav(Register rd, Register rt, Register rs) {
   1898   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRAV);
   1899 }
   1900 
   1901 
   1902 void Assembler::dsll32(Register rd, Register rt, uint16_t sa) {
   1903   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL32);
   1904 }
   1905 
   1906 
   1907 void Assembler::dsrl32(Register rd, Register rt, uint16_t sa) {
   1908   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL32);
   1909 }
   1910 
   1911 
   1912 void Assembler::dsra32(Register rd, Register rt, uint16_t sa) {
   1913   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA32);
   1914 }
   1915 
   1916 
   1917 void Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) {
   1918   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   1919   DCHECK(sa <= 3);
   1920   DCHECK(kArchVariant == kMips64r6);
   1921   Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
   1922                 rd.code() << kRdShift | sa << kSaShift | LSA;
   1923   emit(instr);
   1924 }
   1925 
   1926 
   1927 void Assembler::dlsa(Register rd, Register rt, Register rs, uint8_t sa) {
   1928   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   1929   DCHECK(sa <= 3);
   1930   DCHECK(kArchVariant == kMips64r6);
   1931   Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
   1932                 rd.code() << kRdShift | sa << kSaShift | DLSA;
   1933   emit(instr);
   1934 }
   1935 
   1936 
   1937 // ------------Memory-instructions-------------
   1938 
   1939 // Helper for base-reg + offset, when offset is larger than int16.
   1940 void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
   1941   DCHECK(!src.rm().is(at));
   1942   DCHECK(is_int32(src.offset_));
   1943   daddiu(at, zero_reg, (src.offset_ >> kLuiShift) & kImm16Mask);
   1944   dsll(at, at, kLuiShift);
   1945   ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
   1946   daddu(at, at, src.rm());  // Add base register.
   1947 }
   1948 
   1949 
   1950 void Assembler::lb(Register rd, const MemOperand& rs) {
   1951   if (is_int16(rs.offset_)) {
   1952     GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
   1953   } else {  // Offset > 16 bits, use multiple instructions to load.
   1954     LoadRegPlusOffsetToAt(rs);
   1955     GenInstrImmediate(LB, at, rd, 0);  // Equiv to lb(rd, MemOperand(at, 0));
   1956   }
   1957 }
   1958 
   1959 
   1960 void Assembler::lbu(Register rd, const MemOperand& rs) {
   1961   if (is_int16(rs.offset_)) {
   1962     GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
   1963   } else {  // Offset > 16 bits, use multiple instructions to load.
   1964     LoadRegPlusOffsetToAt(rs);
   1965     GenInstrImmediate(LBU, at, rd, 0);  // Equiv to lbu(rd, MemOperand(at, 0));
   1966   }
   1967 }
   1968 
   1969 
   1970 void Assembler::lh(Register rd, const MemOperand& rs) {
   1971   if (is_int16(rs.offset_)) {
   1972     GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
   1973   } else {  // Offset > 16 bits, use multiple instructions to load.
   1974     LoadRegPlusOffsetToAt(rs);
   1975     GenInstrImmediate(LH, at, rd, 0);  // Equiv to lh(rd, MemOperand(at, 0));
   1976   }
   1977 }
   1978 
   1979 
   1980 void Assembler::lhu(Register rd, const MemOperand& rs) {
   1981   if (is_int16(rs.offset_)) {
   1982     GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
   1983   } else {  // Offset > 16 bits, use multiple instructions to load.
   1984     LoadRegPlusOffsetToAt(rs);
   1985     GenInstrImmediate(LHU, at, rd, 0);  // Equiv to lhu(rd, MemOperand(at, 0));
   1986   }
   1987 }
   1988 
   1989 
   1990 void Assembler::lw(Register rd, const MemOperand& rs) {
   1991   if (is_int16(rs.offset_)) {
   1992     GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
   1993   } else {  // Offset > 16 bits, use multiple instructions to load.
   1994     LoadRegPlusOffsetToAt(rs);
   1995     GenInstrImmediate(LW, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
   1996   }
   1997 }
   1998 
   1999 
   2000 void Assembler::lwu(Register rd, const MemOperand& rs) {
   2001   if (is_int16(rs.offset_)) {
   2002     GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
   2003   } else {  // Offset > 16 bits, use multiple instructions to load.
   2004     LoadRegPlusOffsetToAt(rs);
   2005     GenInstrImmediate(LWU, at, rd, 0);  // Equiv to lwu(rd, MemOperand(at, 0));
   2006   }
   2007 }
   2008 
   2009 
   2010 void Assembler::lwl(Register rd, const MemOperand& rs) {
   2011   DCHECK(is_int16(rs.offset_));
   2012   DCHECK(kArchVariant == kMips64r2);
   2013   GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
   2014 }
   2015 
   2016 
   2017 void Assembler::lwr(Register rd, const MemOperand& rs) {
   2018   DCHECK(is_int16(rs.offset_));
   2019   DCHECK(kArchVariant == kMips64r2);
   2020   GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
   2021 }
   2022 
   2023 
   2024 void Assembler::sb(Register rd, const MemOperand& rs) {
   2025   if (is_int16(rs.offset_)) {
   2026     GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
   2027   } else {  // Offset > 16 bits, use multiple instructions to store.
   2028     LoadRegPlusOffsetToAt(rs);
   2029     GenInstrImmediate(SB, at, rd, 0);  // Equiv to sb(rd, MemOperand(at, 0));
   2030   }
   2031 }
   2032 
   2033 
   2034 void Assembler::sh(Register rd, const MemOperand& rs) {
   2035   if (is_int16(rs.offset_)) {
   2036     GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
   2037   } else {  // Offset > 16 bits, use multiple instructions to store.
   2038     LoadRegPlusOffsetToAt(rs);
   2039     GenInstrImmediate(SH, at, rd, 0);  // Equiv to sh(rd, MemOperand(at, 0));
   2040   }
   2041 }
   2042 
   2043 
   2044 void Assembler::sw(Register rd, const MemOperand& rs) {
   2045   if (is_int16(rs.offset_)) {
   2046     GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
   2047   } else {  // Offset > 16 bits, use multiple instructions to store.
   2048     LoadRegPlusOffsetToAt(rs);
   2049     GenInstrImmediate(SW, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
   2050   }
   2051 }
   2052 
   2053 
   2054 void Assembler::swl(Register rd, const MemOperand& rs) {
   2055   DCHECK(is_int16(rs.offset_));
   2056   DCHECK(kArchVariant == kMips64r2);
   2057   GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
   2058 }
   2059 
   2060 
   2061 void Assembler::swr(Register rd, const MemOperand& rs) {
   2062   DCHECK(is_int16(rs.offset_));
   2063   DCHECK(kArchVariant == kMips64r2);
   2064   GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
   2065 }
   2066 
   2067 
   2068 void Assembler::lui(Register rd, int32_t j) {
   2069   DCHECK(is_uint16(j));
   2070   GenInstrImmediate(LUI, zero_reg, rd, j);
   2071 }
   2072 
   2073 
   2074 void Assembler::aui(Register rt, Register rs, int32_t j) {
   2075   // This instruction uses same opcode as 'lui'. The difference in encoding is
   2076   // 'lui' has zero reg. for rs field.
   2077   DCHECK(is_uint16(j));
   2078   GenInstrImmediate(LUI, rs, rt, j);
   2079 }
   2080 
   2081 
   2082 void Assembler::daui(Register rt, Register rs, int32_t j) {
   2083   DCHECK(is_uint16(j));
   2084   DCHECK(!rs.is(zero_reg));
   2085   GenInstrImmediate(DAUI, rs, rt, j);
   2086 }
   2087 
   2088 
   2089 void Assembler::dahi(Register rs, int32_t j) {
   2090   DCHECK(is_uint16(j));
   2091   GenInstrImmediate(REGIMM, rs, DAHI, j);
   2092 }
   2093 
   2094 
   2095 void Assembler::dati(Register rs, int32_t j) {
   2096   DCHECK(is_uint16(j));
   2097   GenInstrImmediate(REGIMM, rs, DATI, j);
   2098 }
   2099 
   2100 
   2101 void Assembler::ldl(Register rd, const MemOperand& rs) {
   2102   DCHECK(is_int16(rs.offset_));
   2103   DCHECK(kArchVariant == kMips64r2);
   2104   GenInstrImmediate(LDL, rs.rm(), rd, rs.offset_);
   2105 }
   2106 
   2107 
   2108 void Assembler::ldr(Register rd, const MemOperand& rs) {
   2109   DCHECK(is_int16(rs.offset_));
   2110   DCHECK(kArchVariant == kMips64r2);
   2111   GenInstrImmediate(LDR, rs.rm(), rd, rs.offset_);
   2112 }
   2113 
   2114 
   2115 void Assembler::sdl(Register rd, const MemOperand& rs) {
   2116   DCHECK(is_int16(rs.offset_));
   2117   DCHECK(kArchVariant == kMips64r2);
   2118   GenInstrImmediate(SDL, rs.rm(), rd, rs.offset_);
   2119 }
   2120 
   2121 
   2122 void Assembler::sdr(Register rd, const MemOperand& rs) {
   2123   DCHECK(is_int16(rs.offset_));
   2124   DCHECK(kArchVariant == kMips64r2);
   2125   GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
   2126 }
   2127 
   2128 
   2129 void Assembler::ld(Register rd, const MemOperand& rs) {
   2130   if (is_int16(rs.offset_)) {
   2131     GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
   2132   } else {  // Offset > 16 bits, use multiple instructions to load.
   2133     LoadRegPlusOffsetToAt(rs);
   2134     GenInstrImmediate(LD, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
   2135   }
   2136 }
   2137 
   2138 
   2139 void Assembler::sd(Register rd, const MemOperand& rs) {
   2140   if (is_int16(rs.offset_)) {
   2141     GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
   2142   } else {  // Offset > 16 bits, use multiple instructions to store.
   2143     LoadRegPlusOffsetToAt(rs);
   2144     GenInstrImmediate(SD, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
   2145   }
   2146 }
   2147 
   2148 
   2149 // ---------PC-Relative instructions-----------
   2150 
   2151 void Assembler::addiupc(Register rs, int32_t imm19) {
   2152   DCHECK(kArchVariant == kMips64r6);
   2153   DCHECK(rs.is_valid() && is_int19(imm19));
   2154   uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
   2155   GenInstrImmediate(PCREL, rs, imm21);
   2156 }
   2157 
   2158 
   2159 void Assembler::lwpc(Register rs, int32_t offset19) {
   2160   DCHECK(kArchVariant == kMips64r6);
   2161   DCHECK(rs.is_valid() && is_int19(offset19));
   2162   uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
   2163   GenInstrImmediate(PCREL, rs, imm21);
   2164 }
   2165 
   2166 
   2167 void Assembler::lwupc(Register rs, int32_t offset19) {
   2168   DCHECK(kArchVariant == kMips64r6);
   2169   DCHECK(rs.is_valid() && is_int19(offset19));
   2170   uint32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
   2171   GenInstrImmediate(PCREL, rs, imm21);
   2172 }
   2173 
   2174 
   2175 void Assembler::ldpc(Register rs, int32_t offset18) {
   2176   DCHECK(kArchVariant == kMips64r6);
   2177   DCHECK(rs.is_valid() && is_int18(offset18));
   2178   uint32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
   2179   GenInstrImmediate(PCREL, rs, imm21);
   2180 }
   2181 
   2182 
   2183 void Assembler::auipc(Register rs, int16_t imm16) {
   2184   DCHECK(kArchVariant == kMips64r6);
   2185   DCHECK(rs.is_valid());
   2186   uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
   2187   GenInstrImmediate(PCREL, rs, imm21);
   2188 }
   2189 
   2190 
   2191 void Assembler::aluipc(Register rs, int16_t imm16) {
   2192   DCHECK(kArchVariant == kMips64r6);
   2193   DCHECK(rs.is_valid());
   2194   uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
   2195   GenInstrImmediate(PCREL, rs, imm21);
   2196 }
   2197 
   2198 
   2199 // -------------Misc-instructions--------------
   2200 
   2201 // Break / Trap instructions.
   2202 void Assembler::break_(uint32_t code, bool break_as_stop) {
   2203   DCHECK((code & ~0xfffff) == 0);
   2204   // We need to invalidate breaks that could be stops as well because the
   2205   // simulator expects a char pointer after the stop instruction.
   2206   // See constants-mips.h for explanation.
   2207   DCHECK((break_as_stop &&
   2208           code <= kMaxStopCode &&
   2209           code > kMaxWatchpointCode) ||
   2210          (!break_as_stop &&
   2211           (code > kMaxStopCode ||
   2212            code <= kMaxWatchpointCode)));
   2213   Instr break_instr = SPECIAL | BREAK | (code << 6);
   2214   emit(break_instr);
   2215 }
   2216 
   2217 
   2218 void Assembler::stop(const char* msg, uint32_t code) {
   2219   DCHECK(code > kMaxWatchpointCode);
   2220   DCHECK(code <= kMaxStopCode);
   2221 #if defined(V8_HOST_ARCH_MIPS) || defined(V8_HOST_ARCH_MIPS64)
   2222   break_(0x54321);
   2223 #else  // V8_HOST_ARCH_MIPS
   2224   BlockTrampolinePoolFor(3);
   2225   // The Simulator will handle the stop instruction and get the message address.
   2226   // On MIPS stop() is just a special kind of break_().
   2227   break_(code, true);
   2228   // Do not embed the message string address! We used to do this, but that
   2229   // made snapshots created from position-independent executable builds
   2230   // non-deterministic.
   2231   // TODO(yangguo): remove this field entirely.
   2232   nop();
   2233 #endif
   2234 }
   2235 
   2236 
   2237 void Assembler::tge(Register rs, Register rt, uint16_t code) {
   2238   DCHECK(is_uint10(code));
   2239   Instr instr = SPECIAL | TGE | rs.code() << kRsShift
   2240       | rt.code() << kRtShift | code << 6;
   2241   emit(instr);
   2242 }
   2243 
   2244 
   2245 void Assembler::tgeu(Register rs, Register rt, uint16_t code) {
   2246   DCHECK(is_uint10(code));
   2247   Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
   2248       | rt.code() << kRtShift | code << 6;
   2249   emit(instr);
   2250 }
   2251 
   2252 
   2253 void Assembler::tlt(Register rs, Register rt, uint16_t code) {
   2254   DCHECK(is_uint10(code));
   2255   Instr instr =
   2256       SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2257   emit(instr);
   2258 }
   2259 
   2260 
   2261 void Assembler::tltu(Register rs, Register rt, uint16_t code) {
   2262   DCHECK(is_uint10(code));
   2263   Instr instr =
   2264       SPECIAL | TLTU | rs.code() << kRsShift
   2265       | rt.code() << kRtShift | code << 6;
   2266   emit(instr);
   2267 }
   2268 
   2269 
   2270 void Assembler::teq(Register rs, Register rt, uint16_t code) {
   2271   DCHECK(is_uint10(code));
   2272   Instr instr =
   2273       SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2274   emit(instr);
   2275 }
   2276 
   2277 
   2278 void Assembler::tne(Register rs, Register rt, uint16_t code) {
   2279   DCHECK(is_uint10(code));
   2280   Instr instr =
   2281       SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2282   emit(instr);
   2283 }
   2284 
   2285 void Assembler::sync() {
   2286   Instr sync_instr = SPECIAL | SYNC;
   2287   emit(sync_instr);
   2288 }
   2289 
   2290 // Move from HI/LO register.
   2291 
   2292 void Assembler::mfhi(Register rd) {
   2293   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
   2294 }
   2295 
   2296 
   2297 void Assembler::mflo(Register rd) {
   2298   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
   2299 }
   2300 
   2301 
   2302 // Set on less than instructions.
   2303 void Assembler::slt(Register rd, Register rs, Register rt) {
   2304   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
   2305 }
   2306 
   2307 
   2308 void Assembler::sltu(Register rd, Register rs, Register rt) {
   2309   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
   2310 }
   2311 
   2312 
   2313 void Assembler::slti(Register rt, Register rs, int32_t j) {
   2314   GenInstrImmediate(SLTI, rs, rt, j);
   2315 }
   2316 
   2317 
   2318 void Assembler::sltiu(Register rt, Register rs, int32_t j) {
   2319   GenInstrImmediate(SLTIU, rs, rt, j);
   2320 }
   2321 
   2322 
   2323 // Conditional move.
   2324 void Assembler::movz(Register rd, Register rs, Register rt) {
   2325   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
   2326 }
   2327 
   2328 
   2329 void Assembler::movn(Register rd, Register rs, Register rt) {
   2330   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
   2331 }
   2332 
   2333 
   2334 void Assembler::movt(Register rd, Register rs, uint16_t cc) {
   2335   Register rt;
   2336   rt.reg_code = (cc & 0x0007) << 2 | 1;
   2337   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
   2338 }
   2339 
   2340 
   2341 void Assembler::movf(Register rd, Register rs, uint16_t cc) {
   2342   Register rt;
   2343   rt.reg_code = (cc & 0x0007) << 2 | 0;
   2344   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
   2345 }
   2346 
   2347 
   2348 void Assembler::min_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2349   min(S, fd, fs, ft);
   2350 }
   2351 
   2352 
   2353 void Assembler::min_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2354   min(D, fd, fs, ft);
   2355 }
   2356 
   2357 
   2358 void Assembler::max_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2359   max(S, fd, fs, ft);
   2360 }
   2361 
   2362 
   2363 void Assembler::max_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2364   max(D, fd, fs, ft);
   2365 }
   2366 
   2367 
   2368 void Assembler::mina_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2369   mina(S, fd, fs, ft);
   2370 }
   2371 
   2372 
   2373 void Assembler::mina_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2374   mina(D, fd, fs, ft);
   2375 }
   2376 
   2377 
   2378 void Assembler::maxa_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2379   maxa(S, fd, fs, ft);
   2380 }
   2381 
   2382 
   2383 void Assembler::maxa_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2384   maxa(D, fd, fs, ft);
   2385 }
   2386 
   2387 
   2388 void Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2389                     FPURegister ft) {
   2390   DCHECK(kArchVariant == kMips64r6);
   2391   DCHECK((fmt == D) || (fmt == S));
   2392   GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
   2393 }
   2394 
   2395 
   2396 void Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2397                     FPURegister ft) {
   2398   DCHECK(kArchVariant == kMips64r6);
   2399   DCHECK((fmt == D) || (fmt == S));
   2400   GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
   2401 }
   2402 
   2403 
   2404 // GPR.
   2405 void Assembler::seleqz(Register rd, Register rs, Register rt) {
   2406   DCHECK(kArchVariant == kMips64r6);
   2407   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
   2408 }
   2409 
   2410 
   2411 // GPR.
   2412 void Assembler::selnez(Register rd, Register rs, Register rt) {
   2413   DCHECK(kArchVariant == kMips64r6);
   2414   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
   2415 }
   2416 
   2417 
   2418 // Bit twiddling.
   2419 void Assembler::clz(Register rd, Register rs) {
   2420   if (kArchVariant != kMips64r6) {
   2421     // Clz instr requires same GPR number in 'rd' and 'rt' fields.
   2422     GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
   2423   } else {
   2424     GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
   2425   }
   2426 }
   2427 
   2428 
   2429 void Assembler::dclz(Register rd, Register rs) {
   2430   if (kArchVariant != kMips64r6) {
   2431     // dclz instr requires same GPR number in 'rd' and 'rt' fields.
   2432     GenInstrRegister(SPECIAL2, rs, rd, rd, 0, DCLZ);
   2433   } else {
   2434     GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, DCLZ_R6);
   2435   }
   2436 }
   2437 
   2438 
   2439 void Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2440   // Should be called via MacroAssembler::Ins.
   2441   // Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
   2442   DCHECK((kArchVariant == kMips64r2) || (kArchVariant == kMips64r6));
   2443   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
   2444 }
   2445 
   2446 
   2447 void Assembler::dins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2448   // Should be called via MacroAssembler::Dins.
   2449   // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
   2450   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2451   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, DINS);
   2452 }
   2453 
   2454 
   2455 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2456   // Should be called via MacroAssembler::Ext.
   2457   // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
   2458   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2459   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
   2460 }
   2461 
   2462 
   2463 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2464   // Should be called via MacroAssembler::Dext.
   2465   // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
   2466   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2467   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
   2468 }
   2469 
   2470 
   2471 void Assembler::dextm(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2472   // Should be called via MacroAssembler::Dextm.
   2473   // Dextm instr has 'rt' field as dest, and two uint5: msb, lsb.
   2474   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2475   GenInstrRegister(SPECIAL3, rs, rt, size - 1 - 32, pos, DEXTM);
   2476 }
   2477 
   2478 
   2479 void Assembler::dextu(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2480   // Should be called via MacroAssembler::Dextu.
   2481   // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
   2482   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2483   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos - 32, DEXTU);
   2484 }
   2485 
   2486 
   2487 void Assembler::bitswap(Register rd, Register rt) {
   2488   DCHECK(kArchVariant == kMips64r6);
   2489   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
   2490 }
   2491 
   2492 
   2493 void Assembler::dbitswap(Register rd, Register rt) {
   2494   DCHECK(kArchVariant == kMips64r6);
   2495   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
   2496 }
   2497 
   2498 
   2499 void Assembler::pref(int32_t hint, const MemOperand& rs) {
   2500   DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
   2501   Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
   2502       | (rs.offset_);
   2503   emit(instr);
   2504 }
   2505 
   2506 
   2507 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
   2508   DCHECK(kArchVariant == kMips64r6);
   2509   DCHECK(is_uint3(bp));
   2510   uint16_t sa = (ALIGN << kBp2Bits) | bp;
   2511   GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
   2512 }
   2513 
   2514 
   2515 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
   2516   DCHECK(kArchVariant == kMips64r6);
   2517   DCHECK(is_uint3(bp));
   2518   uint16_t sa = (DALIGN << kBp3Bits) | bp;
   2519   GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
   2520 }
   2521 
   2522 void Assembler::wsbh(Register rd, Register rt) {
   2523   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2524   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, WSBH, BSHFL);
   2525 }
   2526 
   2527 void Assembler::dsbh(Register rd, Register rt) {
   2528   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2529   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSBH, DBSHFL);
   2530 }
   2531 
   2532 void Assembler::dshd(Register rd, Register rt) {
   2533   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2534   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSHD, DBSHFL);
   2535 }
   2536 
   2537 void Assembler::seh(Register rd, Register rt) {
   2538   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2539   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEH, BSHFL);
   2540 }
   2541 
   2542 void Assembler::seb(Register rd, Register rt) {
   2543   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2544   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL);
   2545 }
   2546 
   2547 // --------Coprocessor-instructions----------------
   2548 
   2549 // Load, store, move.
   2550 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
   2551   if (is_int16(src.offset_)) {
   2552     GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
   2553   } else {  // Offset > 16 bits, use multiple instructions to load.
   2554     LoadRegPlusOffsetToAt(src);
   2555     GenInstrImmediate(LWC1, at, fd, 0);
   2556   }
   2557 }
   2558 
   2559 
   2560 void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
   2561   if (is_int16(src.offset_)) {
   2562     GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
   2563   } else {  // Offset > 16 bits, use multiple instructions to load.
   2564     LoadRegPlusOffsetToAt(src);
   2565     GenInstrImmediate(LDC1, at, fd, 0);
   2566   }
   2567 }
   2568 
   2569 
   2570 void Assembler::swc1(FPURegister fd, const MemOperand& src) {
   2571   if (is_int16(src.offset_)) {
   2572     GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
   2573   } else {  // Offset > 16 bits, use multiple instructions to load.
   2574     LoadRegPlusOffsetToAt(src);
   2575     GenInstrImmediate(SWC1, at, fd, 0);
   2576   }
   2577 }
   2578 
   2579 
   2580 void Assembler::sdc1(FPURegister fd, const MemOperand& src) {
   2581   DCHECK(!src.rm().is(at));
   2582   if (is_int16(src.offset_)) {
   2583     GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
   2584   } else {  // Offset > 16 bits, use multiple instructions to load.
   2585     LoadRegPlusOffsetToAt(src);
   2586     GenInstrImmediate(SDC1, at, fd, 0);
   2587   }
   2588 }
   2589 
   2590 
   2591 void Assembler::mtc1(Register rt, FPURegister fs) {
   2592   GenInstrRegister(COP1, MTC1, rt, fs, f0);
   2593 }
   2594 
   2595 
   2596 void Assembler::mthc1(Register rt, FPURegister fs) {
   2597   GenInstrRegister(COP1, MTHC1, rt, fs, f0);
   2598 }
   2599 
   2600 
   2601 void Assembler::dmtc1(Register rt, FPURegister fs) {
   2602   GenInstrRegister(COP1, DMTC1, rt, fs, f0);
   2603 }
   2604 
   2605 
   2606 void Assembler::mfc1(Register rt, FPURegister fs) {
   2607   GenInstrRegister(COP1, MFC1, rt, fs, f0);
   2608 }
   2609 
   2610 
   2611 void Assembler::mfhc1(Register rt, FPURegister fs) {
   2612   GenInstrRegister(COP1, MFHC1, rt, fs, f0);
   2613 }
   2614 
   2615 
   2616 void Assembler::dmfc1(Register rt, FPURegister fs) {
   2617   GenInstrRegister(COP1, DMFC1, rt, fs, f0);
   2618 }
   2619 
   2620 
   2621 void Assembler::ctc1(Register rt, FPUControlRegister fs) {
   2622   GenInstrRegister(COP1, CTC1, rt, fs);
   2623 }
   2624 
   2625 
   2626 void Assembler::cfc1(Register rt, FPUControlRegister fs) {
   2627   GenInstrRegister(COP1, CFC1, rt, fs);
   2628 }
   2629 
   2630 
   2631 void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
   2632   uint64_t i;
   2633   memcpy(&i, &d, 8);
   2634 
   2635   *lo = i & 0xffffffff;
   2636   *hi = i >> 32;
   2637 }
   2638 
   2639 
   2640 void Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2641                     FPURegister ft) {
   2642   DCHECK(kArchVariant == kMips64r6);
   2643   DCHECK((fmt == D) || (fmt == S));
   2644 
   2645   GenInstrRegister(COP1, fmt, ft, fs, fd, SEL);
   2646 }
   2647 
   2648 
   2649 void Assembler::sel_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2650   sel(S, fd, fs, ft);
   2651 }
   2652 
   2653 
   2654 void Assembler::sel_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2655   sel(D, fd, fs, ft);
   2656 }
   2657 
   2658 
   2659 // FPR.
   2660 void Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2661                        FPURegister ft) {
   2662   DCHECK((fmt == D) || (fmt == S));
   2663   GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
   2664 }
   2665 
   2666 
   2667 void Assembler::seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2668   seleqz(D, fd, fs, ft);
   2669 }
   2670 
   2671 
   2672 void Assembler::seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2673   seleqz(S, fd, fs, ft);
   2674 }
   2675 
   2676 
   2677 void Assembler::selnez_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2678   selnez(D, fd, fs, ft);
   2679 }
   2680 
   2681 
   2682 void Assembler::selnez_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2683   selnez(S, fd, fs, ft);
   2684 }
   2685 
   2686 
   2687 void Assembler::movz_s(FPURegister fd, FPURegister fs, Register rt) {
   2688   DCHECK(kArchVariant == kMips64r2);
   2689   GenInstrRegister(COP1, S, rt, fs, fd, MOVZ_C);
   2690 }
   2691 
   2692 
   2693 void Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
   2694   DCHECK(kArchVariant == kMips64r2);
   2695   GenInstrRegister(COP1, D, rt, fs, fd, MOVZ_C);
   2696 }
   2697 
   2698 
   2699 void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   2700   DCHECK(kArchVariant == kMips64r2);
   2701   FPURegister ft;
   2702   ft.reg_code = (cc & 0x0007) << 2 | 1;
   2703   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
   2704 }
   2705 
   2706 
   2707 void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   2708   DCHECK(kArchVariant == kMips64r2);
   2709   FPURegister ft;
   2710   ft.reg_code = (cc & 0x0007) << 2 | 1;
   2711   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
   2712 }
   2713 
   2714 
   2715 void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   2716   DCHECK(kArchVariant == kMips64r2);
   2717   FPURegister ft;
   2718   ft.reg_code = (cc & 0x0007) << 2 | 0;
   2719   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
   2720 }
   2721 
   2722 
   2723 void Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   2724   DCHECK(kArchVariant == kMips64r2);
   2725   FPURegister ft;
   2726   ft.reg_code = (cc & 0x0007) << 2 | 0;
   2727   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
   2728 }
   2729 
   2730 
   2731 void Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) {
   2732   DCHECK(kArchVariant == kMips64r2);
   2733   GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C);
   2734 }
   2735 
   2736 
   2737 void Assembler::movn_d(FPURegister fd, FPURegister fs, Register rt) {
   2738   DCHECK(kArchVariant == kMips64r2);
   2739   GenInstrRegister(COP1, D, rt, fs, fd, MOVN_C);
   2740 }
   2741 
   2742 
   2743 // FPR.
   2744 void Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2745                        FPURegister ft) {
   2746   DCHECK(kArchVariant == kMips64r6);
   2747   DCHECK((fmt == D) || (fmt == S));
   2748   GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
   2749 }
   2750 
   2751 
   2752 // Arithmetic.
   2753 
   2754 void Assembler::add_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2755   GenInstrRegister(COP1, S, ft, fs, fd, ADD_D);
   2756 }
   2757 
   2758 
   2759 void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2760   GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
   2761 }
   2762 
   2763 
   2764 void Assembler::sub_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2765   GenInstrRegister(COP1, S, ft, fs, fd, SUB_D);
   2766 }
   2767 
   2768 
   2769 void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2770   GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
   2771 }
   2772 
   2773 
   2774 void Assembler::mul_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2775   GenInstrRegister(COP1, S, ft, fs, fd, MUL_D);
   2776 }
   2777 
   2778 
   2779 void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2780   GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
   2781 }
   2782 
   2783 void Assembler::madd_s(FPURegister fd, FPURegister fr, FPURegister fs,
   2784                        FPURegister ft) {
   2785   DCHECK(kArchVariant == kMips64r2);
   2786   GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_S);
   2787 }
   2788 
   2789 void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
   2790     FPURegister ft) {
   2791   DCHECK(kArchVariant == kMips64r2);
   2792   GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
   2793 }
   2794 
   2795 void Assembler::msub_s(FPURegister fd, FPURegister fr, FPURegister fs,
   2796                        FPURegister ft) {
   2797   DCHECK(kArchVariant == kMips64r2);
   2798   GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_S);
   2799 }
   2800 
   2801 void Assembler::msub_d(FPURegister fd, FPURegister fr, FPURegister fs,
   2802                        FPURegister ft) {
   2803   DCHECK(kArchVariant == kMips64r2);
   2804   GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_D);
   2805 }
   2806 
   2807 void Assembler::maddf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2808   DCHECK(kArchVariant == kMips64r6);
   2809   GenInstrRegister(COP1, S, ft, fs, fd, MADDF_S);
   2810 }
   2811 
   2812 void Assembler::maddf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2813   DCHECK(kArchVariant == kMips64r6);
   2814   GenInstrRegister(COP1, D, ft, fs, fd, MADDF_D);
   2815 }
   2816 
   2817 void Assembler::msubf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2818   DCHECK(kArchVariant == kMips64r6);
   2819   GenInstrRegister(COP1, S, ft, fs, fd, MSUBF_S);
   2820 }
   2821 
   2822 void Assembler::msubf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2823   DCHECK(kArchVariant == kMips64r6);
   2824   GenInstrRegister(COP1, D, ft, fs, fd, MSUBF_D);
   2825 }
   2826 
   2827 void Assembler::div_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2828   GenInstrRegister(COP1, S, ft, fs, fd, DIV_D);
   2829 }
   2830 
   2831 
   2832 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2833   GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
   2834 }
   2835 
   2836 
   2837 void Assembler::abs_s(FPURegister fd, FPURegister fs) {
   2838   GenInstrRegister(COP1, S, f0, fs, fd, ABS_D);
   2839 }
   2840 
   2841 
   2842 void Assembler::abs_d(FPURegister fd, FPURegister fs) {
   2843   GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
   2844 }
   2845 
   2846 
   2847 void Assembler::mov_d(FPURegister fd, FPURegister fs) {
   2848   GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
   2849 }
   2850 
   2851 
   2852 void Assembler::mov_s(FPURegister fd, FPURegister fs) {
   2853   GenInstrRegister(COP1, S, f0, fs, fd, MOV_S);
   2854 }
   2855 
   2856 
   2857 void Assembler::neg_s(FPURegister fd, FPURegister fs) {
   2858   GenInstrRegister(COP1, S, f0, fs, fd, NEG_D);
   2859 }
   2860 
   2861 
   2862 void Assembler::neg_d(FPURegister fd, FPURegister fs) {
   2863   GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
   2864 }
   2865 
   2866 
   2867 void Assembler::sqrt_s(FPURegister fd, FPURegister fs) {
   2868   GenInstrRegister(COP1, S, f0, fs, fd, SQRT_D);
   2869 }
   2870 
   2871 
   2872 void Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
   2873   GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
   2874 }
   2875 
   2876 
   2877 void Assembler::rsqrt_s(FPURegister fd, FPURegister fs) {
   2878   GenInstrRegister(COP1, S, f0, fs, fd, RSQRT_S);
   2879 }
   2880 
   2881 
   2882 void Assembler::rsqrt_d(FPURegister fd, FPURegister fs) {
   2883   GenInstrRegister(COP1, D, f0, fs, fd, RSQRT_D);
   2884 }
   2885 
   2886 
   2887 void Assembler::recip_d(FPURegister fd, FPURegister fs) {
   2888   GenInstrRegister(COP1, D, f0, fs, fd, RECIP_D);
   2889 }
   2890 
   2891 
   2892 void Assembler::recip_s(FPURegister fd, FPURegister fs) {
   2893   GenInstrRegister(COP1, S, f0, fs, fd, RECIP_S);
   2894 }
   2895 
   2896 
   2897 // Conversions.
   2898 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
   2899   GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
   2900 }
   2901 
   2902 
   2903 void Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
   2904   GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
   2905 }
   2906 
   2907 
   2908 void Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
   2909   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
   2910 }
   2911 
   2912 
   2913 void Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
   2914   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
   2915 }
   2916 
   2917 
   2918 void Assembler::round_w_s(FPURegister fd, FPURegister fs) {
   2919   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
   2920 }
   2921 
   2922 
   2923 void Assembler::round_w_d(FPURegister fd, FPURegister fs) {
   2924   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
   2925 }
   2926 
   2927 
   2928 void Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
   2929   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
   2930 }
   2931 
   2932 
   2933 void Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
   2934   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
   2935 }
   2936 
   2937 
   2938 void Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
   2939   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
   2940 }
   2941 
   2942 
   2943 void Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
   2944   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
   2945 }
   2946 
   2947 
   2948 void Assembler::rint_s(FPURegister fd, FPURegister fs) { rint(S, fd, fs); }
   2949 
   2950 
   2951 void Assembler::rint_d(FPURegister fd, FPURegister fs) { rint(D, fd, fs); }
   2952 
   2953 
   2954 void Assembler::rint(SecondaryField fmt, FPURegister fd, FPURegister fs) {
   2955   DCHECK(kArchVariant == kMips64r6);
   2956   GenInstrRegister(COP1, fmt, f0, fs, fd, RINT);
   2957 }
   2958 
   2959 
   2960 void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
   2961   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2962   GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
   2963 }
   2964 
   2965 
   2966 void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
   2967   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2968   GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
   2969 }
   2970 
   2971 
   2972 void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
   2973   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2974   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
   2975 }
   2976 
   2977 
   2978 void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
   2979   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2980   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
   2981 }
   2982 
   2983 
   2984 void Assembler::round_l_s(FPURegister fd, FPURegister fs) {
   2985   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
   2986 }
   2987 
   2988 
   2989 void Assembler::round_l_d(FPURegister fd, FPURegister fs) {
   2990   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
   2991 }
   2992 
   2993 
   2994 void Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
   2995   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
   2996 }
   2997 
   2998 
   2999 void Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
   3000   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
   3001 }
   3002 
   3003 
   3004 void Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
   3005   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
   3006 }
   3007 
   3008 
   3009 void Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
   3010   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
   3011 }
   3012 
   3013 
   3014 void Assembler::class_s(FPURegister fd, FPURegister fs) {
   3015   DCHECK(kArchVariant == kMips64r6);
   3016   GenInstrRegister(COP1, S, f0, fs, fd, CLASS_S);
   3017 }
   3018 
   3019 
   3020 void Assembler::class_d(FPURegister fd, FPURegister fs) {
   3021   DCHECK(kArchVariant == kMips64r6);
   3022   GenInstrRegister(COP1, D, f0, fs, fd, CLASS_D);
   3023 }
   3024 
   3025 
   3026 void Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3027                      FPURegister ft) {
   3028   DCHECK(kArchVariant == kMips64r6);
   3029   DCHECK((fmt == D) || (fmt == S));
   3030   GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
   3031 }
   3032 
   3033 
   3034 void Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3035                      FPURegister ft) {
   3036   DCHECK(kArchVariant == kMips64r6);
   3037   DCHECK((fmt == D) || (fmt == S));
   3038   GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
   3039 }
   3040 
   3041 
   3042 void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
   3043   GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
   3044 }
   3045 
   3046 
   3047 void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
   3048   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3049   GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
   3050 }
   3051 
   3052 
   3053 void Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
   3054   GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
   3055 }
   3056 
   3057 
   3058 void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
   3059   GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
   3060 }
   3061 
   3062 
   3063 void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
   3064   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3065   GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
   3066 }
   3067 
   3068 
   3069 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
   3070   GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
   3071 }
   3072 
   3073 
   3074 // Conditions for >= MIPSr6.
   3075 void Assembler::cmp(FPUCondition cond, SecondaryField fmt,
   3076     FPURegister fd, FPURegister fs, FPURegister ft) {
   3077   DCHECK(kArchVariant == kMips64r6);
   3078   DCHECK((fmt & ~(31 << kRsShift)) == 0);
   3079   Instr instr = COP1 | fmt | ft.code() << kFtShift |
   3080       fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
   3081   emit(instr);
   3082 }
   3083 
   3084 
   3085 void Assembler::cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs,
   3086                       FPURegister ft) {
   3087   cmp(cond, W, fd, fs, ft);
   3088 }
   3089 
   3090 void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
   3091                       FPURegister ft) {
   3092   cmp(cond, L, fd, fs, ft);
   3093 }
   3094 
   3095 
   3096 void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
   3097   DCHECK(kArchVariant == kMips64r6);
   3098   Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
   3099   emit(instr);
   3100 }
   3101 
   3102 
   3103 void Assembler::bc1nez(int16_t offset, FPURegister ft) {
   3104   DCHECK(kArchVariant == kMips64r6);
   3105   Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
   3106   emit(instr);
   3107 }
   3108 
   3109 
   3110 // Conditions for < MIPSr6.
   3111 void Assembler::c(FPUCondition cond, SecondaryField fmt,
   3112     FPURegister fs, FPURegister ft, uint16_t cc) {
   3113   DCHECK(kArchVariant != kMips64r6);
   3114   DCHECK(is_uint3(cc));
   3115   DCHECK(fmt == S || fmt == D);
   3116   DCHECK((fmt & ~(31 << kRsShift)) == 0);
   3117   Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
   3118       | cc << 8 | 3 << 4 | cond;
   3119   emit(instr);
   3120 }
   3121 
   3122 
   3123 void Assembler::c_s(FPUCondition cond, FPURegister fs, FPURegister ft,
   3124                     uint16_t cc) {
   3125   c(cond, S, fs, ft, cc);
   3126 }
   3127 
   3128 
   3129 void Assembler::c_d(FPUCondition cond, FPURegister fs, FPURegister ft,
   3130                     uint16_t cc) {
   3131   c(cond, D, fs, ft, cc);
   3132 }
   3133 
   3134 
   3135 void Assembler::fcmp(FPURegister src1, const double src2,
   3136       FPUCondition cond) {
   3137   DCHECK(src2 == 0.0);
   3138   mtc1(zero_reg, f14);
   3139   cvt_d_w(f14, f14);
   3140   c(cond, D, src1, f14, 0);
   3141 }
   3142 
   3143 
   3144 void Assembler::bc1f(int16_t offset, uint16_t cc) {
   3145   DCHECK(is_uint3(cc));
   3146   Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
   3147   emit(instr);
   3148 }
   3149 
   3150 
   3151 void Assembler::bc1t(int16_t offset, uint16_t cc) {
   3152   DCHECK(is_uint3(cc));
   3153   Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
   3154   emit(instr);
   3155 }
   3156 
   3157 
   3158 int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
   3159                                          intptr_t pc_delta) {
   3160   if (RelocInfo::IsInternalReference(rmode)) {
   3161     int64_t* p = reinterpret_cast<int64_t*>(pc);
   3162     if (*p == kEndOfJumpChain) {
   3163       return 0;  // Number of instructions patched.
   3164     }
   3165     *p += pc_delta;
   3166     return 2;  // Number of instructions patched.
   3167   }
   3168   Instr instr = instr_at(pc);
   3169   DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
   3170   if (IsLui(instr)) {
   3171     Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
   3172     Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
   3173     Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize);
   3174     DCHECK(IsOri(instr_ori));
   3175     DCHECK(IsOri(instr_ori2));
   3176     // TODO(plind): symbolic names for the shifts.
   3177     int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
   3178     imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
   3179     imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)) << 16;
   3180     // Sign extend address.
   3181     imm >>= 16;
   3182 
   3183     if (imm == kEndOfJumpChain) {
   3184       return 0;  // Number of instructions patched.
   3185     }
   3186     imm += pc_delta;
   3187     DCHECK((imm & 3) == 0);
   3188 
   3189     instr_lui &= ~kImm16Mask;
   3190     instr_ori &= ~kImm16Mask;
   3191     instr_ori2 &= ~kImm16Mask;
   3192 
   3193     instr_at_put(pc + 0 * Assembler::kInstrSize,
   3194                  instr_lui | ((imm >> 32) & kImm16Mask));
   3195     instr_at_put(pc + 1 * Assembler::kInstrSize,
   3196                  instr_ori | (imm >> 16 & kImm16Mask));
   3197     instr_at_put(pc + 3 * Assembler::kInstrSize,
   3198                  instr_ori2 | (imm & kImm16Mask));
   3199     return 4;  // Number of instructions patched.
   3200   } else if (IsJ(instr) || IsJal(instr)) {
   3201     // Regular j/jal relocation.
   3202     uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
   3203     imm28 += pc_delta;
   3204     imm28 &= kImm28Mask;
   3205     instr &= ~kImm26Mask;
   3206     DCHECK((imm28 & 3) == 0);
   3207     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
   3208     instr_at_put(pc, instr | (imm26 & kImm26Mask));
   3209     return 1;  // Number of instructions patched.
   3210   } else {
   3211     DCHECK(((instr & kJumpRawMask) == kJRawMark) ||
   3212            ((instr & kJumpRawMask) == kJalRawMark));
   3213     // Unbox raw offset and emit j/jal.
   3214     int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
   3215     // Sign extend 28-bit offset to 32-bit.
   3216     imm28 = (imm28 << 4) >> 4;
   3217     uint64_t target =
   3218         static_cast<int64_t>(imm28) + reinterpret_cast<uint64_t>(pc);
   3219     target &= kImm28Mask;
   3220     DCHECK((imm28 & 3) == 0);
   3221     uint32_t imm26 = static_cast<uint32_t>(target >> 2);
   3222     // Check markings whether to emit j or jal.
   3223     uint32_t unbox = (instr & kJRawMark) ? J : JAL;
   3224     instr_at_put(pc, unbox | (imm26 & kImm26Mask));
   3225     return 1;  // Number of instructions patched.
   3226   }
   3227 }
   3228 
   3229 
   3230 void Assembler::GrowBuffer() {
   3231   if (!own_buffer_) FATAL("external code buffer is too small");
   3232 
   3233   // Compute new buffer size.
   3234   CodeDesc desc;  // The new buffer.
   3235   if (buffer_size_ < 1 * MB) {
   3236     desc.buffer_size = 2*buffer_size_;
   3237   } else {
   3238     desc.buffer_size = buffer_size_ + 1*MB;
   3239   }
   3240   CHECK_GT(desc.buffer_size, 0);  // No overflow.
   3241 
   3242   // Set up new buffer.
   3243   desc.buffer = NewArray<byte>(desc.buffer_size);
   3244   desc.origin = this;
   3245 
   3246   desc.instr_size = pc_offset();
   3247   desc.reloc_size =
   3248       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
   3249 
   3250   // Copy the data.
   3251   intptr_t pc_delta = desc.buffer - buffer_;
   3252   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
   3253       (buffer_ + buffer_size_);
   3254   MemMove(desc.buffer, buffer_, desc.instr_size);
   3255   MemMove(reloc_info_writer.pos() + rc_delta,
   3256               reloc_info_writer.pos(), desc.reloc_size);
   3257 
   3258   // Switch buffers.
   3259   DeleteArray(buffer_);
   3260   buffer_ = desc.buffer;
   3261   buffer_size_ = desc.buffer_size;
   3262   pc_ += pc_delta;
   3263   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
   3264                                reloc_info_writer.last_pc() + pc_delta);
   3265 
   3266   // Relocate runtime entries.
   3267   for (RelocIterator it(desc); !it.done(); it.next()) {
   3268     RelocInfo::Mode rmode = it.rinfo()->rmode();
   3269     if (rmode == RelocInfo::INTERNAL_REFERENCE) {
   3270       byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
   3271       RelocateInternalReference(rmode, p, pc_delta);
   3272     }
   3273   }
   3274   DCHECK(!overflow());
   3275 }
   3276 
   3277 
   3278 void Assembler::db(uint8_t data) {
   3279   CheckForEmitInForbiddenSlot();
   3280   EmitHelper(data);
   3281 }
   3282 
   3283 
   3284 void Assembler::dd(uint32_t data) {
   3285   CheckForEmitInForbiddenSlot();
   3286   EmitHelper(data);
   3287 }
   3288 
   3289 
   3290 void Assembler::dq(uint64_t data) {
   3291   CheckForEmitInForbiddenSlot();
   3292   EmitHelper(data);
   3293 }
   3294 
   3295 
   3296 void Assembler::dd(Label* label) {
   3297   uint64_t data;
   3298   CheckForEmitInForbiddenSlot();
   3299   if (label->is_bound()) {
   3300     data = reinterpret_cast<uint64_t>(buffer_ + label->pos());
   3301   } else {
   3302     data = jump_address(label);
   3303     unbound_labels_count_++;
   3304     internal_reference_positions_.insert(label->pos());
   3305   }
   3306   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
   3307   EmitHelper(data);
   3308 }
   3309 
   3310 
   3311 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
   3312   // We do not try to reuse pool constants.
   3313   RelocInfo rinfo(isolate(), pc_, rmode, data, NULL);
   3314   if (rmode >= RelocInfo::COMMENT &&
   3315       rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL) {
   3316     // Adjust code for new modes.
   3317     DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode));
   3318     // These modes do not need an entry in the constant pool.
   3319   }
   3320   if (!RelocInfo::IsNone(rinfo.rmode())) {
   3321     // Don't record external references unless the heap will be serialized.
   3322     if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
   3323         !serializer_enabled() && !emit_debug_code()) {
   3324       return;
   3325     }
   3326     DCHECK(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
   3327     if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
   3328       RelocInfo reloc_info_with_ast_id(isolate(), pc_, rmode,
   3329                                        RecordedAstId().ToInt(), NULL);
   3330       ClearRecordedAstId();
   3331       reloc_info_writer.Write(&reloc_info_with_ast_id);
   3332     } else {
   3333       reloc_info_writer.Write(&rinfo);
   3334     }
   3335   }
   3336 }
   3337 
   3338 
   3339 void Assembler::BlockTrampolinePoolFor(int instructions) {
   3340   CheckTrampolinePoolQuick(instructions);
   3341   BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
   3342 }
   3343 
   3344 
   3345 void Assembler::CheckTrampolinePool() {
   3346   // Some small sequences of instructions must not be broken up by the
   3347   // insertion of a trampoline pool; such sequences are protected by setting
   3348   // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
   3349   // which are both checked here. Also, recursive calls to CheckTrampolinePool
   3350   // are blocked by trampoline_pool_blocked_nesting_.
   3351   if ((trampoline_pool_blocked_nesting_ > 0) ||
   3352       (pc_offset() < no_trampoline_pool_before_)) {
   3353     // Emission is currently blocked; make sure we try again as soon as
   3354     // possible.
   3355     if (trampoline_pool_blocked_nesting_ > 0) {
   3356       next_buffer_check_ = pc_offset() + kInstrSize;
   3357     } else {
   3358       next_buffer_check_ = no_trampoline_pool_before_;
   3359     }
   3360     return;
   3361   }
   3362 
   3363   DCHECK(!trampoline_emitted_);
   3364   DCHECK(unbound_labels_count_ >= 0);
   3365   if (unbound_labels_count_ > 0) {
   3366     // First we emit jump (2 instructions), then we emit trampoline pool.
   3367     { BlockTrampolinePoolScope block_trampoline_pool(this);
   3368       Label after_pool;
   3369       if (kArchVariant == kMips64r6) {
   3370         bc(&after_pool);
   3371       } else {
   3372         b(&after_pool);
   3373       }
   3374       nop();
   3375 
   3376       int pool_start = pc_offset();
   3377       for (int i = 0; i < unbound_labels_count_; i++) {
   3378         { BlockGrowBufferScope block_buf_growth(this);
   3379           // Buffer growth (and relocation) must be blocked for internal
   3380           // references until associated instructions are emitted and available
   3381           // to be patched.
   3382           RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
   3383           j(&after_pool);
   3384         }
   3385         nop();
   3386       }
   3387       bind(&after_pool);
   3388       trampoline_ = Trampoline(pool_start, unbound_labels_count_);
   3389 
   3390       trampoline_emitted_ = true;
   3391       // As we are only going to emit trampoline once, we need to prevent any
   3392       // further emission.
   3393       next_buffer_check_ = kMaxInt;
   3394     }
   3395   } else {
   3396     // Number of branches to unbound label at this point is zero, so we can
   3397     // move next buffer check to maximum.
   3398     next_buffer_check_ = pc_offset() +
   3399         kMaxBranchOffset - kTrampolineSlotsSize * 16;
   3400   }
   3401   return;
   3402 }
   3403 
   3404 
   3405 Address Assembler::target_address_at(Address pc) {
   3406   Instr instr0 = instr_at(pc);
   3407   Instr instr1 = instr_at(pc + 1 * kInstrSize);
   3408   Instr instr3 = instr_at(pc + 3 * kInstrSize);
   3409 
   3410   // Interpret 4 instructions for address generated by li: See listing in
   3411   // Assembler::set_target_address_at() just below.
   3412   if ((GetOpcodeField(instr0) == LUI) && (GetOpcodeField(instr1) == ORI) &&
   3413       (GetOpcodeField(instr3) == ORI)) {
   3414     // Assemble the 48 bit value.
   3415      int64_t addr  = static_cast<int64_t>(
   3416           ((uint64_t)(GetImmediate16(instr0)) << 32) |
   3417           ((uint64_t)(GetImmediate16(instr1)) << 16) |
   3418           ((uint64_t)(GetImmediate16(instr3))));
   3419 
   3420     // Sign extend to get canonical address.
   3421     addr = (addr << 16) >> 16;
   3422     return reinterpret_cast<Address>(addr);
   3423   }
   3424   // We should never get here, force a bad address if we do.
   3425   UNREACHABLE();
   3426   return (Address)0x0;
   3427 }
   3428 
   3429 
   3430 // MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
   3431 // qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
   3432 // snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
   3433 // OS::nan_value() returns a qNaN.
   3434 void Assembler::QuietNaN(HeapObject* object) {
   3435   HeapNumber::cast(object)->set_value(std::numeric_limits<double>::quiet_NaN());
   3436 }
   3437 
   3438 
   3439 // On Mips64, a target address is stored in a 4-instruction sequence:
   3440 //    0: lui(rd, (j.imm64_ >> 32) & kImm16Mask);
   3441 //    1: ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
   3442 //    2: dsll(rd, rd, 16);
   3443 //    3: ori(rd, rd, j.imm32_ & kImm16Mask);
   3444 //
   3445 // Patching the address must replace all the lui & ori instructions,
   3446 // and flush the i-cache.
   3447 //
   3448 // There is an optimization below, which emits a nop when the address
   3449 // fits in just 16 bits. This is unlikely to help, and should be benchmarked,
   3450 // and possibly removed.
   3451 void Assembler::set_target_address_at(Isolate* isolate, Address pc,
   3452                                       Address target,
   3453                                       ICacheFlushMode icache_flush_mode) {
   3454 // There is an optimization where only 4 instructions are used to load address
   3455 // in code on MIP64 because only 48-bits of address is effectively used.
   3456 // It relies on fact the upper [63:48] bits are not used for virtual address
   3457 // translation and they have to be set according to value of bit 47 in order
   3458 // get canonical address.
   3459   Instr instr1 = instr_at(pc + kInstrSize);
   3460   uint32_t rt_code = GetRt(instr1);
   3461   uint32_t* p = reinterpret_cast<uint32_t*>(pc);
   3462   uint64_t itarget = reinterpret_cast<uint64_t>(target);
   3463 
   3464 #ifdef DEBUG
   3465   // Check we have the result from a li macro-instruction.
   3466   Instr instr0 = instr_at(pc);
   3467   Instr instr3 = instr_at(pc + kInstrSize * 3);
   3468   CHECK((GetOpcodeField(instr0) == LUI && GetOpcodeField(instr1) == ORI &&
   3469          GetOpcodeField(instr3) == ORI));
   3470 #endif
   3471 
   3472   // Must use 4 instructions to insure patchable code.
   3473   // lui rt, upper-16.
   3474   // ori rt, rt, lower-16.
   3475   // dsll rt, rt, 16.
   3476   // ori rt rt, lower-16.
   3477   *p = LUI | (rt_code << kRtShift) | ((itarget >> 32) & kImm16Mask);
   3478   *(p + 1) = ORI | (rt_code << kRtShift) | (rt_code << kRsShift)
   3479       | ((itarget >> 16) & kImm16Mask);
   3480   *(p + 3) = ORI | (rt_code << kRsShift) | (rt_code << kRtShift)
   3481       | (itarget & kImm16Mask);
   3482 
   3483   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
   3484     Assembler::FlushICache(isolate, pc, 4 * Assembler::kInstrSize);
   3485   }
   3486 }
   3487 
   3488 }  // namespace internal
   3489 }  // namespace v8
   3490 
   3491 #endif  // V8_TARGET_ARCH_MIPS64
   3492