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