Home | History | Annotate | Download | only in mips64
      1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 // - Redistributions of source code must retain the above copyright notice,
      9 // this list of conditions and the following disclaimer.
     10 //
     11 // - Redistribution in binary form must reproduce the above copyright
     12 // notice, this list of conditions and the following disclaimer in the
     13 // documentation and/or other materials provided with the distribution.
     14 //
     15 // - Neither the name of Sun Microsystems or the names of contributors may
     16 // be used to endorse or promote products derived from this software without
     17 // specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // The original source code covered by the above license above has been
     32 // modified significantly by Google Inc.
     33 // Copyright 2012 the V8 project authors. All rights reserved.
     34 
     35 #include "src/mips64/assembler-mips64.h"
     36 
     37 #if V8_TARGET_ARCH_MIPS64
     38 
     39 #include "src/base/cpu.h"
     40 #include "src/code-stubs.h"
     41 #include "src/deoptimizer.h"
     42 #include "src/mips64/assembler-mips64-inl.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 void CpuFeatures::ProbeImpl(bool cross_compile) {
     70   supported_ |= CpuFeaturesImpliedByCompiler();
     71 
     72   // Only use statically determined features for cross compile (snapshot).
     73   if (cross_compile) return;
     74 
     75   // If the compiler is allowed to use fpu then we can use fpu too in our
     76   // code generation.
     77 #ifndef __mips__
     78   // For the simulator build, use FPU.
     79   supported_ |= 1u << FPU;
     80 #if defined(_MIPS_ARCH_MIPS64R6) && defined(_MIPS_MSA)
     81   supported_ |= 1u << MIPS_SIMD;
     82 #endif
     83 #else
     84   // Probe for additional features at runtime.
     85   base::CPU cpu;
     86   if (cpu.has_fpu()) supported_ |= 1u << FPU;
     87 #if defined(_MIPS_ARCH_MIPS64R6)
     88 #if defined(_MIPS_MSA)
     89   supported_ |= 1u << MIPS_SIMD;
     90 #else
     91   if (cpu.has_msa()) supported_ |= 1u << MIPS_SIMD;
     92 #endif
     93 #endif
     94 #endif
     95 }
     96 
     97 
     98 void CpuFeatures::PrintTarget() { }
     99 void CpuFeatures::PrintFeatures() { }
    100 
    101 
    102 int ToNumber(Register reg) {
    103   DCHECK(reg.is_valid());
    104   const int kNumbers[] = {
    105     0,    // zero_reg
    106     1,    // at
    107     2,    // v0
    108     3,    // v1
    109     4,    // a0
    110     5,    // a1
    111     6,    // a2
    112     7,    // a3
    113     8,    // a4
    114     9,    // a5
    115     10,   // a6
    116     11,   // a7
    117     12,   // t0
    118     13,   // t1
    119     14,   // t2
    120     15,   // t3
    121     16,   // s0
    122     17,   // s1
    123     18,   // s2
    124     19,   // s3
    125     20,   // s4
    126     21,   // s5
    127     22,   // s6
    128     23,   // s7
    129     24,   // t8
    130     25,   // t9
    131     26,   // k0
    132     27,   // k1
    133     28,   // gp
    134     29,   // sp
    135     30,   // fp
    136     31,   // ra
    137   };
    138   return kNumbers[reg.code()];
    139 }
    140 
    141 
    142 Register ToRegister(int num) {
    143   DCHECK(num >= 0 && num < kNumRegisters);
    144   const Register kRegisters[] = {
    145     zero_reg,
    146     at,
    147     v0, v1,
    148     a0, a1, a2, a3, a4, a5, a6, a7,
    149     t0, t1, t2, t3,
    150     s0, s1, s2, s3, s4, s5, s6, s7,
    151     t8, t9,
    152     k0, k1,
    153     gp,
    154     sp,
    155     fp,
    156     ra
    157   };
    158   return kRegisters[num];
    159 }
    160 
    161 
    162 // -----------------------------------------------------------------------------
    163 // Implementation of RelocInfo.
    164 
    165 const int RelocInfo::kApplyMask =
    166     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
    167     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
    168 
    169 bool RelocInfo::IsCodedSpecially() {
    170   // The deserializer needs to know whether a pointer is specially coded.  Being
    171   // specially coded on MIPS means that it is a lui/ori instruction, and that is
    172   // always the case inside code objects.
    173   return true;
    174 }
    175 
    176 
    177 bool RelocInfo::IsInConstantPool() {
    178   return false;
    179 }
    180 
    181 int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) {
    182   DCHECK(IsRuntimeEntry(rmode_));
    183   return Deoptimizer::GetDeoptimizationId(isolate, target_address(), kind);
    184 }
    185 
    186 void RelocInfo::set_js_to_wasm_address(Address address,
    187                                        ICacheFlushMode icache_flush_mode) {
    188   DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
    189   Assembler::set_target_address_at(pc_, constant_pool_, address,
    190                                    icache_flush_mode);
    191 }
    192 
    193 Address RelocInfo::js_to_wasm_address() const {
    194   DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
    195   return Assembler::target_address_at(pc_, constant_pool_);
    196 }
    197 
    198 uint32_t RelocInfo::wasm_call_tag() const {
    199   DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
    200   return static_cast<uint32_t>(
    201       Assembler::target_address_at(pc_, constant_pool_));
    202 }
    203 
    204 // -----------------------------------------------------------------------------
    205 // Implementation of Operand and MemOperand.
    206 // See assembler-mips-inl.h for inlined constructors.
    207 
    208 Operand::Operand(Handle<HeapObject> handle)
    209     : rm_(no_reg), rmode_(RelocInfo::EMBEDDED_OBJECT) {
    210   value_.immediate = static_cast<intptr_t>(handle.address());
    211 }
    212 
    213 Operand Operand::EmbeddedNumber(double value) {
    214   int32_t smi;
    215   if (DoubleToSmiInteger(value, &smi)) return Operand(Smi::FromInt(smi));
    216   Operand result(0, RelocInfo::EMBEDDED_OBJECT);
    217   result.is_heap_object_request_ = true;
    218   result.value_.heap_object_request = HeapObjectRequest(value);
    219   return result;
    220 }
    221 
    222 Operand Operand::EmbeddedCode(CodeStub* stub) {
    223   Operand result(0, RelocInfo::CODE_TARGET);
    224   result.is_heap_object_request_ = true;
    225   result.value_.heap_object_request = HeapObjectRequest(stub);
    226   return result;
    227 }
    228 
    229 MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
    230   offset_ = offset;
    231 }
    232 
    233 
    234 MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
    235                        OffsetAddend offset_addend)
    236     : Operand(rm) {
    237   offset_ = unit * multiplier + offset_addend;
    238 }
    239 
    240 void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
    241   for (auto& request : heap_object_requests_) {
    242     Handle<HeapObject> object;
    243     switch (request.kind()) {
    244       case HeapObjectRequest::kHeapNumber:
    245         object =
    246             isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
    247         break;
    248       case HeapObjectRequest::kCodeStub:
    249         request.code_stub()->set_isolate(isolate);
    250         object = request.code_stub()->GetCode();
    251         break;
    252     }
    253     Address pc = reinterpret_cast<Address>(buffer_) + request.offset();
    254     set_target_value_at(pc, reinterpret_cast<uint64_t>(object.location()));
    255   }
    256 }
    257 
    258 // -----------------------------------------------------------------------------
    259 // Specific instructions, constants, and masks.
    260 
    261 // daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
    262 // operations as post-increment of sp.
    263 const Instr kPopInstruction = DADDIU | (sp.code() << kRsShift) |
    264                               (sp.code() << kRtShift) |
    265                               (kPointerSize & kImm16Mask);  // NOLINT
    266 // daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
    267 const Instr kPushInstruction = DADDIU | (sp.code() << kRsShift) |
    268                                (sp.code() << kRtShift) |
    269                                (-kPointerSize & kImm16Mask);  // NOLINT
    270 // Sd(r, MemOperand(sp, 0))
    271 const Instr kPushRegPattern =
    272     SD | (sp.code() << kRsShift) | (0 & kImm16Mask);  // NOLINT
    273 //  Ld(r, MemOperand(sp, 0))
    274 const Instr kPopRegPattern =
    275     LD | (sp.code() << kRsShift) | (0 & kImm16Mask);  // NOLINT
    276 
    277 const Instr kLwRegFpOffsetPattern =
    278     LW | (fp.code() << kRsShift) | (0 & kImm16Mask);  // NOLINT
    279 
    280 const Instr kSwRegFpOffsetPattern =
    281     SW | (fp.code() << kRsShift) | (0 & kImm16Mask);  // NOLINT
    282 
    283 const Instr kLwRegFpNegOffsetPattern =
    284     LW | (fp.code() << kRsShift) | (kNegOffset & kImm16Mask);  // NOLINT
    285 
    286 const Instr kSwRegFpNegOffsetPattern =
    287     SW | (fp.code() << kRsShift) | (kNegOffset & kImm16Mask);  // NOLINT
    288 // A mask for the Rt register for push, pop, lw, sw instructions.
    289 const Instr kRtMask = kRtFieldMask;
    290 const Instr kLwSwInstrTypeMask = 0xFFE00000;
    291 const Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
    292 const Instr kLwSwOffsetMask = kImm16Mask;
    293 
    294 Assembler::Assembler(const AssemblerOptions& options, void* buffer,
    295                      int buffer_size)
    296     : AssemblerBase(options, buffer, buffer_size),
    297       scratch_register_list_(at.bit()) {
    298   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
    299 
    300   last_trampoline_pool_end_ = 0;
    301   no_trampoline_pool_before_ = 0;
    302   trampoline_pool_blocked_nesting_ = 0;
    303   // We leave space (16 * kTrampolineSlotsSize)
    304   // for BlockTrampolinePoolScope buffer.
    305   next_buffer_check_ = FLAG_force_long_branches
    306       ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
    307   internal_trampoline_exception_ = false;
    308   last_bound_pos_ = 0;
    309 
    310   trampoline_emitted_ = FLAG_force_long_branches;
    311   unbound_labels_count_ = 0;
    312   block_buffer_growth_ = false;
    313 }
    314 
    315 void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
    316   EmitForbiddenSlotInstruction();
    317   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
    318 
    319   AllocateAndInstallRequestedHeapObjects(isolate);
    320 
    321   // Set up code descriptor.
    322   desc->buffer = buffer_;
    323   desc->buffer_size = buffer_size_;
    324   desc->instr_size = pc_offset();
    325   desc->reloc_size =
    326       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
    327   desc->origin = this;
    328   desc->constant_pool_size = 0;
    329   desc->unwinding_info_size = 0;
    330   desc->unwinding_info = nullptr;
    331 }
    332 
    333 
    334 void Assembler::Align(int m) {
    335   DCHECK(m >= 4 && base::bits::IsPowerOfTwo(m));
    336   EmitForbiddenSlotInstruction();
    337   while ((pc_offset() & (m - 1)) != 0) {
    338     nop();
    339   }
    340 }
    341 
    342 
    343 void Assembler::CodeTargetAlign() {
    344   // No advantage to aligning branch/call targets to more than
    345   // single instruction, that I am aware of.
    346   Align(4);
    347 }
    348 
    349 
    350 Register Assembler::GetRtReg(Instr instr) {
    351   return Register::from_code((instr & kRtFieldMask) >> kRtShift);
    352 }
    353 
    354 
    355 Register Assembler::GetRsReg(Instr instr) {
    356   return Register::from_code((instr & kRsFieldMask) >> kRsShift);
    357 }
    358 
    359 
    360 Register Assembler::GetRdReg(Instr instr) {
    361   return Register::from_code((instr & kRdFieldMask) >> kRdShift);
    362 }
    363 
    364 
    365 uint32_t Assembler::GetRt(Instr instr) {
    366   return (instr & kRtFieldMask) >> kRtShift;
    367 }
    368 
    369 
    370 uint32_t Assembler::GetRtField(Instr instr) {
    371   return instr & kRtFieldMask;
    372 }
    373 
    374 
    375 uint32_t Assembler::GetRs(Instr instr) {
    376   return (instr & kRsFieldMask) >> kRsShift;
    377 }
    378 
    379 
    380 uint32_t Assembler::GetRsField(Instr instr) {
    381   return instr & kRsFieldMask;
    382 }
    383 
    384 
    385 uint32_t Assembler::GetRd(Instr instr) {
    386   return  (instr & kRdFieldMask) >> kRdShift;
    387 }
    388 
    389 
    390 uint32_t Assembler::GetRdField(Instr instr) {
    391   return  instr & kRdFieldMask;
    392 }
    393 
    394 
    395 uint32_t Assembler::GetSa(Instr instr) {
    396   return (instr & kSaFieldMask) >> kSaShift;
    397 }
    398 
    399 
    400 uint32_t Assembler::GetSaField(Instr instr) {
    401   return instr & kSaFieldMask;
    402 }
    403 
    404 
    405 uint32_t Assembler::GetOpcodeField(Instr instr) {
    406   return instr & kOpcodeMask;
    407 }
    408 
    409 
    410 uint32_t Assembler::GetFunction(Instr instr) {
    411   return (instr & kFunctionFieldMask) >> kFunctionShift;
    412 }
    413 
    414 
    415 uint32_t Assembler::GetFunctionField(Instr instr) {
    416   return instr & kFunctionFieldMask;
    417 }
    418 
    419 
    420 uint32_t Assembler::GetImmediate16(Instr instr) {
    421   return instr & kImm16Mask;
    422 }
    423 
    424 
    425 uint32_t Assembler::GetLabelConst(Instr instr) {
    426   return instr & ~kImm16Mask;
    427 }
    428 
    429 
    430 bool Assembler::IsPop(Instr instr) {
    431   return (instr & ~kRtMask) == kPopRegPattern;
    432 }
    433 
    434 
    435 bool Assembler::IsPush(Instr instr) {
    436   return (instr & ~kRtMask) == kPushRegPattern;
    437 }
    438 
    439 
    440 bool Assembler::IsSwRegFpOffset(Instr instr) {
    441   return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
    442 }
    443 
    444 
    445 bool Assembler::IsLwRegFpOffset(Instr instr) {
    446   return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
    447 }
    448 
    449 
    450 bool Assembler::IsSwRegFpNegOffset(Instr instr) {
    451   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
    452           kSwRegFpNegOffsetPattern);
    453 }
    454 
    455 
    456 bool Assembler::IsLwRegFpNegOffset(Instr instr) {
    457   return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
    458           kLwRegFpNegOffsetPattern);
    459 }
    460 
    461 
    462 // Labels refer to positions in the (to be) generated code.
    463 // There are bound, linked, and unused labels.
    464 //
    465 // Bound labels refer to known positions in the already
    466 // generated code. pos() is the position the label refers to.
    467 //
    468 // Linked labels refer to unknown positions in the code
    469 // to be generated; pos() is the position of the last
    470 // instruction using the label.
    471 
    472 // The link chain is terminated by a value in the instruction of -1,
    473 // which is an otherwise illegal value (branch -1 is inf loop).
    474 // The instruction 16-bit offset field addresses 32-bit words, but in
    475 // code is conv to an 18-bit value addressing bytes, hence the -4 value.
    476 
    477 const int kEndOfChain = -4;
    478 // Determines the end of the Jump chain (a subset of the label link chain).
    479 const int kEndOfJumpChain = 0;
    480 
    481 bool Assembler::IsMsaBranch(Instr instr) {
    482   uint32_t opcode = GetOpcodeField(instr);
    483   uint32_t rs_field = GetRsField(instr);
    484   if (opcode == COP1) {
    485     switch (rs_field) {
    486       case BZ_V:
    487       case BZ_B:
    488       case BZ_H:
    489       case BZ_W:
    490       case BZ_D:
    491       case BNZ_V:
    492       case BNZ_B:
    493       case BNZ_H:
    494       case BNZ_W:
    495       case BNZ_D:
    496         return true;
    497       default:
    498         return false;
    499     }
    500   } else {
    501     return false;
    502   }
    503 }
    504 
    505 bool Assembler::IsBranch(Instr instr) {
    506   uint32_t opcode   = GetOpcodeField(instr);
    507   uint32_t rt_field = GetRtField(instr);
    508   uint32_t rs_field = GetRsField(instr);
    509   // Checks if the instruction is a branch.
    510   bool isBranch =
    511       opcode == BEQ || opcode == BNE || opcode == BLEZ || opcode == BGTZ ||
    512       opcode == BEQL || opcode == BNEL || opcode == BLEZL || opcode == BGTZL ||
    513       (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
    514                             rt_field == BLTZAL || rt_field == BGEZAL)) ||
    515       (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
    516       (opcode == COP1 && rs_field == BC1EQZ) ||
    517       (opcode == COP1 && rs_field == BC1NEZ) || IsMsaBranch(instr);
    518   if (!isBranch && kArchVariant == kMips64r6) {
    519     // All the 3 variants of POP10 (BOVC, BEQC, BEQZALC) and
    520     // POP30 (BNVC, BNEC, BNEZALC) are branch ops.
    521     isBranch |= opcode == POP10 || opcode == POP30 || opcode == BC ||
    522                 opcode == BALC ||
    523                 (opcode == POP66 && rs_field != 0) ||  // BEQZC
    524                 (opcode == POP76 && rs_field != 0);    // BNEZC
    525   }
    526   return isBranch;
    527 }
    528 
    529 
    530 bool Assembler::IsBc(Instr instr) {
    531   uint32_t opcode = GetOpcodeField(instr);
    532   // Checks if the instruction is a BC or BALC.
    533   return opcode == BC || opcode == BALC;
    534 }
    535 
    536 bool Assembler::IsNal(Instr instr) {
    537   uint32_t opcode = GetOpcodeField(instr);
    538   uint32_t rt_field = GetRtField(instr);
    539   uint32_t rs_field = GetRsField(instr);
    540   return opcode == REGIMM && rt_field == BLTZAL && rs_field == 0;
    541 }
    542 
    543 bool Assembler::IsBzc(Instr instr) {
    544   uint32_t opcode = GetOpcodeField(instr);
    545   // Checks if the instruction is BEQZC or BNEZC.
    546   return (opcode == POP66 && GetRsField(instr) != 0) ||
    547          (opcode == POP76 && GetRsField(instr) != 0);
    548 }
    549 
    550 
    551 bool Assembler::IsEmittedConstant(Instr instr) {
    552   uint32_t label_constant = GetLabelConst(instr);
    553   return label_constant == 0;  // Emitted label const in reg-exp engine.
    554 }
    555 
    556 
    557 bool Assembler::IsBeq(Instr instr) {
    558   return GetOpcodeField(instr) == BEQ;
    559 }
    560 
    561 
    562 bool Assembler::IsBne(Instr instr) {
    563   return GetOpcodeField(instr) == BNE;
    564 }
    565 
    566 
    567 bool Assembler::IsBeqzc(Instr instr) {
    568   uint32_t opcode = GetOpcodeField(instr);
    569   return opcode == POP66 && GetRsField(instr) != 0;
    570 }
    571 
    572 
    573 bool Assembler::IsBnezc(Instr instr) {
    574   uint32_t opcode = GetOpcodeField(instr);
    575   return opcode == POP76 && GetRsField(instr) != 0;
    576 }
    577 
    578 
    579 bool Assembler::IsBeqc(Instr instr) {
    580   uint32_t opcode = GetOpcodeField(instr);
    581   uint32_t rs = GetRsField(instr);
    582   uint32_t rt = GetRtField(instr);
    583   return opcode == POP10 && rs != 0 && rs < rt;  // && rt != 0
    584 }
    585 
    586 
    587 bool Assembler::IsBnec(Instr instr) {
    588   uint32_t opcode = GetOpcodeField(instr);
    589   uint32_t rs = GetRsField(instr);
    590   uint32_t rt = GetRtField(instr);
    591   return opcode == POP30 && rs != 0 && rs < rt;  // && rt != 0
    592 }
    593 
    594 bool Assembler::IsMov(Instr instr, Register rd, Register rs) {
    595   uint32_t opcode = GetOpcodeField(instr);
    596   uint32_t rd_field = GetRd(instr);
    597   uint32_t rs_field = GetRs(instr);
    598   uint32_t rt_field = GetRt(instr);
    599   uint32_t rd_reg = static_cast<uint32_t>(rd.code());
    600   uint32_t rs_reg = static_cast<uint32_t>(rs.code());
    601   uint32_t function_field = GetFunctionField(instr);
    602   // Checks if the instruction is a OR with zero_reg argument (aka MOV).
    603   bool res = opcode == SPECIAL && function_field == OR && rd_field == rd_reg &&
    604              rs_field == rs_reg && rt_field == 0;
    605   return res;
    606 }
    607 
    608 bool Assembler::IsJump(Instr instr) {
    609   uint32_t opcode   = GetOpcodeField(instr);
    610   uint32_t rt_field = GetRtField(instr);
    611   uint32_t rd_field = GetRdField(instr);
    612   uint32_t function_field = GetFunctionField(instr);
    613   // Checks if the instruction is a jump.
    614   return opcode == J || opcode == JAL ||
    615       (opcode == SPECIAL && rt_field == 0 &&
    616       ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
    617 }
    618 
    619 
    620 bool Assembler::IsJ(Instr instr) {
    621   uint32_t opcode = GetOpcodeField(instr);
    622   // Checks if the instruction is a jump.
    623   return opcode == J;
    624 }
    625 
    626 
    627 bool Assembler::IsJal(Instr instr) {
    628   return GetOpcodeField(instr) == JAL;
    629 }
    630 
    631 
    632 bool Assembler::IsJr(Instr instr) {
    633   return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
    634 }
    635 
    636 
    637 bool Assembler::IsJalr(Instr instr) {
    638   return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR;
    639 }
    640 
    641 
    642 bool Assembler::IsLui(Instr instr) {
    643   uint32_t opcode = GetOpcodeField(instr);
    644   // Checks if the instruction is a load upper immediate.
    645   return opcode == LUI;
    646 }
    647 
    648 
    649 bool Assembler::IsOri(Instr instr) {
    650   uint32_t opcode = GetOpcodeField(instr);
    651   // Checks if the instruction is a load upper immediate.
    652   return opcode == ORI;
    653 }
    654 
    655 
    656 bool Assembler::IsNop(Instr instr, unsigned int type) {
    657   // See Assembler::nop(type).
    658   DCHECK_LT(type, 32);
    659   uint32_t opcode = GetOpcodeField(instr);
    660   uint32_t function = GetFunctionField(instr);
    661   uint32_t rt = GetRt(instr);
    662   uint32_t rd = GetRd(instr);
    663   uint32_t sa = GetSa(instr);
    664 
    665   // Traditional mips nop == sll(zero_reg, zero_reg, 0)
    666   // When marking non-zero type, use sll(zero_reg, at, type)
    667   // to avoid use of mips ssnop and ehb special encodings
    668   // of the sll instruction.
    669 
    670   Register nop_rt_reg = (type == 0) ? zero_reg : at;
    671   bool ret = (opcode == SPECIAL && function == SLL &&
    672               rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
    673               rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
    674               sa == type);
    675 
    676   return ret;
    677 }
    678 
    679 
    680 int32_t Assembler::GetBranchOffset(Instr instr) {
    681   DCHECK(IsBranch(instr));
    682   return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
    683 }
    684 
    685 
    686 bool Assembler::IsLw(Instr instr) {
    687   return (static_cast<uint32_t>(instr & kOpcodeMask) == LW);
    688 }
    689 
    690 
    691 int16_t Assembler::GetLwOffset(Instr instr) {
    692   DCHECK(IsLw(instr));
    693   return ((instr & kImm16Mask));
    694 }
    695 
    696 
    697 Instr Assembler::SetLwOffset(Instr instr, int16_t offset) {
    698   DCHECK(IsLw(instr));
    699 
    700   // We actually create a new lw instruction based on the original one.
    701   Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
    702       | (offset & kImm16Mask);
    703 
    704   return temp_instr;
    705 }
    706 
    707 
    708 bool Assembler::IsSw(Instr instr) {
    709   return (static_cast<uint32_t>(instr & kOpcodeMask) == SW);
    710 }
    711 
    712 
    713 Instr Assembler::SetSwOffset(Instr instr, int16_t offset) {
    714   DCHECK(IsSw(instr));
    715   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
    716 }
    717 
    718 
    719 bool Assembler::IsAddImmediate(Instr instr) {
    720   return ((instr & kOpcodeMask) == ADDIU || (instr & kOpcodeMask) == DADDIU);
    721 }
    722 
    723 
    724 Instr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
    725   DCHECK(IsAddImmediate(instr));
    726   return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
    727 }
    728 
    729 
    730 bool Assembler::IsAndImmediate(Instr instr) {
    731   return GetOpcodeField(instr) == ANDI;
    732 }
    733 
    734 
    735 static Assembler::OffsetSize OffsetSizeInBits(Instr instr) {
    736   if (kArchVariant == kMips64r6) {
    737     if (Assembler::IsBc(instr)) {
    738       return Assembler::OffsetSize::kOffset26;
    739     } else if (Assembler::IsBzc(instr)) {
    740       return Assembler::OffsetSize::kOffset21;
    741     }
    742   }
    743   return Assembler::OffsetSize::kOffset16;
    744 }
    745 
    746 
    747 static inline int32_t AddBranchOffset(int pos, Instr instr) {
    748   int bits = OffsetSizeInBits(instr);
    749   const int32_t mask = (1 << bits) - 1;
    750   bits = 32 - bits;
    751 
    752   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
    753   // the compiler uses arithmetic shifts for signed integers.
    754   int32_t imm = ((instr & mask) << bits) >> (bits - 2);
    755 
    756   if (imm == kEndOfChain) {
    757     // EndOfChain sentinel is returned directly, not relative to pc or pos.
    758     return kEndOfChain;
    759   } else {
    760     return pos + Assembler::kBranchPCOffset + imm;
    761   }
    762 }
    763 
    764 
    765 int Assembler::target_at(int pos, bool is_internal) {
    766   if (is_internal) {
    767     int64_t* p = reinterpret_cast<int64_t*>(buffer_ + pos);
    768     int64_t address = *p;
    769     if (address == kEndOfJumpChain) {
    770       return kEndOfChain;
    771     } else {
    772       int64_t instr_address = reinterpret_cast<int64_t>(p);
    773       DCHECK(instr_address - address < INT_MAX);
    774       int delta = static_cast<int>(instr_address - address);
    775       DCHECK(pos > delta);
    776       return pos - delta;
    777     }
    778   }
    779   Instr instr = instr_at(pos);
    780   if ((instr & ~kImm16Mask) == 0) {
    781     // Emitted label constant, not part of a branch.
    782     if (instr == 0) {
    783        return kEndOfChain;
    784      } else {
    785        int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
    786        return (imm18 + pos);
    787      }
    788   }
    789   // Check we have a branch or jump instruction.
    790   DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr) ||
    791          IsMov(instr, t8, ra));
    792   // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
    793   // the compiler uses arithmetic shifts for signed integers.
    794   if (IsBranch(instr)) {
    795     return AddBranchOffset(pos, instr);
    796   } else if (IsMov(instr, t8, ra)) {
    797     int32_t imm32;
    798     Instr instr_lui = instr_at(pos + 2 * kInstrSize);
    799     Instr instr_ori = instr_at(pos + 3 * kInstrSize);
    800     DCHECK(IsLui(instr_lui));
    801     DCHECK(IsOri(instr_ori));
    802     imm32 = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
    803     imm32 |= (instr_ori & static_cast<int32_t>(kImm16Mask));
    804     if (imm32 == kEndOfJumpChain) {
    805       // EndOfChain sentinel is returned directly, not relative to pc or pos.
    806       return kEndOfChain;
    807     }
    808     return pos + Assembler::kLongBranchPCOffset + imm32;
    809   } else if (IsLui(instr)) {
    810     if (IsNal(instr_at(pos + kInstrSize))) {
    811       int32_t imm32;
    812       Instr instr_lui = instr_at(pos + 0 * kInstrSize);
    813       Instr instr_ori = instr_at(pos + 2 * kInstrSize);
    814       DCHECK(IsLui(instr_lui));
    815       DCHECK(IsOri(instr_ori));
    816       imm32 = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
    817       imm32 |= (instr_ori & static_cast<int32_t>(kImm16Mask));
    818       if (imm32 == kEndOfJumpChain) {
    819         // EndOfChain sentinel is returned directly, not relative to pc or pos.
    820         return kEndOfChain;
    821       }
    822       return pos + Assembler::kLongBranchPCOffset + imm32;
    823     } else {
    824       Instr instr_lui = instr_at(pos + 0 * kInstrSize);
    825       Instr instr_ori = instr_at(pos + 1 * kInstrSize);
    826       Instr instr_ori2 = instr_at(pos + 3 * kInstrSize);
    827       DCHECK(IsOri(instr_ori));
    828       DCHECK(IsOri(instr_ori2));
    829 
    830       // TODO(plind) create named constants for shift values.
    831       int64_t imm = static_cast<int64_t>(instr_lui & kImm16Mask) << 48;
    832       imm |= static_cast<int64_t>(instr_ori & kImm16Mask) << 32;
    833       imm |= static_cast<int64_t>(instr_ori2 & kImm16Mask) << 16;
    834       // Sign extend address;
    835       imm >>= 16;
    836 
    837       if (imm == kEndOfJumpChain) {
    838         // EndOfChain sentinel is returned directly, not relative to pc or pos.
    839         return kEndOfChain;
    840       } else {
    841         uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
    842         DCHECK(instr_address - imm < INT_MAX);
    843         int delta = static_cast<int>(instr_address - imm);
    844         DCHECK(pos > delta);
    845         return pos - delta;
    846       }
    847     }
    848   } else {
    849     DCHECK(IsJ(instr) || IsJal(instr));
    850     int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
    851     if (imm28 == kEndOfJumpChain) {
    852       // EndOfChain sentinel is returned directly, not relative to pc or pos.
    853       return kEndOfChain;
    854     } else {
    855       // Sign extend 28-bit offset.
    856       int32_t delta = static_cast<int32_t>((imm28 << 4) >> 4);
    857       return pos + delta;
    858     }
    859   }
    860 }
    861 
    862 
    863 static inline Instr SetBranchOffset(int32_t pos, int32_t target_pos,
    864                                     Instr instr) {
    865   int32_t bits = OffsetSizeInBits(instr);
    866   int32_t imm = target_pos - (pos + Assembler::kBranchPCOffset);
    867   DCHECK_EQ(imm & 3, 0);
    868   imm >>= 2;
    869 
    870   const int32_t mask = (1 << bits) - 1;
    871   instr &= ~mask;
    872   DCHECK(is_intn(imm, bits));
    873 
    874   return instr | (imm & mask);
    875 }
    876 
    877 
    878 void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
    879   if (is_internal) {
    880     uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
    881     *reinterpret_cast<uint64_t*>(buffer_ + pos) = imm;
    882     return;
    883   }
    884   Instr instr = instr_at(pos);
    885   if ((instr & ~kImm16Mask) == 0) {
    886     DCHECK(target_pos == kEndOfChain || target_pos >= 0);
    887     // Emitted label constant, not part of a branch.
    888     // Make label relative to Code* of generated Code object.
    889     instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
    890     return;
    891   }
    892 
    893   if (IsBranch(instr)) {
    894     instr = SetBranchOffset(pos, target_pos, instr);
    895     instr_at_put(pos, instr);
    896   } else if (IsLui(instr)) {
    897     if (IsNal(instr_at(pos + kInstrSize))) {
    898       Instr instr_lui = instr_at(pos + 0 * kInstrSize);
    899       Instr instr_ori = instr_at(pos + 2 * kInstrSize);
    900       DCHECK(IsLui(instr_lui));
    901       DCHECK(IsOri(instr_ori));
    902       int32_t imm = target_pos - (pos + Assembler::kLongBranchPCOffset);
    903       DCHECK_EQ(imm & 3, 0);
    904       if (is_int16(imm + Assembler::kLongBranchPCOffset -
    905                    Assembler::kBranchPCOffset)) {
    906         // Optimize by converting to regular branch and link with 16-bit
    907         // offset.
    908         Instr instr_b = REGIMM | BGEZAL;  // Branch and link.
    909         instr_b = SetBranchOffset(pos, target_pos, instr_b);
    910         // Correct ra register to point to one instruction after jalr from
    911         // TurboAssembler::BranchAndLinkLong.
    912         Instr instr_a = DADDIU | ra.code() << kRsShift | ra.code() << kRtShift |
    913                         kOptimizedBranchAndLinkLongReturnOffset;
    914 
    915         instr_at_put(pos, instr_b);
    916         instr_at_put(pos + 1 * kInstrSize, instr_a);
    917       } else {
    918         instr_lui &= ~kImm16Mask;
    919         instr_ori &= ~kImm16Mask;
    920 
    921         instr_at_put(pos + 0 * kInstrSize,
    922                      instr_lui | ((imm >> kLuiShift) & kImm16Mask));
    923         instr_at_put(pos + 2 * kInstrSize, instr_ori | (imm & kImm16Mask));
    924       }
    925     } else {
    926       Instr instr_lui = instr_at(pos + 0 * kInstrSize);
    927       Instr instr_ori = instr_at(pos + 1 * kInstrSize);
    928       Instr instr_ori2 = instr_at(pos + 3 * kInstrSize);
    929       DCHECK(IsOri(instr_ori));
    930       DCHECK(IsOri(instr_ori2));
    931 
    932       uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
    933       DCHECK_EQ(imm & 3, 0);
    934 
    935       instr_lui &= ~kImm16Mask;
    936       instr_ori &= ~kImm16Mask;
    937       instr_ori2 &= ~kImm16Mask;
    938 
    939       instr_at_put(pos + 0 * kInstrSize,
    940                    instr_lui | ((imm >> 32) & kImm16Mask));
    941       instr_at_put(pos + 1 * kInstrSize,
    942                    instr_ori | ((imm >> 16) & kImm16Mask));
    943       instr_at_put(pos + 3 * kInstrSize, instr_ori2 | (imm & kImm16Mask));
    944     }
    945   } else if (IsMov(instr, t8, ra)) {
    946     Instr instr_lui = instr_at(pos + 2 * kInstrSize);
    947     Instr instr_ori = instr_at(pos + 3 * kInstrSize);
    948     DCHECK(IsLui(instr_lui));
    949     DCHECK(IsOri(instr_ori));
    950 
    951     int32_t imm_short = target_pos - (pos + Assembler::kBranchPCOffset);
    952 
    953     if (is_int16(imm_short)) {
    954       // Optimize by converting to regular branch with 16-bit
    955       // offset
    956       Instr instr_b = BEQ;
    957       instr_b = SetBranchOffset(pos, target_pos, instr_b);
    958 
    959       Instr instr_j = instr_at(pos + 5 * kInstrSize);
    960       Instr instr_branch_delay;
    961 
    962       if (IsJump(instr_j)) {
    963         instr_branch_delay = instr_at(pos + 6 * kInstrSize);
    964       } else {
    965         instr_branch_delay = instr_at(pos + 7 * kInstrSize);
    966       }
    967       instr_at_put(pos, instr_b);
    968       instr_at_put(pos + 1 * kInstrSize, instr_branch_delay);
    969     } else {
    970       int32_t imm = target_pos - (pos + Assembler::kLongBranchPCOffset);
    971       DCHECK_EQ(imm & 3, 0);
    972 
    973       instr_lui &= ~kImm16Mask;
    974       instr_ori &= ~kImm16Mask;
    975 
    976       instr_at_put(pos + 2 * kInstrSize,
    977                    instr_lui | ((imm >> kLuiShift) & kImm16Mask));
    978       instr_at_put(pos + 3 * kInstrSize, instr_ori | (imm & kImm16Mask));
    979     }
    980   } else if (IsJ(instr) || IsJal(instr)) {
    981     int32_t imm28 = target_pos - pos;
    982     DCHECK_EQ(imm28 & 3, 0);
    983 
    984     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
    985     DCHECK(is_uint26(imm26));
    986     // Place 26-bit signed offset with markings.
    987     // When code is committed it will be resolved to j/jal.
    988     int32_t mark = IsJ(instr) ? kJRawMark : kJalRawMark;
    989     instr_at_put(pos, mark | (imm26 & kImm26Mask));
    990   } else {
    991     int32_t imm28 = target_pos - pos;
    992     DCHECK_EQ(imm28 & 3, 0);
    993 
    994     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
    995     DCHECK(is_uint26(imm26));
    996     // Place raw 26-bit signed offset.
    997     // When code is committed it will be resolved to j/jal.
    998     instr &= ~kImm26Mask;
    999     instr_at_put(pos, instr | (imm26 & kImm26Mask));
   1000   }
   1001 }
   1002 
   1003 void Assembler::print(const Label* L) {
   1004   if (L->is_unused()) {
   1005     PrintF("unused label\n");
   1006   } else if (L->is_bound()) {
   1007     PrintF("bound label to %d\n", L->pos());
   1008   } else if (L->is_linked()) {
   1009     Label l;
   1010     l.link_to(L->pos());
   1011     PrintF("unbound label");
   1012     while (l.is_linked()) {
   1013       PrintF("@ %d ", l.pos());
   1014       Instr instr = instr_at(l.pos());
   1015       if ((instr & ~kImm16Mask) == 0) {
   1016         PrintF("value\n");
   1017       } else {
   1018         PrintF("%d\n", instr);
   1019       }
   1020       next(&l, is_internal_reference(&l));
   1021     }
   1022   } else {
   1023     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
   1024   }
   1025 }
   1026 
   1027 
   1028 void Assembler::bind_to(Label* L, int pos) {
   1029   DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
   1030   int trampoline_pos = kInvalidSlotPos;
   1031   bool is_internal = false;
   1032   if (L->is_linked() && !trampoline_emitted_) {
   1033     unbound_labels_count_--;
   1034     if (!is_internal_reference(L)) {
   1035       next_buffer_check_ += kTrampolineSlotsSize;
   1036     }
   1037   }
   1038 
   1039   while (L->is_linked()) {
   1040     int fixup_pos = L->pos();
   1041     int dist = pos - fixup_pos;
   1042     is_internal = is_internal_reference(L);
   1043     next(L, is_internal);  // Call next before overwriting link with target at
   1044                            // fixup_pos.
   1045     Instr instr = instr_at(fixup_pos);
   1046     if (is_internal) {
   1047       target_at_put(fixup_pos, pos, is_internal);
   1048     } else {
   1049       if (IsBranch(instr)) {
   1050         int branch_offset = BranchOffset(instr);
   1051         if (dist > branch_offset) {
   1052           if (trampoline_pos == kInvalidSlotPos) {
   1053             trampoline_pos = get_trampoline_entry(fixup_pos);
   1054             CHECK_NE(trampoline_pos, kInvalidSlotPos);
   1055           }
   1056           CHECK((trampoline_pos - fixup_pos) <= branch_offset);
   1057           target_at_put(fixup_pos, trampoline_pos, false);
   1058           fixup_pos = trampoline_pos;
   1059         }
   1060         target_at_put(fixup_pos, pos, false);
   1061       } else {
   1062         DCHECK(IsJ(instr) || IsJal(instr) || IsLui(instr) ||
   1063                IsEmittedConstant(instr) || IsMov(instr, t8, ra));
   1064         target_at_put(fixup_pos, pos, false);
   1065       }
   1066     }
   1067   }
   1068   L->bind_to(pos);
   1069 
   1070   // Keep track of the last bound label so we don't eliminate any instructions
   1071   // before a bound label.
   1072   if (pos > last_bound_pos_)
   1073     last_bound_pos_ = pos;
   1074 }
   1075 
   1076 
   1077 void Assembler::bind(Label* L) {
   1078   DCHECK(!L->is_bound());  // Label can only be bound once.
   1079   bind_to(L, pc_offset());
   1080 }
   1081 
   1082 
   1083 void Assembler::next(Label* L, bool is_internal) {
   1084   DCHECK(L->is_linked());
   1085   int link = target_at(L->pos(), is_internal);
   1086   if (link == kEndOfChain) {
   1087     L->Unuse();
   1088   } else {
   1089     DCHECK_GE(link, 0);
   1090     L->link_to(link);
   1091   }
   1092 }
   1093 
   1094 
   1095 bool Assembler::is_near(Label* L) {
   1096   DCHECK(L->is_bound());
   1097   return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize;
   1098 }
   1099 
   1100 
   1101 bool Assembler::is_near(Label* L, OffsetSize bits) {
   1102   if (L == nullptr || !L->is_bound()) return true;
   1103   return ((pc_offset() - L->pos()) <
   1104           (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize);
   1105 }
   1106 
   1107 
   1108 bool Assembler::is_near_branch(Label* L) {
   1109   DCHECK(L->is_bound());
   1110   return kArchVariant == kMips64r6 ? is_near_r6(L) : is_near_pre_r6(L);
   1111 }
   1112 
   1113 
   1114 int Assembler::BranchOffset(Instr instr) {
   1115   // At pre-R6 and for other R6 branches the offset is 16 bits.
   1116   int bits = OffsetSize::kOffset16;
   1117 
   1118   if (kArchVariant == kMips64r6) {
   1119     uint32_t opcode = GetOpcodeField(instr);
   1120     switch (opcode) {
   1121       // Checks BC or BALC.
   1122       case BC:
   1123       case BALC:
   1124         bits = OffsetSize::kOffset26;
   1125         break;
   1126 
   1127       // Checks BEQZC or BNEZC.
   1128       case POP66:
   1129       case POP76:
   1130         if (GetRsField(instr) != 0) bits = OffsetSize::kOffset21;
   1131         break;
   1132       default:
   1133         break;
   1134     }
   1135   }
   1136 
   1137   return (1 << (bits + 2 - 1)) - 1;
   1138 }
   1139 
   1140 
   1141 // We have to use a temporary register for things that can be relocated even
   1142 // if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
   1143 // space.  There is no guarantee that the relocated location can be similarly
   1144 // encoded.
   1145 bool Assembler::MustUseReg(RelocInfo::Mode rmode) {
   1146   return !RelocInfo::IsNone(rmode);
   1147 }
   1148 
   1149 void Assembler::GenInstrRegister(Opcode opcode,
   1150                                  Register rs,
   1151                                  Register rt,
   1152                                  Register rd,
   1153                                  uint16_t sa,
   1154                                  SecondaryField func) {
   1155   DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
   1156   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1157       | (rd.code() << kRdShift) | (sa << kSaShift) | func;
   1158   emit(instr);
   1159 }
   1160 
   1161 
   1162 void Assembler::GenInstrRegister(Opcode opcode,
   1163                                  Register rs,
   1164                                  Register rt,
   1165                                  uint16_t msb,
   1166                                  uint16_t lsb,
   1167                                  SecondaryField func) {
   1168   DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
   1169   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1170       | (msb << kRdShift) | (lsb << kSaShift) | func;
   1171   emit(instr);
   1172 }
   1173 
   1174 
   1175 void Assembler::GenInstrRegister(Opcode opcode,
   1176                                  SecondaryField fmt,
   1177                                  FPURegister ft,
   1178                                  FPURegister fs,
   1179                                  FPURegister fd,
   1180                                  SecondaryField func) {
   1181   DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
   1182   Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
   1183       | (fd.code() << kFdShift) | func;
   1184   emit(instr);
   1185 }
   1186 
   1187 
   1188 void Assembler::GenInstrRegister(Opcode opcode,
   1189                                  FPURegister fr,
   1190                                  FPURegister ft,
   1191                                  FPURegister fs,
   1192                                  FPURegister fd,
   1193                                  SecondaryField func) {
   1194   DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
   1195   Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
   1196       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
   1197   emit(instr);
   1198 }
   1199 
   1200 
   1201 void Assembler::GenInstrRegister(Opcode opcode,
   1202                                  SecondaryField fmt,
   1203                                  Register rt,
   1204                                  FPURegister fs,
   1205                                  FPURegister fd,
   1206                                  SecondaryField func) {
   1207   DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
   1208   Instr instr = opcode | fmt | (rt.code() << kRtShift)
   1209       | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
   1210   emit(instr);
   1211 }
   1212 
   1213 
   1214 void Assembler::GenInstrRegister(Opcode opcode,
   1215                                  SecondaryField fmt,
   1216                                  Register rt,
   1217                                  FPUControlRegister fs,
   1218                                  SecondaryField func) {
   1219   DCHECK(fs.is_valid() && rt.is_valid());
   1220   Instr instr =
   1221       opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
   1222   emit(instr);
   1223 }
   1224 
   1225 
   1226 // Instructions with immediate value.
   1227 // Registers are in the order of the instruction encoding, from left to right.
   1228 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, Register rt,
   1229                                   int32_t j,
   1230                                   CompactBranchType is_compact_branch) {
   1231   DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
   1232   Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   1233       | (j & kImm16Mask);
   1234   emit(instr, is_compact_branch);
   1235 }
   1236 
   1237 void Assembler::GenInstrImmediate(Opcode opcode, Register base, Register rt,
   1238                                   int32_t offset9, int bit6,
   1239                                   SecondaryField func) {
   1240   DCHECK(base.is_valid() && rt.is_valid() && is_int9(offset9) &&
   1241          is_uint1(bit6));
   1242   Instr instr = opcode | (base.code() << kBaseShift) | (rt.code() << kRtShift) |
   1243                 ((offset9 << kImm9Shift) & kImm9Mask) | bit6 << kBit6Shift |
   1244                 func;
   1245   emit(instr);
   1246 }
   1247 
   1248 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, SecondaryField SF,
   1249                                   int32_t j,
   1250                                   CompactBranchType is_compact_branch) {
   1251   DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
   1252   Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
   1253   emit(instr, is_compact_branch);
   1254 }
   1255 
   1256 
   1257 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, FPURegister ft,
   1258                                   int32_t j,
   1259                                   CompactBranchType is_compact_branch) {
   1260   DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
   1261   Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
   1262       | (j & kImm16Mask);
   1263   emit(instr, is_compact_branch);
   1264 }
   1265 
   1266 
   1267 void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t offset21,
   1268                                   CompactBranchType is_compact_branch) {
   1269   DCHECK(rs.is_valid() && (is_int21(offset21)));
   1270   Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
   1271   emit(instr, is_compact_branch);
   1272 }
   1273 
   1274 
   1275 void Assembler::GenInstrImmediate(Opcode opcode, Register rs,
   1276                                   uint32_t offset21) {
   1277   DCHECK(rs.is_valid() && (is_uint21(offset21)));
   1278   Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
   1279   emit(instr);
   1280 }
   1281 
   1282 
   1283 void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26,
   1284                                   CompactBranchType is_compact_branch) {
   1285   DCHECK(is_int26(offset26));
   1286   Instr instr = opcode | (offset26 & kImm26Mask);
   1287   emit(instr, is_compact_branch);
   1288 }
   1289 
   1290 
   1291 void Assembler::GenInstrJump(Opcode opcode,
   1292                              uint32_t address) {
   1293   BlockTrampolinePoolScope block_trampoline_pool(this);
   1294   DCHECK(is_uint26(address));
   1295   Instr instr = opcode | address;
   1296   emit(instr);
   1297   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1298 }
   1299 
   1300 // MSA instructions
   1301 void Assembler::GenInstrMsaI8(SecondaryField operation, uint32_t imm8,
   1302                               MSARegister ws, MSARegister wd) {
   1303   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1304   DCHECK(ws.is_valid() && wd.is_valid() && is_uint8(imm8));
   1305   Instr instr = MSA | operation | ((imm8 & kImm8Mask) << kWtShift) |
   1306                 (ws.code() << kWsShift) | (wd.code() << kWdShift);
   1307   emit(instr);
   1308 }
   1309 
   1310 void Assembler::GenInstrMsaI5(SecondaryField operation, SecondaryField df,
   1311                               int32_t imm5, MSARegister ws, MSARegister wd) {
   1312   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1313   DCHECK(ws.is_valid() && wd.is_valid());
   1314   DCHECK((operation == MAXI_S) || (operation == MINI_S) ||
   1315                  (operation == CEQI) || (operation == CLTI_S) ||
   1316                  (operation == CLEI_S)
   1317              ? is_int5(imm5)
   1318              : is_uint5(imm5));
   1319   Instr instr = MSA | operation | df | ((imm5 & kImm5Mask) << kWtShift) |
   1320                 (ws.code() << kWsShift) | (wd.code() << kWdShift);
   1321   emit(instr);
   1322 }
   1323 
   1324 void Assembler::GenInstrMsaBit(SecondaryField operation, SecondaryField df,
   1325                                uint32_t m, MSARegister ws, MSARegister wd) {
   1326   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1327   DCHECK(ws.is_valid() && wd.is_valid() && is_valid_msa_df_m(df, m));
   1328   Instr instr = MSA | operation | df | (m << kWtShift) |
   1329                 (ws.code() << kWsShift) | (wd.code() << kWdShift);
   1330   emit(instr);
   1331 }
   1332 
   1333 void Assembler::GenInstrMsaI10(SecondaryField operation, SecondaryField df,
   1334                                int32_t imm10, MSARegister wd) {
   1335   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1336   DCHECK(wd.is_valid() && is_int10(imm10));
   1337   Instr instr = MSA | operation | df | ((imm10 & kImm10Mask) << kWsShift) |
   1338                 (wd.code() << kWdShift);
   1339   emit(instr);
   1340 }
   1341 
   1342 template <typename RegType>
   1343 void Assembler::GenInstrMsa3R(SecondaryField operation, SecondaryField df,
   1344                               RegType t, MSARegister ws, MSARegister wd) {
   1345   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1346   DCHECK(t.is_valid() && ws.is_valid() && wd.is_valid());
   1347   Instr instr = MSA | operation | df | (t.code() << kWtShift) |
   1348                 (ws.code() << kWsShift) | (wd.code() << kWdShift);
   1349   emit(instr);
   1350 }
   1351 
   1352 template <typename DstType, typename SrcType>
   1353 void Assembler::GenInstrMsaElm(SecondaryField operation, SecondaryField df,
   1354                                uint32_t n, SrcType src, DstType dst) {
   1355   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1356   DCHECK(src.is_valid() && dst.is_valid() && is_valid_msa_df_n(df, n));
   1357   Instr instr = MSA | operation | df | (n << kWtShift) |
   1358                 (src.code() << kWsShift) | (dst.code() << kWdShift) |
   1359                 MSA_ELM_MINOR;
   1360   emit(instr);
   1361 }
   1362 
   1363 void Assembler::GenInstrMsa3RF(SecondaryField operation, uint32_t df,
   1364                                MSARegister wt, MSARegister ws, MSARegister wd) {
   1365   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1366   DCHECK(wt.is_valid() && ws.is_valid() && wd.is_valid());
   1367   DCHECK_LT(df, 2);
   1368   Instr instr = MSA | operation | (df << 21) | (wt.code() << kWtShift) |
   1369                 (ws.code() << kWsShift) | (wd.code() << kWdShift);
   1370   emit(instr);
   1371 }
   1372 
   1373 void Assembler::GenInstrMsaVec(SecondaryField operation, MSARegister wt,
   1374                                MSARegister ws, MSARegister wd) {
   1375   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1376   DCHECK(wt.is_valid() && ws.is_valid() && wd.is_valid());
   1377   Instr instr = MSA | operation | (wt.code() << kWtShift) |
   1378                 (ws.code() << kWsShift) | (wd.code() << kWdShift) |
   1379                 MSA_VEC_2R_2RF_MINOR;
   1380   emit(instr);
   1381 }
   1382 
   1383 void Assembler::GenInstrMsaMI10(SecondaryField operation, int32_t s10,
   1384                                 Register rs, MSARegister wd) {
   1385   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1386   DCHECK(rs.is_valid() && wd.is_valid() && is_int10(s10));
   1387   Instr instr = MSA | operation | ((s10 & kImm10Mask) << kWtShift) |
   1388                 (rs.code() << kWsShift) | (wd.code() << kWdShift);
   1389   emit(instr);
   1390 }
   1391 
   1392 void Assembler::GenInstrMsa2R(SecondaryField operation, SecondaryField df,
   1393                               MSARegister ws, MSARegister wd) {
   1394   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1395   DCHECK(ws.is_valid() && wd.is_valid());
   1396   Instr instr = MSA | MSA_2R_FORMAT | operation | df | (ws.code() << kWsShift) |
   1397                 (wd.code() << kWdShift) | MSA_VEC_2R_2RF_MINOR;
   1398   emit(instr);
   1399 }
   1400 
   1401 void Assembler::GenInstrMsa2RF(SecondaryField operation, SecondaryField df,
   1402                                MSARegister ws, MSARegister wd) {
   1403   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1404   DCHECK(ws.is_valid() && wd.is_valid());
   1405   Instr instr = MSA | MSA_2RF_FORMAT | operation | df |
   1406                 (ws.code() << kWsShift) | (wd.code() << kWdShift) |
   1407                 MSA_VEC_2R_2RF_MINOR;
   1408   emit(instr);
   1409 }
   1410 
   1411 void Assembler::GenInstrMsaBranch(SecondaryField operation, MSARegister wt,
   1412                                   int32_t offset16) {
   1413   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   1414   DCHECK(wt.is_valid() && is_int16(offset16));
   1415   BlockTrampolinePoolScope block_trampoline_pool(this);
   1416   Instr instr =
   1417       COP1 | operation | (wt.code() << kWtShift) | (offset16 & kImm16Mask);
   1418   emit(instr);
   1419   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1420 }
   1421 
   1422 // Returns the next free trampoline entry.
   1423 int32_t Assembler::get_trampoline_entry(int32_t pos) {
   1424   int32_t trampoline_entry = kInvalidSlotPos;
   1425   if (!internal_trampoline_exception_) {
   1426     if (trampoline_.start() > pos) {
   1427      trampoline_entry = trampoline_.take_slot();
   1428     }
   1429 
   1430     if (kInvalidSlotPos == trampoline_entry) {
   1431       internal_trampoline_exception_ = true;
   1432     }
   1433   }
   1434   return trampoline_entry;
   1435 }
   1436 
   1437 
   1438 uint64_t Assembler::jump_address(Label* L) {
   1439   int64_t target_pos;
   1440   if (L->is_bound()) {
   1441     target_pos = L->pos();
   1442   } else {
   1443     if (L->is_linked()) {
   1444       target_pos = L->pos();  // L's link.
   1445       L->link_to(pc_offset());
   1446     } else {
   1447       L->link_to(pc_offset());
   1448       return kEndOfJumpChain;
   1449     }
   1450   }
   1451   uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
   1452   DCHECK_EQ(imm & 3, 0);
   1453 
   1454   return imm;
   1455 }
   1456 
   1457 
   1458 uint64_t Assembler::jump_offset(Label* L) {
   1459   int64_t target_pos;
   1460   int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
   1461 
   1462   if (L->is_bound()) {
   1463     target_pos = L->pos();
   1464   } else {
   1465     if (L->is_linked()) {
   1466       target_pos = L->pos();  // L's link.
   1467       L->link_to(pc_offset() + pad);
   1468     } else {
   1469       L->link_to(pc_offset() + pad);
   1470       return kEndOfJumpChain;
   1471     }
   1472   }
   1473   int64_t imm = target_pos - (pc_offset() + pad);
   1474   DCHECK_EQ(imm & 3, 0);
   1475 
   1476   return static_cast<uint64_t>(imm);
   1477 }
   1478 
   1479 uint64_t Assembler::branch_long_offset(Label* L) {
   1480   int64_t target_pos;
   1481 
   1482   if (L->is_bound()) {
   1483     target_pos = L->pos();
   1484   } else {
   1485     if (L->is_linked()) {
   1486       target_pos = L->pos();  // L's link.
   1487       L->link_to(pc_offset());
   1488     } else {
   1489       L->link_to(pc_offset());
   1490       return kEndOfJumpChain;
   1491     }
   1492   }
   1493   int64_t offset = target_pos - (pc_offset() + kLongBranchPCOffset);
   1494   DCHECK_EQ(offset & 3, 0);
   1495 
   1496   return static_cast<uint64_t>(offset);
   1497 }
   1498 
   1499 int32_t Assembler::branch_offset_helper(Label* L, OffsetSize bits) {
   1500   int32_t target_pos;
   1501   int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
   1502 
   1503   if (L->is_bound()) {
   1504     target_pos = L->pos();
   1505   } else {
   1506     if (L->is_linked()) {
   1507       target_pos = L->pos();
   1508       L->link_to(pc_offset() + pad);
   1509     } else {
   1510       L->link_to(pc_offset() + pad);
   1511       if (!trampoline_emitted_) {
   1512         unbound_labels_count_++;
   1513         next_buffer_check_ -= kTrampolineSlotsSize;
   1514       }
   1515       return kEndOfChain;
   1516     }
   1517   }
   1518 
   1519   int32_t offset = target_pos - (pc_offset() + kBranchPCOffset + pad);
   1520   DCHECK(is_intn(offset, bits + 2));
   1521   DCHECK_EQ(offset & 3, 0);
   1522 
   1523   return offset;
   1524 }
   1525 
   1526 
   1527 void Assembler::label_at_put(Label* L, int at_offset) {
   1528   int target_pos;
   1529   if (L->is_bound()) {
   1530     target_pos = L->pos();
   1531     instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
   1532   } else {
   1533     if (L->is_linked()) {
   1534       target_pos = L->pos();  // L's link.
   1535       int32_t imm18 = target_pos - at_offset;
   1536       DCHECK_EQ(imm18 & 3, 0);
   1537       int32_t imm16 = imm18 >> 2;
   1538       DCHECK(is_int16(imm16));
   1539       instr_at_put(at_offset, (imm16 & kImm16Mask));
   1540     } else {
   1541       target_pos = kEndOfChain;
   1542       instr_at_put(at_offset, 0);
   1543       if (!trampoline_emitted_) {
   1544         unbound_labels_count_++;
   1545         next_buffer_check_ -= kTrampolineSlotsSize;
   1546       }
   1547     }
   1548     L->link_to(at_offset);
   1549   }
   1550 }
   1551 
   1552 
   1553 //------- Branch and jump instructions --------
   1554 
   1555 void Assembler::b(int16_t offset) {
   1556   beq(zero_reg, zero_reg, offset);
   1557 }
   1558 
   1559 
   1560 void Assembler::bal(int16_t offset) {
   1561   bgezal(zero_reg, offset);
   1562 }
   1563 
   1564 
   1565 void Assembler::bc(int32_t offset) {
   1566   DCHECK_EQ(kArchVariant, kMips64r6);
   1567   GenInstrImmediate(BC, offset, CompactBranchType::COMPACT_BRANCH);
   1568 }
   1569 
   1570 
   1571 void Assembler::balc(int32_t offset) {
   1572   DCHECK_EQ(kArchVariant, kMips64r6);
   1573   GenInstrImmediate(BALC, offset, CompactBranchType::COMPACT_BRANCH);
   1574 }
   1575 
   1576 
   1577 void Assembler::beq(Register rs, Register rt, int16_t offset) {
   1578   BlockTrampolinePoolScope block_trampoline_pool(this);
   1579   GenInstrImmediate(BEQ, rs, rt, offset);
   1580   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1581 }
   1582 
   1583 
   1584 void Assembler::bgez(Register rs, int16_t offset) {
   1585   BlockTrampolinePoolScope block_trampoline_pool(this);
   1586   GenInstrImmediate(REGIMM, rs, BGEZ, offset);
   1587   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1588 }
   1589 
   1590 
   1591 void Assembler::bgezc(Register rt, int16_t offset) {
   1592   DCHECK_EQ(kArchVariant, kMips64r6);
   1593   DCHECK(rt != zero_reg);
   1594   GenInstrImmediate(BLEZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1595 }
   1596 
   1597 
   1598 void Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
   1599   DCHECK_EQ(kArchVariant, kMips64r6);
   1600   DCHECK(rs != zero_reg);
   1601   DCHECK(rt != zero_reg);
   1602   DCHECK(rs.code() != rt.code());
   1603   GenInstrImmediate(BLEZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1604 }
   1605 
   1606 
   1607 void Assembler::bgec(Register rs, Register rt, int16_t offset) {
   1608   DCHECK_EQ(kArchVariant, kMips64r6);
   1609   DCHECK(rs != zero_reg);
   1610   DCHECK(rt != zero_reg);
   1611   DCHECK(rs.code() != rt.code());
   1612   GenInstrImmediate(BLEZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1613 }
   1614 
   1615 
   1616 void Assembler::bgezal(Register rs, int16_t offset) {
   1617   DCHECK(kArchVariant != kMips64r6 || rs == zero_reg);
   1618   DCHECK(rs != ra);
   1619   BlockTrampolinePoolScope block_trampoline_pool(this);
   1620   GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
   1621   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1622 }
   1623 
   1624 
   1625 void Assembler::bgtz(Register rs, int16_t offset) {
   1626   BlockTrampolinePoolScope block_trampoline_pool(this);
   1627   GenInstrImmediate(BGTZ, rs, zero_reg, offset);
   1628   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1629 }
   1630 
   1631 
   1632 void Assembler::bgtzc(Register rt, int16_t offset) {
   1633   DCHECK_EQ(kArchVariant, kMips64r6);
   1634   DCHECK(rt != zero_reg);
   1635   GenInstrImmediate(BGTZL, zero_reg, rt, offset,
   1636                     CompactBranchType::COMPACT_BRANCH);
   1637 }
   1638 
   1639 
   1640 void Assembler::blez(Register rs, int16_t offset) {
   1641   BlockTrampolinePoolScope block_trampoline_pool(this);
   1642   GenInstrImmediate(BLEZ, rs, zero_reg, offset);
   1643   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1644 }
   1645 
   1646 
   1647 void Assembler::blezc(Register rt, int16_t offset) {
   1648   DCHECK_EQ(kArchVariant, kMips64r6);
   1649   DCHECK(rt != zero_reg);
   1650   GenInstrImmediate(BLEZL, zero_reg, rt, offset,
   1651                     CompactBranchType::COMPACT_BRANCH);
   1652 }
   1653 
   1654 
   1655 void Assembler::bltzc(Register rt, int16_t offset) {
   1656   DCHECK_EQ(kArchVariant, kMips64r6);
   1657   DCHECK(rt != zero_reg);
   1658   GenInstrImmediate(BGTZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1659 }
   1660 
   1661 
   1662 void Assembler::bltuc(Register rs, Register rt, int16_t offset) {
   1663   DCHECK_EQ(kArchVariant, kMips64r6);
   1664   DCHECK(rs != zero_reg);
   1665   DCHECK(rt != zero_reg);
   1666   DCHECK(rs.code() != rt.code());
   1667   GenInstrImmediate(BGTZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1668 }
   1669 
   1670 
   1671 void Assembler::bltc(Register rs, Register rt, int16_t offset) {
   1672   DCHECK_EQ(kArchVariant, kMips64r6);
   1673   DCHECK(rs != zero_reg);
   1674   DCHECK(rt != zero_reg);
   1675   DCHECK(rs.code() != rt.code());
   1676   GenInstrImmediate(BGTZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1677 }
   1678 
   1679 
   1680 void Assembler::bltz(Register rs, int16_t offset) {
   1681   BlockTrampolinePoolScope block_trampoline_pool(this);
   1682   GenInstrImmediate(REGIMM, rs, BLTZ, offset);
   1683   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1684 }
   1685 
   1686 
   1687 void Assembler::bltzal(Register rs, int16_t offset) {
   1688   DCHECK(kArchVariant != kMips64r6 || rs == zero_reg);
   1689   DCHECK(rs != ra);
   1690   BlockTrampolinePoolScope block_trampoline_pool(this);
   1691   GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
   1692   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1693 }
   1694 
   1695 
   1696 void Assembler::bne(Register rs, Register rt, int16_t offset) {
   1697   BlockTrampolinePoolScope block_trampoline_pool(this);
   1698   GenInstrImmediate(BNE, rs, rt, offset);
   1699   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1700 }
   1701 
   1702 
   1703 void Assembler::bovc(Register rs, Register rt, int16_t offset) {
   1704   DCHECK_EQ(kArchVariant, kMips64r6);
   1705   if (rs.code() >= rt.code()) {
   1706     GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1707   } else {
   1708     GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1709   }
   1710 }
   1711 
   1712 
   1713 void Assembler::bnvc(Register rs, Register rt, int16_t offset) {
   1714   DCHECK_EQ(kArchVariant, kMips64r6);
   1715   if (rs.code() >= rt.code()) {
   1716     GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1717   } else {
   1718     GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1719   }
   1720 }
   1721 
   1722 
   1723 void Assembler::blezalc(Register rt, int16_t offset) {
   1724   DCHECK_EQ(kArchVariant, kMips64r6);
   1725   DCHECK(rt != zero_reg);
   1726   DCHECK(rt != ra);
   1727   GenInstrImmediate(BLEZ, zero_reg, rt, offset,
   1728                     CompactBranchType::COMPACT_BRANCH);
   1729 }
   1730 
   1731 
   1732 void Assembler::bgezalc(Register rt, int16_t offset) {
   1733   DCHECK_EQ(kArchVariant, kMips64r6);
   1734   DCHECK(rt != zero_reg);
   1735   DCHECK(rt != ra);
   1736   GenInstrImmediate(BLEZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1737 }
   1738 
   1739 
   1740 void Assembler::bgezall(Register rs, int16_t offset) {
   1741   DCHECK_NE(kArchVariant, kMips64r6);
   1742   DCHECK(rs != zero_reg);
   1743   DCHECK(rs != ra);
   1744   BlockTrampolinePoolScope block_trampoline_pool(this);
   1745   GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
   1746   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1747 }
   1748 
   1749 
   1750 void Assembler::bltzalc(Register rt, int16_t offset) {
   1751   DCHECK_EQ(kArchVariant, kMips64r6);
   1752   DCHECK(rt != zero_reg);
   1753   DCHECK(rt != ra);
   1754   GenInstrImmediate(BGTZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1755 }
   1756 
   1757 
   1758 void Assembler::bgtzalc(Register rt, int16_t offset) {
   1759   DCHECK_EQ(kArchVariant, kMips64r6);
   1760   DCHECK(rt != zero_reg);
   1761   DCHECK(rt != ra);
   1762   GenInstrImmediate(BGTZ, zero_reg, rt, offset,
   1763                     CompactBranchType::COMPACT_BRANCH);
   1764 }
   1765 
   1766 
   1767 void Assembler::beqzalc(Register rt, int16_t offset) {
   1768   DCHECK_EQ(kArchVariant, kMips64r6);
   1769   DCHECK(rt != zero_reg);
   1770   DCHECK(rt != ra);
   1771   GenInstrImmediate(ADDI, zero_reg, rt, offset,
   1772                     CompactBranchType::COMPACT_BRANCH);
   1773 }
   1774 
   1775 
   1776 void Assembler::bnezalc(Register rt, int16_t offset) {
   1777   DCHECK_EQ(kArchVariant, kMips64r6);
   1778   DCHECK(rt != zero_reg);
   1779   DCHECK(rt != ra);
   1780   GenInstrImmediate(DADDI, zero_reg, rt, offset,
   1781                     CompactBranchType::COMPACT_BRANCH);
   1782 }
   1783 
   1784 
   1785 void Assembler::beqc(Register rs, Register rt, int16_t offset) {
   1786   DCHECK_EQ(kArchVariant, kMips64r6);
   1787   DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
   1788   if (rs.code() < rt.code()) {
   1789     GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1790   } else {
   1791     GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1792   }
   1793 }
   1794 
   1795 
   1796 void Assembler::beqzc(Register rs, int32_t offset) {
   1797   DCHECK_EQ(kArchVariant, kMips64r6);
   1798   DCHECK(rs != zero_reg);
   1799   GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1800 }
   1801 
   1802 
   1803 void Assembler::bnec(Register rs, Register rt, int16_t offset) {
   1804   DCHECK_EQ(kArchVariant, kMips64r6);
   1805   DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
   1806   if (rs.code() < rt.code()) {
   1807     GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
   1808   } else {
   1809     GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1810   }
   1811 }
   1812 
   1813 
   1814 void Assembler::bnezc(Register rs, int32_t offset) {
   1815   DCHECK_EQ(kArchVariant, kMips64r6);
   1816   DCHECK(rs != zero_reg);
   1817   GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH);
   1818 }
   1819 
   1820 
   1821 void Assembler::j(int64_t target) {
   1822   BlockTrampolinePoolScope block_trampoline_pool(this);
   1823   GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask);
   1824   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1825 }
   1826 
   1827 
   1828 void Assembler::j(Label* target) {
   1829   uint64_t imm = jump_offset(target);
   1830   if (target->is_bound()) {
   1831     BlockTrampolinePoolScope block_trampoline_pool(this);
   1832     GenInstrJump(static_cast<Opcode>(kJRawMark),
   1833                  static_cast<uint32_t>(imm >> 2) & kImm26Mask);
   1834     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1835   } else {
   1836     j(imm);
   1837   }
   1838 }
   1839 
   1840 
   1841 void Assembler::jal(Label* target) {
   1842   uint64_t imm = jump_offset(target);
   1843   if (target->is_bound()) {
   1844     BlockTrampolinePoolScope block_trampoline_pool(this);
   1845     GenInstrJump(static_cast<Opcode>(kJalRawMark),
   1846                  static_cast<uint32_t>(imm >> 2) & kImm26Mask);
   1847     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1848   } else {
   1849     jal(imm);
   1850   }
   1851 }
   1852 
   1853 
   1854 void Assembler::jr(Register rs) {
   1855   if (kArchVariant != kMips64r6) {
   1856     BlockTrampolinePoolScope block_trampoline_pool(this);
   1857     GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
   1858     BlockTrampolinePoolFor(1);  // For associated delay slot.
   1859   } else {
   1860     jalr(rs, zero_reg);
   1861   }
   1862 }
   1863 
   1864 
   1865 void Assembler::jal(int64_t target) {
   1866   BlockTrampolinePoolScope block_trampoline_pool(this);
   1867   GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask);
   1868   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1869 }
   1870 
   1871 
   1872 void Assembler::jalr(Register rs, Register rd) {
   1873   DCHECK(rs.code() != rd.code());
   1874   BlockTrampolinePoolScope block_trampoline_pool(this);
   1875   GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
   1876   BlockTrampolinePoolFor(1);  // For associated delay slot.
   1877 }
   1878 
   1879 
   1880 void Assembler::jic(Register rt, int16_t offset) {
   1881   DCHECK_EQ(kArchVariant, kMips64r6);
   1882   GenInstrImmediate(POP66, zero_reg, rt, offset);
   1883 }
   1884 
   1885 
   1886 void Assembler::jialc(Register rt, int16_t offset) {
   1887   DCHECK_EQ(kArchVariant, kMips64r6);
   1888   GenInstrImmediate(POP76, zero_reg, rt, offset);
   1889 }
   1890 
   1891 
   1892 // -------Data-processing-instructions---------
   1893 
   1894 // Arithmetic.
   1895 
   1896 void Assembler::addu(Register rd, Register rs, Register rt) {
   1897   GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
   1898 }
   1899 
   1900 
   1901 void Assembler::addiu(Register rd, Register rs, int32_t j) {
   1902   GenInstrImmediate(ADDIU, rs, rd, j);
   1903 }
   1904 
   1905 
   1906 void Assembler::subu(Register rd, Register rs, Register rt) {
   1907   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
   1908 }
   1909 
   1910 
   1911 void Assembler::mul(Register rd, Register rs, Register rt) {
   1912   if (kArchVariant == kMips64r6) {
   1913       GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
   1914   } else {
   1915       GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
   1916   }
   1917 }
   1918 
   1919 
   1920 void Assembler::muh(Register rd, Register rs, Register rt) {
   1921   DCHECK_EQ(kArchVariant, kMips64r6);
   1922   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
   1923 }
   1924 
   1925 
   1926 void Assembler::mulu(Register rd, Register rs, Register rt) {
   1927   DCHECK_EQ(kArchVariant, kMips64r6);
   1928   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
   1929 }
   1930 
   1931 
   1932 void Assembler::muhu(Register rd, Register rs, Register rt) {
   1933   DCHECK_EQ(kArchVariant, kMips64r6);
   1934   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
   1935 }
   1936 
   1937 
   1938 void Assembler::dmul(Register rd, Register rs, Register rt) {
   1939   DCHECK_EQ(kArchVariant, kMips64r6);
   1940   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH);
   1941 }
   1942 
   1943 
   1944 void Assembler::dmuh(Register rd, Register rs, Register rt) {
   1945   DCHECK_EQ(kArchVariant, kMips64r6);
   1946   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH);
   1947 }
   1948 
   1949 
   1950 void Assembler::dmulu(Register rd, Register rs, Register rt) {
   1951   DCHECK_EQ(kArchVariant, kMips64r6);
   1952   GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH_U);
   1953 }
   1954 
   1955 
   1956 void Assembler::dmuhu(Register rd, Register rs, Register rt) {
   1957   DCHECK_EQ(kArchVariant, kMips64r6);
   1958   GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH_U);
   1959 }
   1960 
   1961 
   1962 void Assembler::mult(Register rs, Register rt) {
   1963   DCHECK_NE(kArchVariant, kMips64r6);
   1964   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
   1965 }
   1966 
   1967 
   1968 void Assembler::multu(Register rs, Register rt) {
   1969   DCHECK_NE(kArchVariant, kMips64r6);
   1970   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
   1971 }
   1972 
   1973 
   1974 void Assembler::daddiu(Register rd, Register rs, int32_t j) {
   1975   GenInstrImmediate(DADDIU, rs, rd, j);
   1976 }
   1977 
   1978 
   1979 void Assembler::div(Register rs, Register rt) {
   1980   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
   1981 }
   1982 
   1983 
   1984 void Assembler::div(Register rd, Register rs, Register rt) {
   1985   DCHECK_EQ(kArchVariant, kMips64r6);
   1986   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
   1987 }
   1988 
   1989 
   1990 void Assembler::mod(Register rd, Register rs, Register rt) {
   1991   DCHECK_EQ(kArchVariant, kMips64r6);
   1992   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
   1993 }
   1994 
   1995 
   1996 void Assembler::divu(Register rs, Register rt) {
   1997   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
   1998 }
   1999 
   2000 
   2001 void Assembler::divu(Register rd, Register rs, Register rt) {
   2002   DCHECK_EQ(kArchVariant, kMips64r6);
   2003   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
   2004 }
   2005 
   2006 
   2007 void Assembler::modu(Register rd, Register rs, Register rt) {
   2008   DCHECK_EQ(kArchVariant, kMips64r6);
   2009   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
   2010 }
   2011 
   2012 
   2013 void Assembler::daddu(Register rd, Register rs, Register rt) {
   2014   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DADDU);
   2015 }
   2016 
   2017 
   2018 void Assembler::dsubu(Register rd, Register rs, Register rt) {
   2019   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSUBU);
   2020 }
   2021 
   2022 
   2023 void Assembler::dmult(Register rs, Register rt) {
   2024   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULT);
   2025 }
   2026 
   2027 
   2028 void Assembler::dmultu(Register rs, Register rt) {
   2029   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULTU);
   2030 }
   2031 
   2032 
   2033 void Assembler::ddiv(Register rs, Register rt) {
   2034   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIV);
   2035 }
   2036 
   2037 
   2038 void Assembler::ddiv(Register rd, Register rs, Register rt) {
   2039   DCHECK_EQ(kArchVariant, kMips64r6);
   2040   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD);
   2041 }
   2042 
   2043 
   2044 void Assembler::dmod(Register rd, Register rs, Register rt) {
   2045   DCHECK_EQ(kArchVariant, kMips64r6);
   2046   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD);
   2047 }
   2048 
   2049 
   2050 void Assembler::ddivu(Register rs, Register rt) {
   2051   GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIVU);
   2052 }
   2053 
   2054 
   2055 void Assembler::ddivu(Register rd, Register rs, Register rt) {
   2056   DCHECK_EQ(kArchVariant, kMips64r6);
   2057   GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD_U);
   2058 }
   2059 
   2060 
   2061 void Assembler::dmodu(Register rd, Register rs, Register rt) {
   2062   DCHECK_EQ(kArchVariant, kMips64r6);
   2063   GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD_U);
   2064 }
   2065 
   2066 
   2067 // Logical.
   2068 
   2069 void Assembler::and_(Register rd, Register rs, Register rt) {
   2070   GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
   2071 }
   2072 
   2073 
   2074 void Assembler::andi(Register rt, Register rs, int32_t j) {
   2075   DCHECK(is_uint16(j));
   2076   GenInstrImmediate(ANDI, rs, rt, j);
   2077 }
   2078 
   2079 
   2080 void Assembler::or_(Register rd, Register rs, Register rt) {
   2081   GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
   2082 }
   2083 
   2084 
   2085 void Assembler::ori(Register rt, Register rs, int32_t j) {
   2086   DCHECK(is_uint16(j));
   2087   GenInstrImmediate(ORI, rs, rt, j);
   2088 }
   2089 
   2090 
   2091 void Assembler::xor_(Register rd, Register rs, Register rt) {
   2092   GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
   2093 }
   2094 
   2095 
   2096 void Assembler::xori(Register rt, Register rs, int32_t j) {
   2097   DCHECK(is_uint16(j));
   2098   GenInstrImmediate(XORI, rs, rt, j);
   2099 }
   2100 
   2101 
   2102 void Assembler::nor(Register rd, Register rs, Register rt) {
   2103   GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
   2104 }
   2105 
   2106 
   2107 // Shifts.
   2108 void Assembler::sll(Register rd,
   2109                     Register rt,
   2110                     uint16_t sa,
   2111                     bool coming_from_nop) {
   2112   // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
   2113   // generated using the sll instruction. They must be generated using
   2114   // nop(int/NopMarkerTypes).
   2115   DCHECK(coming_from_nop || (rd != zero_reg && rt != zero_reg));
   2116   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SLL);
   2117 }
   2118 
   2119 
   2120 void Assembler::sllv(Register rd, Register rt, Register rs) {
   2121   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
   2122 }
   2123 
   2124 
   2125 void Assembler::srl(Register rd, Register rt, uint16_t sa) {
   2126   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRL);
   2127 }
   2128 
   2129 
   2130 void Assembler::srlv(Register rd, Register rt, Register rs) {
   2131   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
   2132 }
   2133 
   2134 
   2135 void Assembler::sra(Register rd, Register rt, uint16_t sa) {
   2136   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRA);
   2137 }
   2138 
   2139 
   2140 void Assembler::srav(Register rd, Register rt, Register rs) {
   2141   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
   2142 }
   2143 
   2144 
   2145 void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
   2146   // Should be called via MacroAssembler::Ror.
   2147   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   2148   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2149   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
   2150       | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
   2151   emit(instr);
   2152 }
   2153 
   2154 
   2155 void Assembler::rotrv(Register rd, Register rt, Register rs) {
   2156   // Should be called via MacroAssembler::Ror.
   2157   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   2158   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2159   Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   2160      | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
   2161   emit(instr);
   2162 }
   2163 
   2164 
   2165 void Assembler::dsll(Register rd, Register rt, uint16_t sa) {
   2166   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL);
   2167 }
   2168 
   2169 
   2170 void Assembler::dsllv(Register rd, Register rt, Register rs) {
   2171   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSLLV);
   2172 }
   2173 
   2174 
   2175 void Assembler::dsrl(Register rd, Register rt, uint16_t sa) {
   2176   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL);
   2177 }
   2178 
   2179 
   2180 void Assembler::dsrlv(Register rd, Register rt, Register rs) {
   2181   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRLV);
   2182 }
   2183 
   2184 
   2185 void Assembler::drotr(Register rd, Register rt, uint16_t sa) {
   2186   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   2187   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
   2188       | (rd.code() << kRdShift) | (sa << kSaShift) | DSRL;
   2189   emit(instr);
   2190 }
   2191 
   2192 void Assembler::drotr32(Register rd, Register rt, uint16_t sa) {
   2193   DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
   2194   Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift) |
   2195                 (rd.code() << kRdShift) | (sa << kSaShift) | DSRL32;
   2196   emit(instr);
   2197 }
   2198 
   2199 void Assembler::drotrv(Register rd, Register rt, Register rs) {
   2200   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
   2201   Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
   2202       | (rd.code() << kRdShift) | (1 << kSaShift) | DSRLV;
   2203   emit(instr);
   2204 }
   2205 
   2206 
   2207 void Assembler::dsra(Register rd, Register rt, uint16_t sa) {
   2208   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA);
   2209 }
   2210 
   2211 
   2212 void Assembler::dsrav(Register rd, Register rt, Register rs) {
   2213   GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRAV);
   2214 }
   2215 
   2216 
   2217 void Assembler::dsll32(Register rd, Register rt, uint16_t sa) {
   2218   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL32);
   2219 }
   2220 
   2221 
   2222 void Assembler::dsrl32(Register rd, Register rt, uint16_t sa) {
   2223   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL32);
   2224 }
   2225 
   2226 
   2227 void Assembler::dsra32(Register rd, Register rt, uint16_t sa) {
   2228   GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA32);
   2229 }
   2230 
   2231 
   2232 void Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) {
   2233   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   2234   DCHECK_LE(sa, 3);
   2235   DCHECK_EQ(kArchVariant, kMips64r6);
   2236   Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
   2237                 rd.code() << kRdShift | sa << kSaShift | LSA;
   2238   emit(instr);
   2239 }
   2240 
   2241 
   2242 void Assembler::dlsa(Register rd, Register rt, Register rs, uint8_t sa) {
   2243   DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
   2244   DCHECK_LE(sa, 3);
   2245   DCHECK_EQ(kArchVariant, kMips64r6);
   2246   Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
   2247                 rd.code() << kRdShift | sa << kSaShift | DLSA;
   2248   emit(instr);
   2249 }
   2250 
   2251 
   2252 // ------------Memory-instructions-------------
   2253 
   2254 void Assembler::AdjustBaseAndOffset(MemOperand& src,
   2255                                     OffsetAccessType access_type,
   2256                                     int second_access_add_to_offset) {
   2257   // This method is used to adjust the base register and offset pair
   2258   // for a load/store when the offset doesn't fit into int16_t.
   2259   // It is assumed that 'base + offset' is sufficiently aligned for memory
   2260   // operands that are machine word in size or smaller. For doubleword-sized
   2261   // operands it's assumed that 'base' is a multiple of 8, while 'offset'
   2262   // may be a multiple of 4 (e.g. 4-byte-aligned long and double arguments
   2263   // and spilled variables on the stack accessed relative to the stack
   2264   // pointer register).
   2265   // We preserve the "alignment" of 'offset' by adjusting it by a multiple of 8.
   2266 
   2267   bool doubleword_aligned = (src.offset() & (kDoubleSize - 1)) == 0;
   2268   bool two_accesses = static_cast<bool>(access_type) || !doubleword_aligned;
   2269   DCHECK_LE(second_access_add_to_offset, 7);  // Must be <= 7.
   2270 
   2271   // is_int16 must be passed a signed value, hence the static cast below.
   2272   if (is_int16(src.offset()) &&
   2273       (!two_accesses || is_int16(static_cast<int32_t>(
   2274                             src.offset() + second_access_add_to_offset)))) {
   2275     // Nothing to do: 'offset' (and, if needed, 'offset + 4', or other specified
   2276     // value) fits into int16_t.
   2277     return;
   2278   }
   2279 
   2280   DCHECK(src.rm() !=
   2281          at);  // Must not overwrite the register 'base' while loading 'offset'.
   2282 
   2283 #ifdef DEBUG
   2284   // Remember the "(mis)alignment" of 'offset', it will be checked at the end.
   2285   uint32_t misalignment = src.offset() & (kDoubleSize - 1);
   2286 #endif
   2287 
   2288   // Do not load the whole 32-bit 'offset' if it can be represented as
   2289   // a sum of two 16-bit signed offsets. This can save an instruction or two.
   2290   // To simplify matters, only do this for a symmetric range of offsets from
   2291   // about -64KB to about +64KB, allowing further addition of 4 when accessing
   2292   // 64-bit variables with two 32-bit accesses.
   2293   constexpr int32_t kMinOffsetForSimpleAdjustment =
   2294       0x7FF8;  // Max int16_t that's a multiple of 8.
   2295   constexpr int32_t kMaxOffsetForSimpleAdjustment =
   2296       2 * kMinOffsetForSimpleAdjustment;
   2297 
   2298   UseScratchRegisterScope temps(this);
   2299   Register scratch = temps.Acquire();
   2300   if (0 <= src.offset() && src.offset() <= kMaxOffsetForSimpleAdjustment) {
   2301     daddiu(scratch, src.rm(), kMinOffsetForSimpleAdjustment);
   2302     src.offset_ -= kMinOffsetForSimpleAdjustment;
   2303   } else if (-kMaxOffsetForSimpleAdjustment <= src.offset() &&
   2304              src.offset() < 0) {
   2305     daddiu(scratch, src.rm(), -kMinOffsetForSimpleAdjustment);
   2306     src.offset_ += kMinOffsetForSimpleAdjustment;
   2307   } else if (kArchVariant == kMips64r6) {
   2308     // On r6 take advantage of the daui instruction, e.g.:
   2309     //    daui   at, base, offset_high
   2310     //   [dahi   at, 1]                       // When `offset` is close to +2GB.
   2311     //    lw     reg_lo, offset_low(at)
   2312     //   [lw     reg_hi, (offset_low+4)(at)]  // If misaligned 64-bit load.
   2313     // or when offset_low+4 overflows int16_t:
   2314     //    daui   at, base, offset_high
   2315     //    daddiu at, at, 8
   2316     //    lw     reg_lo, (offset_low-8)(at)
   2317     //    lw     reg_hi, (offset_low-4)(at)
   2318     int16_t offset_low = static_cast<uint16_t>(src.offset());
   2319     int32_t offset_low32 = offset_low;
   2320     int16_t offset_high = static_cast<uint16_t>(src.offset() >> 16);
   2321     bool increment_hi16 = offset_low < 0;
   2322     bool overflow_hi16 = false;
   2323 
   2324     if (increment_hi16) {
   2325       offset_high++;
   2326       overflow_hi16 = (offset_high == -32768);
   2327     }
   2328     daui(scratch, src.rm(), static_cast<uint16_t>(offset_high));
   2329 
   2330     if (overflow_hi16) {
   2331       dahi(scratch, 1);
   2332     }
   2333 
   2334     if (two_accesses && !is_int16(static_cast<int32_t>(
   2335                             offset_low32 + second_access_add_to_offset))) {
   2336       // Avoid overflow in the 16-bit offset of the load/store instruction when
   2337       // adding 4.
   2338       daddiu(scratch, scratch, kDoubleSize);
   2339       offset_low32 -= kDoubleSize;
   2340     }
   2341 
   2342     src.offset_ = offset_low32;
   2343   } else {
   2344     // Do not load the whole 32-bit 'offset' if it can be represented as
   2345     // a sum of three 16-bit signed offsets. This can save an instruction.
   2346     // To simplify matters, only do this for a symmetric range of offsets from
   2347     // about -96KB to about +96KB, allowing further addition of 4 when accessing
   2348     // 64-bit variables with two 32-bit accesses.
   2349     constexpr int32_t kMinOffsetForMediumAdjustment =
   2350         2 * kMinOffsetForSimpleAdjustment;
   2351     constexpr int32_t kMaxOffsetForMediumAdjustment =
   2352         3 * kMinOffsetForSimpleAdjustment;
   2353     if (0 <= src.offset() && src.offset() <= kMaxOffsetForMediumAdjustment) {
   2354       daddiu(scratch, src.rm(), kMinOffsetForMediumAdjustment / 2);
   2355       daddiu(scratch, scratch, kMinOffsetForMediumAdjustment / 2);
   2356       src.offset_ -= kMinOffsetForMediumAdjustment;
   2357     } else if (-kMaxOffsetForMediumAdjustment <= src.offset() &&
   2358                src.offset() < 0) {
   2359       daddiu(scratch, src.rm(), -kMinOffsetForMediumAdjustment / 2);
   2360       daddiu(scratch, scratch, -kMinOffsetForMediumAdjustment / 2);
   2361       src.offset_ += kMinOffsetForMediumAdjustment;
   2362     } else {
   2363       // Now that all shorter options have been exhausted, load the full 32-bit
   2364       // offset.
   2365       int32_t loaded_offset = RoundDown(src.offset(), kDoubleSize);
   2366       lui(scratch, (loaded_offset >> kLuiShift) & kImm16Mask);
   2367       ori(scratch, scratch, loaded_offset & kImm16Mask);  // Load 32-bit offset.
   2368       daddu(scratch, scratch, src.rm());
   2369       src.offset_ -= loaded_offset;
   2370     }
   2371   }
   2372   src.rm_ = scratch;
   2373 
   2374   DCHECK(is_int16(src.offset()));
   2375   if (two_accesses) {
   2376     DCHECK(is_int16(
   2377         static_cast<int32_t>(src.offset() + second_access_add_to_offset)));
   2378   }
   2379   DCHECK(misalignment == (src.offset() & (kDoubleSize - 1)));
   2380 }
   2381 
   2382 void Assembler::lb(Register rd, const MemOperand& rs) {
   2383   GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
   2384 }
   2385 
   2386 
   2387 void Assembler::lbu(Register rd, const MemOperand& rs) {
   2388   GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
   2389 }
   2390 
   2391 
   2392 void Assembler::lh(Register rd, const MemOperand& rs) {
   2393   GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
   2394 }
   2395 
   2396 
   2397 void Assembler::lhu(Register rd, const MemOperand& rs) {
   2398   GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
   2399 }
   2400 
   2401 
   2402 void Assembler::lw(Register rd, const MemOperand& rs) {
   2403   GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
   2404 }
   2405 
   2406 
   2407 void Assembler::lwu(Register rd, const MemOperand& rs) {
   2408   GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
   2409 }
   2410 
   2411 
   2412 void Assembler::lwl(Register rd, const MemOperand& rs) {
   2413   DCHECK(is_int16(rs.offset_));
   2414   DCHECK_EQ(kArchVariant, kMips64r2);
   2415   GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
   2416 }
   2417 
   2418 
   2419 void Assembler::lwr(Register rd, const MemOperand& rs) {
   2420   DCHECK(is_int16(rs.offset_));
   2421   DCHECK_EQ(kArchVariant, kMips64r2);
   2422   GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
   2423 }
   2424 
   2425 
   2426 void Assembler::sb(Register rd, const MemOperand& rs) {
   2427   GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
   2428 }
   2429 
   2430 
   2431 void Assembler::sh(Register rd, const MemOperand& rs) {
   2432   GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
   2433 }
   2434 
   2435 
   2436 void Assembler::sw(Register rd, const MemOperand& rs) {
   2437   GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
   2438 }
   2439 
   2440 
   2441 void Assembler::swl(Register rd, const MemOperand& rs) {
   2442   DCHECK(is_int16(rs.offset_));
   2443   DCHECK_EQ(kArchVariant, kMips64r2);
   2444   GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
   2445 }
   2446 
   2447 
   2448 void Assembler::swr(Register rd, const MemOperand& rs) {
   2449   DCHECK(is_int16(rs.offset_));
   2450   DCHECK_EQ(kArchVariant, kMips64r2);
   2451   GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
   2452 }
   2453 
   2454 void Assembler::ll(Register rd, const MemOperand& rs) {
   2455   if (kArchVariant == kMips64r6) {
   2456     DCHECK(is_int9(rs.offset_));
   2457     GenInstrImmediate(SPECIAL3, rs.rm(), rd, rs.offset_, 0, LL_R6);
   2458   } else {
   2459     DCHECK_EQ(kArchVariant, kMips64r2);
   2460     DCHECK(is_int16(rs.offset_));
   2461     GenInstrImmediate(LL, rs.rm(), rd, rs.offset_);
   2462   }
   2463 }
   2464 
   2465 void Assembler::lld(Register rd, const MemOperand& rs) {
   2466   if (kArchVariant == kMips64r6) {
   2467     DCHECK(is_int9(rs.offset_));
   2468     GenInstrImmediate(SPECIAL3, rs.rm(), rd, rs.offset_, 0, LLD_R6);
   2469   } else {
   2470     DCHECK_EQ(kArchVariant, kMips64r2);
   2471     DCHECK(is_int16(rs.offset_));
   2472     GenInstrImmediate(LLD, rs.rm(), rd, rs.offset_);
   2473   }
   2474 }
   2475 
   2476 void Assembler::sc(Register rd, const MemOperand& rs) {
   2477   if (kArchVariant == kMips64r6) {
   2478     DCHECK(is_int9(rs.offset_));
   2479     GenInstrImmediate(SPECIAL3, rs.rm(), rd, rs.offset_, 0, SC_R6);
   2480   } else {
   2481     DCHECK_EQ(kArchVariant, kMips64r2);
   2482     GenInstrImmediate(SC, rs.rm(), rd, rs.offset_);
   2483   }
   2484 }
   2485 
   2486 void Assembler::scd(Register rd, const MemOperand& rs) {
   2487   if (kArchVariant == kMips64r6) {
   2488     DCHECK(is_int9(rs.offset_));
   2489     GenInstrImmediate(SPECIAL3, rs.rm(), rd, rs.offset_, 0, SCD_R6);
   2490   } else {
   2491     DCHECK_EQ(kArchVariant, kMips64r2);
   2492     GenInstrImmediate(SCD, rs.rm(), rd, rs.offset_);
   2493   }
   2494 }
   2495 
   2496 void Assembler::lui(Register rd, int32_t j) {
   2497   DCHECK(is_uint16(j) || is_int16(j));
   2498   GenInstrImmediate(LUI, zero_reg, rd, j);
   2499 }
   2500 
   2501 
   2502 void Assembler::aui(Register rt, Register rs, int32_t j) {
   2503   // This instruction uses same opcode as 'lui'. The difference in encoding is
   2504   // 'lui' has zero reg. for rs field.
   2505   DCHECK(is_uint16(j));
   2506   GenInstrImmediate(LUI, rs, rt, j);
   2507 }
   2508 
   2509 
   2510 void Assembler::daui(Register rt, Register rs, int32_t j) {
   2511   DCHECK(is_uint16(j));
   2512   DCHECK(rs != zero_reg);
   2513   GenInstrImmediate(DAUI, rs, rt, j);
   2514 }
   2515 
   2516 
   2517 void Assembler::dahi(Register rs, int32_t j) {
   2518   DCHECK(is_uint16(j));
   2519   GenInstrImmediate(REGIMM, rs, DAHI, j);
   2520 }
   2521 
   2522 
   2523 void Assembler::dati(Register rs, int32_t j) {
   2524   DCHECK(is_uint16(j));
   2525   GenInstrImmediate(REGIMM, rs, DATI, j);
   2526 }
   2527 
   2528 
   2529 void Assembler::ldl(Register rd, const MemOperand& rs) {
   2530   DCHECK(is_int16(rs.offset_));
   2531   DCHECK_EQ(kArchVariant, kMips64r2);
   2532   GenInstrImmediate(LDL, rs.rm(), rd, rs.offset_);
   2533 }
   2534 
   2535 
   2536 void Assembler::ldr(Register rd, const MemOperand& rs) {
   2537   DCHECK(is_int16(rs.offset_));
   2538   DCHECK_EQ(kArchVariant, kMips64r2);
   2539   GenInstrImmediate(LDR, rs.rm(), rd, rs.offset_);
   2540 }
   2541 
   2542 
   2543 void Assembler::sdl(Register rd, const MemOperand& rs) {
   2544   DCHECK(is_int16(rs.offset_));
   2545   DCHECK_EQ(kArchVariant, kMips64r2);
   2546   GenInstrImmediate(SDL, rs.rm(), rd, rs.offset_);
   2547 }
   2548 
   2549 
   2550 void Assembler::sdr(Register rd, const MemOperand& rs) {
   2551   DCHECK(is_int16(rs.offset_));
   2552   DCHECK_EQ(kArchVariant, kMips64r2);
   2553   GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
   2554 }
   2555 
   2556 
   2557 void Assembler::ld(Register rd, const MemOperand& rs) {
   2558   GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
   2559 }
   2560 
   2561 
   2562 void Assembler::sd(Register rd, const MemOperand& rs) {
   2563   GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
   2564 }
   2565 
   2566 
   2567 // ---------PC-Relative instructions-----------
   2568 
   2569 void Assembler::addiupc(Register rs, int32_t imm19) {
   2570   DCHECK_EQ(kArchVariant, kMips64r6);
   2571   DCHECK(rs.is_valid() && is_int19(imm19));
   2572   uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
   2573   GenInstrImmediate(PCREL, rs, imm21);
   2574 }
   2575 
   2576 
   2577 void Assembler::lwpc(Register rs, int32_t offset19) {
   2578   DCHECK_EQ(kArchVariant, kMips64r6);
   2579   DCHECK(rs.is_valid() && is_int19(offset19));
   2580   uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
   2581   GenInstrImmediate(PCREL, rs, imm21);
   2582 }
   2583 
   2584 
   2585 void Assembler::lwupc(Register rs, int32_t offset19) {
   2586   DCHECK_EQ(kArchVariant, kMips64r6);
   2587   DCHECK(rs.is_valid() && is_int19(offset19));
   2588   uint32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
   2589   GenInstrImmediate(PCREL, rs, imm21);
   2590 }
   2591 
   2592 
   2593 void Assembler::ldpc(Register rs, int32_t offset18) {
   2594   DCHECK_EQ(kArchVariant, kMips64r6);
   2595   DCHECK(rs.is_valid() && is_int18(offset18));
   2596   uint32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
   2597   GenInstrImmediate(PCREL, rs, imm21);
   2598 }
   2599 
   2600 
   2601 void Assembler::auipc(Register rs, int16_t imm16) {
   2602   DCHECK_EQ(kArchVariant, kMips64r6);
   2603   DCHECK(rs.is_valid());
   2604   uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
   2605   GenInstrImmediate(PCREL, rs, imm21);
   2606 }
   2607 
   2608 
   2609 void Assembler::aluipc(Register rs, int16_t imm16) {
   2610   DCHECK_EQ(kArchVariant, kMips64r6);
   2611   DCHECK(rs.is_valid());
   2612   uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
   2613   GenInstrImmediate(PCREL, rs, imm21);
   2614 }
   2615 
   2616 
   2617 // -------------Misc-instructions--------------
   2618 
   2619 // Break / Trap instructions.
   2620 void Assembler::break_(uint32_t code, bool break_as_stop) {
   2621   DCHECK_EQ(code & ~0xFFFFF, 0);
   2622   // We need to invalidate breaks that could be stops as well because the
   2623   // simulator expects a char pointer after the stop instruction.
   2624   // See constants-mips.h for explanation.
   2625   DCHECK((break_as_stop &&
   2626           code <= kMaxStopCode &&
   2627           code > kMaxWatchpointCode) ||
   2628          (!break_as_stop &&
   2629           (code > kMaxStopCode ||
   2630            code <= kMaxWatchpointCode)));
   2631   Instr break_instr = SPECIAL | BREAK | (code << 6);
   2632   emit(break_instr);
   2633 }
   2634 
   2635 
   2636 void Assembler::stop(const char* msg, uint32_t code) {
   2637   DCHECK_GT(code, kMaxWatchpointCode);
   2638   DCHECK_LE(code, kMaxStopCode);
   2639 #if defined(V8_HOST_ARCH_MIPS) || defined(V8_HOST_ARCH_MIPS64)
   2640   break_(0x54321);
   2641 #else  // V8_HOST_ARCH_MIPS
   2642   break_(code, true);
   2643 #endif
   2644 }
   2645 
   2646 
   2647 void Assembler::tge(Register rs, Register rt, uint16_t code) {
   2648   DCHECK(is_uint10(code));
   2649   Instr instr = SPECIAL | TGE | rs.code() << kRsShift
   2650       | rt.code() << kRtShift | code << 6;
   2651   emit(instr);
   2652 }
   2653 
   2654 
   2655 void Assembler::tgeu(Register rs, Register rt, uint16_t code) {
   2656   DCHECK(is_uint10(code));
   2657   Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
   2658       | rt.code() << kRtShift | code << 6;
   2659   emit(instr);
   2660 }
   2661 
   2662 
   2663 void Assembler::tlt(Register rs, Register rt, uint16_t code) {
   2664   DCHECK(is_uint10(code));
   2665   Instr instr =
   2666       SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2667   emit(instr);
   2668 }
   2669 
   2670 
   2671 void Assembler::tltu(Register rs, Register rt, uint16_t code) {
   2672   DCHECK(is_uint10(code));
   2673   Instr instr =
   2674       SPECIAL | TLTU | rs.code() << kRsShift
   2675       | rt.code() << kRtShift | code << 6;
   2676   emit(instr);
   2677 }
   2678 
   2679 
   2680 void Assembler::teq(Register rs, Register rt, uint16_t code) {
   2681   DCHECK(is_uint10(code));
   2682   Instr instr =
   2683       SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2684   emit(instr);
   2685 }
   2686 
   2687 
   2688 void Assembler::tne(Register rs, Register rt, uint16_t code) {
   2689   DCHECK(is_uint10(code));
   2690   Instr instr =
   2691       SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
   2692   emit(instr);
   2693 }
   2694 
   2695 void Assembler::sync() {
   2696   Instr sync_instr = SPECIAL | SYNC;
   2697   emit(sync_instr);
   2698 }
   2699 
   2700 // Move from HI/LO register.
   2701 
   2702 void Assembler::mfhi(Register rd) {
   2703   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
   2704 }
   2705 
   2706 
   2707 void Assembler::mflo(Register rd) {
   2708   GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
   2709 }
   2710 
   2711 
   2712 // Set on less than instructions.
   2713 void Assembler::slt(Register rd, Register rs, Register rt) {
   2714   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
   2715 }
   2716 
   2717 
   2718 void Assembler::sltu(Register rd, Register rs, Register rt) {
   2719   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
   2720 }
   2721 
   2722 
   2723 void Assembler::slti(Register rt, Register rs, int32_t j) {
   2724   GenInstrImmediate(SLTI, rs, rt, j);
   2725 }
   2726 
   2727 
   2728 void Assembler::sltiu(Register rt, Register rs, int32_t j) {
   2729   GenInstrImmediate(SLTIU, rs, rt, j);
   2730 }
   2731 
   2732 
   2733 // Conditional move.
   2734 void Assembler::movz(Register rd, Register rs, Register rt) {
   2735   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
   2736 }
   2737 
   2738 
   2739 void Assembler::movn(Register rd, Register rs, Register rt) {
   2740   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
   2741 }
   2742 
   2743 
   2744 void Assembler::movt(Register rd, Register rs, uint16_t cc) {
   2745   Register rt = Register::from_code((cc & 0x0007) << 2 | 1);
   2746   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
   2747 }
   2748 
   2749 
   2750 void Assembler::movf(Register rd, Register rs, uint16_t cc) {
   2751   Register rt = Register::from_code((cc & 0x0007) << 2 | 0);
   2752   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
   2753 }
   2754 
   2755 
   2756 void Assembler::min_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2757   min(S, fd, fs, ft);
   2758 }
   2759 
   2760 
   2761 void Assembler::min_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2762   min(D, fd, fs, ft);
   2763 }
   2764 
   2765 
   2766 void Assembler::max_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2767   max(S, fd, fs, ft);
   2768 }
   2769 
   2770 
   2771 void Assembler::max_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2772   max(D, fd, fs, ft);
   2773 }
   2774 
   2775 
   2776 void Assembler::mina_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2777   mina(S, fd, fs, ft);
   2778 }
   2779 
   2780 
   2781 void Assembler::mina_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2782   mina(D, fd, fs, ft);
   2783 }
   2784 
   2785 
   2786 void Assembler::maxa_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   2787   maxa(S, fd, fs, ft);
   2788 }
   2789 
   2790 
   2791 void Assembler::maxa_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   2792   maxa(D, fd, fs, ft);
   2793 }
   2794 
   2795 
   2796 void Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2797                     FPURegister ft) {
   2798   DCHECK_EQ(kArchVariant, kMips64r6);
   2799   DCHECK((fmt == D) || (fmt == S));
   2800   GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
   2801 }
   2802 
   2803 
   2804 void Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister fs,
   2805                     FPURegister ft) {
   2806   DCHECK_EQ(kArchVariant, kMips64r6);
   2807   DCHECK((fmt == D) || (fmt == S));
   2808   GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
   2809 }
   2810 
   2811 
   2812 // GPR.
   2813 void Assembler::seleqz(Register rd, Register rs, Register rt) {
   2814   DCHECK_EQ(kArchVariant, kMips64r6);
   2815   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
   2816 }
   2817 
   2818 
   2819 // GPR.
   2820 void Assembler::selnez(Register rd, Register rs, Register rt) {
   2821   DCHECK_EQ(kArchVariant, kMips64r6);
   2822   GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
   2823 }
   2824 
   2825 
   2826 // Bit twiddling.
   2827 void Assembler::clz(Register rd, Register rs) {
   2828   if (kArchVariant != kMips64r6) {
   2829     // clz instr requires same GPR number in 'rd' and 'rt' fields.
   2830     GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
   2831   } else {
   2832     GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
   2833   }
   2834 }
   2835 
   2836 
   2837 void Assembler::dclz(Register rd, Register rs) {
   2838   if (kArchVariant != kMips64r6) {
   2839     // dclz instr requires same GPR number in 'rd' and 'rt' fields.
   2840     GenInstrRegister(SPECIAL2, rs, rd, rd, 0, DCLZ);
   2841   } else {
   2842     GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, DCLZ_R6);
   2843   }
   2844 }
   2845 
   2846 
   2847 void Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2848   // Should be called via MacroAssembler::Ins.
   2849   // ins instr has 'rt' field as dest, and two uint5: msb, lsb.
   2850   DCHECK((kArchVariant == kMips64r2) || (kArchVariant == kMips64r6));
   2851   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
   2852 }
   2853 
   2854 
   2855 void Assembler::dins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2856   // Should be called via MacroAssembler::Dins.
   2857   // dins instr has 'rt' field as dest, and two uint5: msb, lsb.
   2858   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2859   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, DINS);
   2860 }
   2861 
   2862 void Assembler::dinsm_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2863   // Should be called via MacroAssembler::Dins.
   2864   // dinsm instr has 'rt' field as dest, and two uint5: msbminus32, lsb.
   2865   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2866   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1 - 32, pos, DINSM);
   2867 }
   2868 
   2869 void Assembler::dinsu_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2870   // Should be called via MacroAssembler::Dins.
   2871   // dinsu instr has 'rt' field as dest, and two uint5: msbminus32, lsbminus32.
   2872   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2873   GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1 - 32, pos - 32, DINSU);
   2874 }
   2875 
   2876 void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2877   // Should be called via MacroAssembler::Ext.
   2878   // ext instr has 'rt' field as dest, and two uint5: msbd, lsb.
   2879   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2880   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
   2881 }
   2882 
   2883 
   2884 void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2885   // Should be called via MacroAssembler::Dext.
   2886   // dext instr has 'rt' field as dest, and two uint5: msbd, lsb.
   2887   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2888   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
   2889 }
   2890 
   2891 void Assembler::dextm_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2892   // Should be called via MacroAssembler::Dextm.
   2893   // dextm instr has 'rt' field as dest, and two uint5: msbdminus32, lsb.
   2894   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2895   GenInstrRegister(SPECIAL3, rs, rt, size - 1 - 32, pos, DEXTM);
   2896 }
   2897 
   2898 void Assembler::dextu_(Register rt, Register rs, uint16_t pos, uint16_t size) {
   2899   // Should be called via MacroAssembler::Dextu.
   2900   // dextu instr has 'rt' field as dest, and two uint5: msbd, lsbminus32.
   2901   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2902   GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos - 32, DEXTU);
   2903 }
   2904 
   2905 
   2906 void Assembler::bitswap(Register rd, Register rt) {
   2907   DCHECK_EQ(kArchVariant, kMips64r6);
   2908   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
   2909 }
   2910 
   2911 
   2912 void Assembler::dbitswap(Register rd, Register rt) {
   2913   DCHECK_EQ(kArchVariant, kMips64r6);
   2914   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
   2915 }
   2916 
   2917 
   2918 void Assembler::pref(int32_t hint, const MemOperand& rs) {
   2919   DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
   2920   Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
   2921       | (rs.offset_);
   2922   emit(instr);
   2923 }
   2924 
   2925 
   2926 void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
   2927   DCHECK_EQ(kArchVariant, kMips64r6);
   2928   DCHECK(is_uint3(bp));
   2929   uint16_t sa = (ALIGN << kBp2Bits) | bp;
   2930   GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
   2931 }
   2932 
   2933 
   2934 void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
   2935   DCHECK_EQ(kArchVariant, kMips64r6);
   2936   DCHECK(is_uint3(bp));
   2937   uint16_t sa = (DALIGN << kBp3Bits) | bp;
   2938   GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
   2939 }
   2940 
   2941 void Assembler::wsbh(Register rd, Register rt) {
   2942   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2943   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, WSBH, BSHFL);
   2944 }
   2945 
   2946 void Assembler::dsbh(Register rd, Register rt) {
   2947   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2948   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSBH, DBSHFL);
   2949 }
   2950 
   2951 void Assembler::dshd(Register rd, Register rt) {
   2952   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2953   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSHD, DBSHFL);
   2954 }
   2955 
   2956 void Assembler::seh(Register rd, Register rt) {
   2957   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2958   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEH, BSHFL);
   2959 }
   2960 
   2961 void Assembler::seb(Register rd, Register rt) {
   2962   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   2963   GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL);
   2964 }
   2965 
   2966 // --------Coprocessor-instructions----------------
   2967 
   2968 // Load, store, move.
   2969 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
   2970   GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
   2971 }
   2972 
   2973 
   2974 void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
   2975   GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
   2976 }
   2977 
   2978 void Assembler::swc1(FPURegister fs, const MemOperand& src) {
   2979   GenInstrImmediate(SWC1, src.rm(), fs, src.offset_);
   2980 }
   2981 
   2982 void Assembler::sdc1(FPURegister fs, const MemOperand& src) {
   2983   GenInstrImmediate(SDC1, src.rm(), fs, src.offset_);
   2984 }
   2985 
   2986 
   2987 void Assembler::mtc1(Register rt, FPURegister fs) {
   2988   GenInstrRegister(COP1, MTC1, rt, fs, f0);
   2989 }
   2990 
   2991 
   2992 void Assembler::mthc1(Register rt, FPURegister fs) {
   2993   GenInstrRegister(COP1, MTHC1, rt, fs, f0);
   2994 }
   2995 
   2996 
   2997 void Assembler::dmtc1(Register rt, FPURegister fs) {
   2998   GenInstrRegister(COP1, DMTC1, rt, fs, f0);
   2999 }
   3000 
   3001 
   3002 void Assembler::mfc1(Register rt, FPURegister fs) {
   3003   GenInstrRegister(COP1, MFC1, rt, fs, f0);
   3004 }
   3005 
   3006 
   3007 void Assembler::mfhc1(Register rt, FPURegister fs) {
   3008   GenInstrRegister(COP1, MFHC1, rt, fs, f0);
   3009 }
   3010 
   3011 
   3012 void Assembler::dmfc1(Register rt, FPURegister fs) {
   3013   GenInstrRegister(COP1, DMFC1, rt, fs, f0);
   3014 }
   3015 
   3016 
   3017 void Assembler::ctc1(Register rt, FPUControlRegister fs) {
   3018   GenInstrRegister(COP1, CTC1, rt, fs);
   3019 }
   3020 
   3021 
   3022 void Assembler::cfc1(Register rt, FPUControlRegister fs) {
   3023   GenInstrRegister(COP1, CFC1, rt, fs);
   3024 }
   3025 
   3026 
   3027 void Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3028                     FPURegister ft) {
   3029   DCHECK_EQ(kArchVariant, kMips64r6);
   3030   DCHECK((fmt == D) || (fmt == S));
   3031 
   3032   GenInstrRegister(COP1, fmt, ft, fs, fd, SEL);
   3033 }
   3034 
   3035 
   3036 void Assembler::sel_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3037   sel(S, fd, fs, ft);
   3038 }
   3039 
   3040 
   3041 void Assembler::sel_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3042   sel(D, fd, fs, ft);
   3043 }
   3044 
   3045 
   3046 // FPR.
   3047 void Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3048                        FPURegister ft) {
   3049   DCHECK((fmt == D) || (fmt == S));
   3050   GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
   3051 }
   3052 
   3053 
   3054 void Assembler::seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3055   seleqz(D, fd, fs, ft);
   3056 }
   3057 
   3058 
   3059 void Assembler::seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3060   seleqz(S, fd, fs, ft);
   3061 }
   3062 
   3063 
   3064 void Assembler::selnez_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3065   selnez(D, fd, fs, ft);
   3066 }
   3067 
   3068 
   3069 void Assembler::selnez_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3070   selnez(S, fd, fs, ft);
   3071 }
   3072 
   3073 
   3074 void Assembler::movz_s(FPURegister fd, FPURegister fs, Register rt) {
   3075   DCHECK_EQ(kArchVariant, kMips64r2);
   3076   GenInstrRegister(COP1, S, rt, fs, fd, MOVZ_C);
   3077 }
   3078 
   3079 
   3080 void Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
   3081   DCHECK_EQ(kArchVariant, kMips64r2);
   3082   GenInstrRegister(COP1, D, rt, fs, fd, MOVZ_C);
   3083 }
   3084 
   3085 
   3086 void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   3087   DCHECK_EQ(kArchVariant, kMips64r2);
   3088   FPURegister ft = FPURegister::from_code((cc & 0x0007) << 2 | 1);
   3089   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
   3090 }
   3091 
   3092 
   3093 void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   3094   DCHECK_EQ(kArchVariant, kMips64r2);
   3095   FPURegister ft = FPURegister::from_code((cc & 0x0007) << 2 | 1);
   3096   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
   3097 }
   3098 
   3099 
   3100 void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   3101   DCHECK_EQ(kArchVariant, kMips64r2);
   3102   FPURegister ft = FPURegister::from_code((cc & 0x0007) << 2 | 0);
   3103   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
   3104 }
   3105 
   3106 
   3107 void Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   3108   DCHECK_EQ(kArchVariant, kMips64r2);
   3109   FPURegister ft = FPURegister::from_code((cc & 0x0007) << 2 | 0);
   3110   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
   3111 }
   3112 
   3113 
   3114 void Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) {
   3115   DCHECK_EQ(kArchVariant, kMips64r2);
   3116   GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C);
   3117 }
   3118 
   3119 
   3120 void Assembler::movn_d(FPURegister fd, FPURegister fs, Register rt) {
   3121   DCHECK_EQ(kArchVariant, kMips64r2);
   3122   GenInstrRegister(COP1, D, rt, fs, fd, MOVN_C);
   3123 }
   3124 
   3125 
   3126 // FPR.
   3127 void Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3128                        FPURegister ft) {
   3129   DCHECK_EQ(kArchVariant, kMips64r6);
   3130   DCHECK((fmt == D) || (fmt == S));
   3131   GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
   3132 }
   3133 
   3134 
   3135 // Arithmetic.
   3136 
   3137 void Assembler::add_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3138   GenInstrRegister(COP1, S, ft, fs, fd, ADD_D);
   3139 }
   3140 
   3141 
   3142 void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3143   GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
   3144 }
   3145 
   3146 
   3147 void Assembler::sub_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3148   GenInstrRegister(COP1, S, ft, fs, fd, SUB_D);
   3149 }
   3150 
   3151 
   3152 void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3153   GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
   3154 }
   3155 
   3156 
   3157 void Assembler::mul_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3158   GenInstrRegister(COP1, S, ft, fs, fd, MUL_D);
   3159 }
   3160 
   3161 
   3162 void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3163   GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
   3164 }
   3165 
   3166 void Assembler::madd_s(FPURegister fd, FPURegister fr, FPURegister fs,
   3167                        FPURegister ft) {
   3168   // On Loongson 3A (MIPS64R2), MADD.S instruction is actually fused MADD.S and
   3169   // this causes failure in some of the tests. Since this optimization is rarely
   3170   // used, and not used at all on MIPS64R6, this isntruction is removed.
   3171   UNREACHABLE();
   3172 }
   3173 
   3174 void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
   3175     FPURegister ft) {
   3176   // On Loongson 3A (MIPS64R2), MADD.D instruction is actually fused MADD.D and
   3177   // this causes failure in some of the tests. Since this optimization is rarely
   3178   // used, and not used at all on MIPS64R6, this isntruction is removed.
   3179   UNREACHABLE();
   3180 }
   3181 
   3182 void Assembler::msub_s(FPURegister fd, FPURegister fr, FPURegister fs,
   3183                        FPURegister ft) {
   3184   // See explanation for instruction madd_s.
   3185   UNREACHABLE();
   3186 }
   3187 
   3188 void Assembler::msub_d(FPURegister fd, FPURegister fr, FPURegister fs,
   3189                        FPURegister ft) {
   3190   // See explanation for instruction madd_d.
   3191   UNREACHABLE();
   3192 }
   3193 
   3194 void Assembler::maddf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3195   DCHECK_EQ(kArchVariant, kMips64r6);
   3196   GenInstrRegister(COP1, S, ft, fs, fd, MADDF_S);
   3197 }
   3198 
   3199 void Assembler::maddf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3200   DCHECK_EQ(kArchVariant, kMips64r6);
   3201   GenInstrRegister(COP1, D, ft, fs, fd, MADDF_D);
   3202 }
   3203 
   3204 void Assembler::msubf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3205   DCHECK_EQ(kArchVariant, kMips64r6);
   3206   GenInstrRegister(COP1, S, ft, fs, fd, MSUBF_S);
   3207 }
   3208 
   3209 void Assembler::msubf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3210   DCHECK_EQ(kArchVariant, kMips64r6);
   3211   GenInstrRegister(COP1, D, ft, fs, fd, MSUBF_D);
   3212 }
   3213 
   3214 void Assembler::div_s(FPURegister fd, FPURegister fs, FPURegister ft) {
   3215   GenInstrRegister(COP1, S, ft, fs, fd, DIV_D);
   3216 }
   3217 
   3218 
   3219 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
   3220   GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
   3221 }
   3222 
   3223 
   3224 void Assembler::abs_s(FPURegister fd, FPURegister fs) {
   3225   GenInstrRegister(COP1, S, f0, fs, fd, ABS_D);
   3226 }
   3227 
   3228 
   3229 void Assembler::abs_d(FPURegister fd, FPURegister fs) {
   3230   GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
   3231 }
   3232 
   3233 
   3234 void Assembler::mov_d(FPURegister fd, FPURegister fs) {
   3235   GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
   3236 }
   3237 
   3238 
   3239 void Assembler::mov_s(FPURegister fd, FPURegister fs) {
   3240   GenInstrRegister(COP1, S, f0, fs, fd, MOV_S);
   3241 }
   3242 
   3243 
   3244 void Assembler::neg_s(FPURegister fd, FPURegister fs) {
   3245   GenInstrRegister(COP1, S, f0, fs, fd, NEG_D);
   3246 }
   3247 
   3248 
   3249 void Assembler::neg_d(FPURegister fd, FPURegister fs) {
   3250   GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
   3251 }
   3252 
   3253 
   3254 void Assembler::sqrt_s(FPURegister fd, FPURegister fs) {
   3255   GenInstrRegister(COP1, S, f0, fs, fd, SQRT_D);
   3256 }
   3257 
   3258 
   3259 void Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
   3260   GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
   3261 }
   3262 
   3263 
   3264 void Assembler::rsqrt_s(FPURegister fd, FPURegister fs) {
   3265   GenInstrRegister(COP1, S, f0, fs, fd, RSQRT_S);
   3266 }
   3267 
   3268 
   3269 void Assembler::rsqrt_d(FPURegister fd, FPURegister fs) {
   3270   GenInstrRegister(COP1, D, f0, fs, fd, RSQRT_D);
   3271 }
   3272 
   3273 
   3274 void Assembler::recip_d(FPURegister fd, FPURegister fs) {
   3275   GenInstrRegister(COP1, D, f0, fs, fd, RECIP_D);
   3276 }
   3277 
   3278 
   3279 void Assembler::recip_s(FPURegister fd, FPURegister fs) {
   3280   GenInstrRegister(COP1, S, f0, fs, fd, RECIP_S);
   3281 }
   3282 
   3283 
   3284 // Conversions.
   3285 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
   3286   GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
   3287 }
   3288 
   3289 
   3290 void Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
   3291   GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
   3292 }
   3293 
   3294 
   3295 void Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
   3296   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
   3297 }
   3298 
   3299 
   3300 void Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
   3301   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
   3302 }
   3303 
   3304 
   3305 void Assembler::round_w_s(FPURegister fd, FPURegister fs) {
   3306   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
   3307 }
   3308 
   3309 
   3310 void Assembler::round_w_d(FPURegister fd, FPURegister fs) {
   3311   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
   3312 }
   3313 
   3314 
   3315 void Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
   3316   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
   3317 }
   3318 
   3319 
   3320 void Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
   3321   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
   3322 }
   3323 
   3324 
   3325 void Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
   3326   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
   3327 }
   3328 
   3329 
   3330 void Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
   3331   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
   3332 }
   3333 
   3334 
   3335 void Assembler::rint_s(FPURegister fd, FPURegister fs) { rint(S, fd, fs); }
   3336 
   3337 
   3338 void Assembler::rint_d(FPURegister fd, FPURegister fs) { rint(D, fd, fs); }
   3339 
   3340 
   3341 void Assembler::rint(SecondaryField fmt, FPURegister fd, FPURegister fs) {
   3342   DCHECK_EQ(kArchVariant, kMips64r6);
   3343   GenInstrRegister(COP1, fmt, f0, fs, fd, RINT);
   3344 }
   3345 
   3346 
   3347 void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
   3348   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3349   GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
   3350 }
   3351 
   3352 
   3353 void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
   3354   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3355   GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
   3356 }
   3357 
   3358 
   3359 void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
   3360   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3361   GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
   3362 }
   3363 
   3364 
   3365 void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
   3366   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3367   GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
   3368 }
   3369 
   3370 
   3371 void Assembler::round_l_s(FPURegister fd, FPURegister fs) {
   3372   GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
   3373 }
   3374 
   3375 
   3376 void Assembler::round_l_d(FPURegister fd, FPURegister fs) {
   3377   GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
   3378 }
   3379 
   3380 
   3381 void Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
   3382   GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
   3383 }
   3384 
   3385 
   3386 void Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
   3387   GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
   3388 }
   3389 
   3390 
   3391 void Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
   3392   GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
   3393 }
   3394 
   3395 
   3396 void Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
   3397   GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
   3398 }
   3399 
   3400 
   3401 void Assembler::class_s(FPURegister fd, FPURegister fs) {
   3402   DCHECK_EQ(kArchVariant, kMips64r6);
   3403   GenInstrRegister(COP1, S, f0, fs, fd, CLASS_S);
   3404 }
   3405 
   3406 
   3407 void Assembler::class_d(FPURegister fd, FPURegister fs) {
   3408   DCHECK_EQ(kArchVariant, kMips64r6);
   3409   GenInstrRegister(COP1, D, f0, fs, fd, CLASS_D);
   3410 }
   3411 
   3412 
   3413 void Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3414                      FPURegister ft) {
   3415   DCHECK_EQ(kArchVariant, kMips64r6);
   3416   DCHECK((fmt == D) || (fmt == S));
   3417   GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
   3418 }
   3419 
   3420 
   3421 void Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister fs,
   3422                      FPURegister ft) {
   3423   DCHECK_EQ(kArchVariant, kMips64r6);
   3424   DCHECK((fmt == D) || (fmt == S));
   3425   GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
   3426 }
   3427 
   3428 
   3429 void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
   3430   GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
   3431 }
   3432 
   3433 
   3434 void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
   3435   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3436   GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
   3437 }
   3438 
   3439 
   3440 void Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
   3441   GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
   3442 }
   3443 
   3444 
   3445 void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
   3446   GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
   3447 }
   3448 
   3449 
   3450 void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
   3451   DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
   3452   GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
   3453 }
   3454 
   3455 
   3456 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
   3457   GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
   3458 }
   3459 
   3460 
   3461 // Conditions for >= MIPSr6.
   3462 void Assembler::cmp(FPUCondition cond, SecondaryField fmt,
   3463     FPURegister fd, FPURegister fs, FPURegister ft) {
   3464   DCHECK_EQ(kArchVariant, kMips64r6);
   3465   DCHECK_EQ(fmt & ~(31 << kRsShift), 0);
   3466   Instr instr = COP1 | fmt | ft.code() << kFtShift |
   3467       fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
   3468   emit(instr);
   3469 }
   3470 
   3471 
   3472 void Assembler::cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs,
   3473                       FPURegister ft) {
   3474   cmp(cond, W, fd, fs, ft);
   3475 }
   3476 
   3477 void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
   3478                       FPURegister ft) {
   3479   cmp(cond, L, fd, fs, ft);
   3480 }
   3481 
   3482 
   3483 void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
   3484   DCHECK_EQ(kArchVariant, kMips64r6);
   3485   BlockTrampolinePoolScope block_trampoline_pool(this);
   3486   Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
   3487   emit(instr);
   3488   BlockTrampolinePoolFor(1);  // For associated delay slot.
   3489 }
   3490 
   3491 
   3492 void Assembler::bc1nez(int16_t offset, FPURegister ft) {
   3493   DCHECK_EQ(kArchVariant, kMips64r6);
   3494   BlockTrampolinePoolScope block_trampoline_pool(this);
   3495   Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
   3496   emit(instr);
   3497   BlockTrampolinePoolFor(1);  // For associated delay slot.
   3498 }
   3499 
   3500 
   3501 // Conditions for < MIPSr6.
   3502 void Assembler::c(FPUCondition cond, SecondaryField fmt,
   3503     FPURegister fs, FPURegister ft, uint16_t cc) {
   3504   DCHECK_NE(kArchVariant, kMips64r6);
   3505   DCHECK(is_uint3(cc));
   3506   DCHECK(fmt == S || fmt == D);
   3507   DCHECK_EQ(fmt & ~(31 << kRsShift), 0);
   3508   Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
   3509       | cc << 8 | 3 << 4 | cond;
   3510   emit(instr);
   3511 }
   3512 
   3513 
   3514 void Assembler::c_s(FPUCondition cond, FPURegister fs, FPURegister ft,
   3515                     uint16_t cc) {
   3516   c(cond, S, fs, ft, cc);
   3517 }
   3518 
   3519 
   3520 void Assembler::c_d(FPUCondition cond, FPURegister fs, FPURegister ft,
   3521                     uint16_t cc) {
   3522   c(cond, D, fs, ft, cc);
   3523 }
   3524 
   3525 
   3526 void Assembler::fcmp(FPURegister src1, const double src2,
   3527       FPUCondition cond) {
   3528   DCHECK_EQ(src2, 0.0);
   3529   mtc1(zero_reg, f14);
   3530   cvt_d_w(f14, f14);
   3531   c(cond, D, src1, f14, 0);
   3532 }
   3533 
   3534 
   3535 void Assembler::bc1f(int16_t offset, uint16_t cc) {
   3536   BlockTrampolinePoolScope block_trampoline_pool(this);
   3537   DCHECK(is_uint3(cc));
   3538   Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
   3539   emit(instr);
   3540   BlockTrampolinePoolFor(1);  // For associated delay slot.
   3541 }
   3542 
   3543 
   3544 void Assembler::bc1t(int16_t offset, uint16_t cc) {
   3545   BlockTrampolinePoolScope block_trampoline_pool(this);
   3546   DCHECK(is_uint3(cc));
   3547   Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
   3548   emit(instr);
   3549   BlockTrampolinePoolFor(1);  // For associated delay slot.
   3550 }
   3551 
   3552 // ---------- MSA instructions ------------
   3553 #define MSA_BRANCH_LIST(V) \
   3554   V(bz_v, BZ_V)            \
   3555   V(bz_b, BZ_B)            \
   3556   V(bz_h, BZ_H)            \
   3557   V(bz_w, BZ_W)            \
   3558   V(bz_d, BZ_D)            \
   3559   V(bnz_v, BNZ_V)          \
   3560   V(bnz_b, BNZ_B)          \
   3561   V(bnz_h, BNZ_H)          \
   3562   V(bnz_w, BNZ_W)          \
   3563   V(bnz_d, BNZ_D)
   3564 
   3565 #define MSA_BRANCH(name, opcode)                         \
   3566   void Assembler::name(MSARegister wt, int16_t offset) { \
   3567     GenInstrMsaBranch(opcode, wt, offset);               \
   3568   }
   3569 
   3570 MSA_BRANCH_LIST(MSA_BRANCH)
   3571 #undef MSA_BRANCH
   3572 #undef MSA_BRANCH_LIST
   3573 
   3574 #define MSA_LD_ST_LIST(V) \
   3575   V(ld_b, LD_B)           \
   3576   V(ld_h, LD_H)           \
   3577   V(ld_w, LD_W)           \
   3578   V(ld_d, LD_D)           \
   3579   V(st_b, ST_B)           \
   3580   V(st_h, ST_H)           \
   3581   V(st_w, ST_W)           \
   3582   V(st_d, ST_D)
   3583 
   3584 #define MSA_LD_ST(name, opcode)                                  \
   3585   void Assembler::name(MSARegister wd, const MemOperand& rs) {   \
   3586     MemOperand source = rs;                                      \
   3587     AdjustBaseAndOffset(source);                                 \
   3588     if (is_int10(source.offset())) {                             \
   3589       GenInstrMsaMI10(opcode, source.offset(), source.rm(), wd); \
   3590     } else {                                                     \
   3591       UseScratchRegisterScope temps(this);                       \
   3592       Register scratch = temps.Acquire();                        \
   3593       DCHECK(rs.rm() != scratch);                                \
   3594       daddiu(scratch, source.rm(), source.offset());             \
   3595       GenInstrMsaMI10(opcode, 0, scratch, wd);                   \
   3596     }                                                            \
   3597   }
   3598 
   3599 MSA_LD_ST_LIST(MSA_LD_ST)
   3600 #undef MSA_LD_ST
   3601 #undef MSA_BRANCH_LIST
   3602 
   3603 #define MSA_I10_LIST(V) \
   3604   V(ldi_b, I5_DF_b)     \
   3605   V(ldi_h, I5_DF_h)     \
   3606   V(ldi_w, I5_DF_w)     \
   3607   V(ldi_d, I5_DF_d)
   3608 
   3609 #define MSA_I10(name, format)                           \
   3610   void Assembler::name(MSARegister wd, int32_t imm10) { \
   3611     GenInstrMsaI10(LDI, format, imm10, wd);             \
   3612   }
   3613 MSA_I10_LIST(MSA_I10)
   3614 #undef MSA_I10
   3615 #undef MSA_I10_LIST
   3616 
   3617 #define MSA_I5_LIST(V) \
   3618   V(addvi, ADDVI)      \
   3619   V(subvi, SUBVI)      \
   3620   V(maxi_s, MAXI_S)    \
   3621   V(maxi_u, MAXI_U)    \
   3622   V(mini_s, MINI_S)    \
   3623   V(mini_u, MINI_U)    \
   3624   V(ceqi, CEQI)        \
   3625   V(clti_s, CLTI_S)    \
   3626   V(clti_u, CLTI_U)    \
   3627   V(clei_s, CLEI_S)    \
   3628   V(clei_u, CLEI_U)
   3629 
   3630 #define MSA_I5_FORMAT(name, opcode, format)                       \
   3631   void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
   3632                                   uint32_t imm5) {                \
   3633     GenInstrMsaI5(opcode, I5_DF_##format, imm5, ws, wd);          \
   3634   }
   3635 
   3636 #define MSA_I5(name, opcode)     \
   3637   MSA_I5_FORMAT(name, opcode, b) \
   3638   MSA_I5_FORMAT(name, opcode, h) \
   3639   MSA_I5_FORMAT(name, opcode, w) \
   3640   MSA_I5_FORMAT(name, opcode, d)
   3641 
   3642 MSA_I5_LIST(MSA_I5)
   3643 #undef MSA_I5
   3644 #undef MSA_I5_FORMAT
   3645 #undef MSA_I5_LIST
   3646 
   3647 #define MSA_I8_LIST(V) \
   3648   V(andi_b, ANDI_B)    \
   3649   V(ori_b, ORI_B)      \
   3650   V(nori_b, NORI_B)    \
   3651   V(xori_b, XORI_B)    \
   3652   V(bmnzi_b, BMNZI_B)  \
   3653   V(bmzi_b, BMZI_B)    \
   3654   V(bseli_b, BSELI_B)  \
   3655   V(shf_b, SHF_B)      \
   3656   V(shf_h, SHF_H)      \
   3657   V(shf_w, SHF_W)
   3658 
   3659 #define MSA_I8(name, opcode)                                            \
   3660   void Assembler::name(MSARegister wd, MSARegister ws, uint32_t imm8) { \
   3661     GenInstrMsaI8(opcode, imm8, ws, wd);                                \
   3662   }
   3663 
   3664 MSA_I8_LIST(MSA_I8)
   3665 #undef MSA_I8
   3666 #undef MSA_I8_LIST
   3667 
   3668 #define MSA_VEC_LIST(V) \
   3669   V(and_v, AND_V)       \
   3670   V(or_v, OR_V)         \
   3671   V(nor_v, NOR_V)       \
   3672   V(xor_v, XOR_V)       \
   3673   V(bmnz_v, BMNZ_V)     \
   3674   V(bmz_v, BMZ_V)       \
   3675   V(bsel_v, BSEL_V)
   3676 
   3677 #define MSA_VEC(name, opcode)                                            \
   3678   void Assembler::name(MSARegister wd, MSARegister ws, MSARegister wt) { \
   3679     GenInstrMsaVec(opcode, wt, ws, wd);                                  \
   3680   }
   3681 
   3682 MSA_VEC_LIST(MSA_VEC)
   3683 #undef MSA_VEC
   3684 #undef MSA_VEC_LIST
   3685 
   3686 #define MSA_2R_LIST(V) \
   3687   V(pcnt, PCNT)        \
   3688   V(nloc, NLOC)        \
   3689   V(nlzc, NLZC)
   3690 
   3691 #define MSA_2R_FORMAT(name, opcode, format)                         \
   3692   void Assembler::name##_##format(MSARegister wd, MSARegister ws) { \
   3693     GenInstrMsa2R(opcode, MSA_2R_DF_##format, ws, wd);              \
   3694   }
   3695 
   3696 #define MSA_2R(name, opcode)     \
   3697   MSA_2R_FORMAT(name, opcode, b) \
   3698   MSA_2R_FORMAT(name, opcode, h) \
   3699   MSA_2R_FORMAT(name, opcode, w) \
   3700   MSA_2R_FORMAT(name, opcode, d)
   3701 
   3702 MSA_2R_LIST(MSA_2R)
   3703 #undef MSA_2R
   3704 #undef MSA_2R_FORMAT
   3705 #undef MSA_2R_LIST
   3706 
   3707 #define MSA_FILL(format)                                              \
   3708   void Assembler::fill_##format(MSARegister wd, Register rs) {        \
   3709     DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));      \
   3710     DCHECK(rs.is_valid() && wd.is_valid());                           \
   3711     Instr instr = MSA | MSA_2R_FORMAT | FILL | MSA_2R_DF_##format |   \
   3712                   (rs.code() << kWsShift) | (wd.code() << kWdShift) | \
   3713                   MSA_VEC_2R_2RF_MINOR;                               \
   3714     emit(instr);                                                      \
   3715   }
   3716 
   3717 MSA_FILL(b)
   3718 MSA_FILL(h)
   3719 MSA_FILL(w)
   3720 MSA_FILL(d)
   3721 #undef MSA_FILL
   3722 
   3723 #define MSA_2RF_LIST(V) \
   3724   V(fclass, FCLASS)     \
   3725   V(ftrunc_s, FTRUNC_S) \
   3726   V(ftrunc_u, FTRUNC_U) \
   3727   V(fsqrt, FSQRT)       \
   3728   V(frsqrt, FRSQRT)     \
   3729   V(frcp, FRCP)         \
   3730   V(frint, FRINT)       \
   3731   V(flog2, FLOG2)       \
   3732   V(fexupl, FEXUPL)     \
   3733   V(fexupr, FEXUPR)     \
   3734   V(ffql, FFQL)         \
   3735   V(ffqr, FFQR)         \
   3736   V(ftint_s, FTINT_S)   \
   3737   V(ftint_u, FTINT_U)   \
   3738   V(ffint_s, FFINT_S)   \
   3739   V(ffint_u, FFINT_U)
   3740 
   3741 #define MSA_2RF_FORMAT(name, opcode, format)                        \
   3742   void Assembler::name##_##format(MSARegister wd, MSARegister ws) { \
   3743     GenInstrMsa2RF(opcode, MSA_2RF_DF_##format, ws, wd);            \
   3744   }
   3745 
   3746 #define MSA_2RF(name, opcode)     \
   3747   MSA_2RF_FORMAT(name, opcode, w) \
   3748   MSA_2RF_FORMAT(name, opcode, d)
   3749 
   3750 MSA_2RF_LIST(MSA_2RF)
   3751 #undef MSA_2RF
   3752 #undef MSA_2RF_FORMAT
   3753 #undef MSA_2RF_LIST
   3754 
   3755 #define MSA_3R_LIST(V)  \
   3756   V(sll, SLL_MSA)       \
   3757   V(sra, SRA_MSA)       \
   3758   V(srl, SRL_MSA)       \
   3759   V(bclr, BCLR)         \
   3760   V(bset, BSET)         \
   3761   V(bneg, BNEG)         \
   3762   V(binsl, BINSL)       \
   3763   V(binsr, BINSR)       \
   3764   V(addv, ADDV)         \
   3765   V(subv, SUBV)         \
   3766   V(max_s, MAX_S)       \
   3767   V(max_u, MAX_U)       \
   3768   V(min_s, MIN_S)       \
   3769   V(min_u, MIN_U)       \
   3770   V(max_a, MAX_A)       \
   3771   V(min_a, MIN_A)       \
   3772   V(ceq, CEQ)           \
   3773   V(clt_s, CLT_S)       \
   3774   V(clt_u, CLT_U)       \
   3775   V(cle_s, CLE_S)       \
   3776   V(cle_u, CLE_U)       \
   3777   V(add_a, ADD_A)       \
   3778   V(adds_a, ADDS_A)     \
   3779   V(adds_s, ADDS_S)     \
   3780   V(adds_u, ADDS_U)     \
   3781   V(ave_s, AVE_S)       \
   3782   V(ave_u, AVE_U)       \
   3783   V(aver_s, AVER_S)     \
   3784   V(aver_u, AVER_U)     \
   3785   V(subs_s, SUBS_S)     \
   3786   V(subs_u, SUBS_U)     \
   3787   V(subsus_u, SUBSUS_U) \
   3788   V(subsuu_s, SUBSUU_S) \
   3789   V(asub_s, ASUB_S)     \
   3790   V(asub_u, ASUB_U)     \
   3791   V(mulv, MULV)         \
   3792   V(maddv, MADDV)       \
   3793   V(msubv, MSUBV)       \
   3794   V(div_s, DIV_S_MSA)   \
   3795   V(div_u, DIV_U)       \
   3796   V(mod_s, MOD_S)       \
   3797   V(mod_u, MOD_U)       \
   3798   V(dotp_s, DOTP_S)     \
   3799   V(dotp_u, DOTP_U)     \
   3800   V(dpadd_s, DPADD_S)   \
   3801   V(dpadd_u, DPADD_U)   \
   3802   V(dpsub_s, DPSUB_S)   \
   3803   V(dpsub_u, DPSUB_U)   \
   3804   V(pckev, PCKEV)       \
   3805   V(pckod, PCKOD)       \
   3806   V(ilvl, ILVL)         \
   3807   V(ilvr, ILVR)         \
   3808   V(ilvev, ILVEV)       \
   3809   V(ilvod, ILVOD)       \
   3810   V(vshf, VSHF)         \
   3811   V(srar, SRAR)         \
   3812   V(srlr, SRLR)         \
   3813   V(hadd_s, HADD_S)     \
   3814   V(hadd_u, HADD_U)     \
   3815   V(hsub_s, HSUB_S)     \
   3816   V(hsub_u, HSUB_U)
   3817 
   3818 #define MSA_3R_FORMAT(name, opcode, format)                             \
   3819   void Assembler::name##_##format(MSARegister wd, MSARegister ws,       \
   3820                                   MSARegister wt) {                     \
   3821     GenInstrMsa3R<MSARegister>(opcode, MSA_3R_DF_##format, wt, ws, wd); \
   3822   }
   3823 
   3824 #define MSA_3R_FORMAT_SLD_SPLAT(name, opcode, format)                \
   3825   void Assembler::name##_##format(MSARegister wd, MSARegister ws,    \
   3826                                   Register rt) {                     \
   3827     GenInstrMsa3R<Register>(opcode, MSA_3R_DF_##format, rt, ws, wd); \
   3828   }
   3829 
   3830 #define MSA_3R(name, opcode)     \
   3831   MSA_3R_FORMAT(name, opcode, b) \
   3832   MSA_3R_FORMAT(name, opcode, h) \
   3833   MSA_3R_FORMAT(name, opcode, w) \
   3834   MSA_3R_FORMAT(name, opcode, d)
   3835 
   3836 #define MSA_3R_SLD_SPLAT(name, opcode)     \
   3837   MSA_3R_FORMAT_SLD_SPLAT(name, opcode, b) \
   3838   MSA_3R_FORMAT_SLD_SPLAT(name, opcode, h) \
   3839   MSA_3R_FORMAT_SLD_SPLAT(name, opcode, w) \
   3840   MSA_3R_FORMAT_SLD_SPLAT(name, opcode, d)
   3841 
   3842 MSA_3R_LIST(MSA_3R)
   3843 MSA_3R_SLD_SPLAT(sld, SLD)
   3844 MSA_3R_SLD_SPLAT(splat, SPLAT)
   3845 
   3846 #undef MSA_3R
   3847 #undef MSA_3R_FORMAT
   3848 #undef MSA_3R_FORMAT_SLD_SPLAT
   3849 #undef MSA_3R_SLD_SPLAT
   3850 #undef MSA_3R_LIST
   3851 
   3852 #define MSA_3RF_LIST1(V) \
   3853   V(fcaf, FCAF)          \
   3854   V(fcun, FCUN)          \
   3855   V(fceq, FCEQ)          \
   3856   V(fcueq, FCUEQ)        \
   3857   V(fclt, FCLT)          \
   3858   V(fcult, FCULT)        \
   3859   V(fcle, FCLE)          \
   3860   V(fcule, FCULE)        \
   3861   V(fsaf, FSAF)          \
   3862   V(fsun, FSUN)          \
   3863   V(fseq, FSEQ)          \
   3864   V(fsueq, FSUEQ)        \
   3865   V(fslt, FSLT)          \
   3866   V(fsult, FSULT)        \
   3867   V(fsle, FSLE)          \
   3868   V(fsule, FSULE)        \
   3869   V(fadd, FADD)          \
   3870   V(fsub, FSUB)          \
   3871   V(fmul, FMUL)          \
   3872   V(fdiv, FDIV)          \
   3873   V(fmadd, FMADD)        \
   3874   V(fmsub, FMSUB)        \
   3875   V(fexp2, FEXP2)        \
   3876   V(fmin, FMIN)          \
   3877   V(fmin_a, FMIN_A)      \
   3878   V(fmax, FMAX)          \
   3879   V(fmax_a, FMAX_A)      \
   3880   V(fcor, FCOR)          \
   3881   V(fcune, FCUNE)        \
   3882   V(fcne, FCNE)          \
   3883   V(fsor, FSOR)          \
   3884   V(fsune, FSUNE)        \
   3885   V(fsne, FSNE)
   3886 
   3887 #define MSA_3RF_LIST2(V) \
   3888   V(fexdo, FEXDO)        \
   3889   V(ftq, FTQ)            \
   3890   V(mul_q, MUL_Q)        \
   3891   V(madd_q, MADD_Q)      \
   3892   V(msub_q, MSUB_Q)      \
   3893   V(mulr_q, MULR_Q)      \
   3894   V(maddr_q, MADDR_Q)    \
   3895   V(msubr_q, MSUBR_Q)
   3896 
   3897 #define MSA_3RF_FORMAT(name, opcode, df, df_c)                \
   3898   void Assembler::name##_##df(MSARegister wd, MSARegister ws, \
   3899                               MSARegister wt) {               \
   3900     GenInstrMsa3RF(opcode, df_c, wt, ws, wd);                 \
   3901   }
   3902 
   3903 #define MSA_3RF_1(name, opcode)      \
   3904   MSA_3RF_FORMAT(name, opcode, w, 0) \
   3905   MSA_3RF_FORMAT(name, opcode, d, 1)
   3906 
   3907 #define MSA_3RF_2(name, opcode)      \
   3908   MSA_3RF_FORMAT(name, opcode, h, 0) \
   3909   MSA_3RF_FORMAT(name, opcode, w, 1)
   3910 
   3911 MSA_3RF_LIST1(MSA_3RF_1)
   3912 MSA_3RF_LIST2(MSA_3RF_2)
   3913 #undef MSA_3RF_1
   3914 #undef MSA_3RF_2
   3915 #undef MSA_3RF_FORMAT
   3916 #undef MSA_3RF_LIST1
   3917 #undef MSA_3RF_LIST2
   3918 
   3919 void Assembler::sldi_b(MSARegister wd, MSARegister ws, uint32_t n) {
   3920   GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_B, n, ws, wd);
   3921 }
   3922 
   3923 void Assembler::sldi_h(MSARegister wd, MSARegister ws, uint32_t n) {
   3924   GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_H, n, ws, wd);
   3925 }
   3926 
   3927 void Assembler::sldi_w(MSARegister wd, MSARegister ws, uint32_t n) {
   3928   GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_W, n, ws, wd);
   3929 }
   3930 
   3931 void Assembler::sldi_d(MSARegister wd, MSARegister ws, uint32_t n) {
   3932   GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_D, n, ws, wd);
   3933 }
   3934 
   3935 void Assembler::splati_b(MSARegister wd, MSARegister ws, uint32_t n) {
   3936   GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_B, n, ws, wd);
   3937 }
   3938 
   3939 void Assembler::splati_h(MSARegister wd, MSARegister ws, uint32_t n) {
   3940   GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_H, n, ws, wd);
   3941 }
   3942 
   3943 void Assembler::splati_w(MSARegister wd, MSARegister ws, uint32_t n) {
   3944   GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_W, n, ws, wd);
   3945 }
   3946 
   3947 void Assembler::splati_d(MSARegister wd, MSARegister ws, uint32_t n) {
   3948   GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_D, n, ws, wd);
   3949 }
   3950 
   3951 void Assembler::copy_s_b(Register rd, MSARegister ws, uint32_t n) {
   3952   GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_B, n, ws, rd);
   3953 }
   3954 
   3955 void Assembler::copy_s_h(Register rd, MSARegister ws, uint32_t n) {
   3956   GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_H, n, ws, rd);
   3957 }
   3958 
   3959 void Assembler::copy_s_w(Register rd, MSARegister ws, uint32_t n) {
   3960   GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_W, n, ws, rd);
   3961 }
   3962 
   3963 void Assembler::copy_s_d(Register rd, MSARegister ws, uint32_t n) {
   3964   GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_D, n, ws, rd);
   3965 }
   3966 
   3967 void Assembler::copy_u_b(Register rd, MSARegister ws, uint32_t n) {
   3968   GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_B, n, ws, rd);
   3969 }
   3970 
   3971 void Assembler::copy_u_h(Register rd, MSARegister ws, uint32_t n) {
   3972   GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_H, n, ws, rd);
   3973 }
   3974 
   3975 void Assembler::copy_u_w(Register rd, MSARegister ws, uint32_t n) {
   3976   GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_W, n, ws, rd);
   3977 }
   3978 
   3979 void Assembler::insert_b(MSARegister wd, uint32_t n, Register rs) {
   3980   GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_B, n, rs, wd);
   3981 }
   3982 
   3983 void Assembler::insert_h(MSARegister wd, uint32_t n, Register rs) {
   3984   GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_H, n, rs, wd);
   3985 }
   3986 
   3987 void Assembler::insert_w(MSARegister wd, uint32_t n, Register rs) {
   3988   GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_W, n, rs, wd);
   3989 }
   3990 
   3991 void Assembler::insert_d(MSARegister wd, uint32_t n, Register rs) {
   3992   GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_D, n, rs, wd);
   3993 }
   3994 
   3995 void Assembler::insve_b(MSARegister wd, uint32_t n, MSARegister ws) {
   3996   GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_B, n, ws, wd);
   3997 }
   3998 
   3999 void Assembler::insve_h(MSARegister wd, uint32_t n, MSARegister ws) {
   4000   GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_H, n, ws, wd);
   4001 }
   4002 
   4003 void Assembler::insve_w(MSARegister wd, uint32_t n, MSARegister ws) {
   4004   GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_W, n, ws, wd);
   4005 }
   4006 
   4007 void Assembler::insve_d(MSARegister wd, uint32_t n, MSARegister ws) {
   4008   GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_D, n, ws, wd);
   4009 }
   4010 
   4011 void Assembler::move_v(MSARegister wd, MSARegister ws) {
   4012   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   4013   DCHECK(ws.is_valid() && wd.is_valid());
   4014   Instr instr = MSA | MOVE_V | (ws.code() << kWsShift) |
   4015                 (wd.code() << kWdShift) | MSA_ELM_MINOR;
   4016   emit(instr);
   4017 }
   4018 
   4019 void Assembler::ctcmsa(MSAControlRegister cd, Register rs) {
   4020   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   4021   DCHECK(cd.is_valid() && rs.is_valid());
   4022   Instr instr = MSA | CTCMSA | (rs.code() << kWsShift) |
   4023                 (cd.code() << kWdShift) | MSA_ELM_MINOR;
   4024   emit(instr);
   4025 }
   4026 
   4027 void Assembler::cfcmsa(Register rd, MSAControlRegister cs) {
   4028   DCHECK((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD));
   4029   DCHECK(rd.is_valid() && cs.is_valid());
   4030   Instr instr = MSA | CFCMSA | (cs.code() << kWsShift) |
   4031                 (rd.code() << kWdShift) | MSA_ELM_MINOR;
   4032   emit(instr);
   4033 }
   4034 
   4035 #define MSA_BIT_LIST(V) \
   4036   V(slli, SLLI)         \
   4037   V(srai, SRAI)         \
   4038   V(srli, SRLI)         \
   4039   V(bclri, BCLRI)       \
   4040   V(bseti, BSETI)       \
   4041   V(bnegi, BNEGI)       \
   4042   V(binsli, BINSLI)     \
   4043   V(binsri, BINSRI)     \
   4044   V(sat_s, SAT_S)       \
   4045   V(sat_u, SAT_U)       \
   4046   V(srari, SRARI)       \
   4047   V(srlri, SRLRI)
   4048 
   4049 #define MSA_BIT_FORMAT(name, opcode, format)                      \
   4050   void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
   4051                                   uint32_t m) {                   \
   4052     GenInstrMsaBit(opcode, BIT_DF_##format, m, ws, wd);           \
   4053   }
   4054 
   4055 #define MSA_BIT(name, opcode)     \
   4056   MSA_BIT_FORMAT(name, opcode, b) \
   4057   MSA_BIT_FORMAT(name, opcode, h) \
   4058   MSA_BIT_FORMAT(name, opcode, w) \
   4059   MSA_BIT_FORMAT(name, opcode, d)
   4060 
   4061 MSA_BIT_LIST(MSA_BIT)
   4062 #undef MSA_BIT
   4063 #undef MSA_BIT_FORMAT
   4064 #undef MSA_BIT_LIST
   4065 
   4066 int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, Address pc,
   4067                                          intptr_t pc_delta) {
   4068   if (RelocInfo::IsInternalReference(rmode)) {
   4069     int64_t* p = reinterpret_cast<int64_t*>(pc);
   4070     if (*p == kEndOfJumpChain) {
   4071       return 0;  // Number of instructions patched.
   4072     }
   4073     *p += pc_delta;
   4074     return 2;  // Number of instructions patched.
   4075   }
   4076   Instr instr = instr_at(pc);
   4077   DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
   4078   if (IsLui(instr)) {
   4079     Instr instr_lui = instr_at(pc + 0 * kInstrSize);
   4080     Instr instr_ori = instr_at(pc + 1 * kInstrSize);
   4081     Instr instr_ori2 = instr_at(pc + 3 * kInstrSize);
   4082     DCHECK(IsOri(instr_ori));
   4083     DCHECK(IsOri(instr_ori2));
   4084     // TODO(plind): symbolic names for the shifts.
   4085     int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
   4086     imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
   4087     imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)) << 16;
   4088     // Sign extend address.
   4089     imm >>= 16;
   4090 
   4091     if (imm == kEndOfJumpChain) {
   4092       return 0;  // Number of instructions patched.
   4093     }
   4094     imm += pc_delta;
   4095     DCHECK_EQ(imm & 3, 0);
   4096 
   4097     instr_lui &= ~kImm16Mask;
   4098     instr_ori &= ~kImm16Mask;
   4099     instr_ori2 &= ~kImm16Mask;
   4100 
   4101     instr_at_put(pc + 0 * kInstrSize, instr_lui | ((imm >> 32) & kImm16Mask));
   4102     instr_at_put(pc + 1 * kInstrSize, instr_ori | (imm >> 16 & kImm16Mask));
   4103     instr_at_put(pc + 3 * kInstrSize, instr_ori2 | (imm & kImm16Mask));
   4104     return 4;  // Number of instructions patched.
   4105   } else if (IsJ(instr) || IsJal(instr)) {
   4106     // Regular j/jal relocation.
   4107     uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
   4108     imm28 += pc_delta;
   4109     imm28 &= kImm28Mask;
   4110     instr &= ~kImm26Mask;
   4111     DCHECK_EQ(imm28 & 3, 0);
   4112     uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
   4113     instr_at_put(pc, instr | (imm26 & kImm26Mask));
   4114     return 1;  // Number of instructions patched.
   4115   } else {
   4116     DCHECK(((instr & kJumpRawMask) == kJRawMark) ||
   4117            ((instr & kJumpRawMask) == kJalRawMark));
   4118     // Unbox raw offset and emit j/jal.
   4119     int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
   4120     // Sign extend 28-bit offset to 32-bit.
   4121     imm28 = (imm28 << 4) >> 4;
   4122     uint64_t target =
   4123         static_cast<int64_t>(imm28) + reinterpret_cast<uint64_t>(pc);
   4124     target &= kImm28Mask;
   4125     DCHECK_EQ(imm28 & 3, 0);
   4126     uint32_t imm26 = static_cast<uint32_t>(target >> 2);
   4127     // Check markings whether to emit j or jal.
   4128     uint32_t unbox = (instr & kJRawMark) ? J : JAL;
   4129     instr_at_put(pc, unbox | (imm26 & kImm26Mask));
   4130     return 1;  // Number of instructions patched.
   4131   }
   4132 }
   4133 
   4134 
   4135 void Assembler::GrowBuffer() {
   4136   if (!own_buffer_) FATAL("external code buffer is too small");
   4137 
   4138   // Compute new buffer size.
   4139   CodeDesc desc;  // the new buffer
   4140   if (buffer_size_ < 1 * MB) {
   4141     desc.buffer_size = 2*buffer_size_;
   4142   } else {
   4143     desc.buffer_size = buffer_size_ + 1*MB;
   4144   }
   4145 
   4146   // Some internal data structures overflow for very large buffers,
   4147   // they must ensure that kMaximalBufferSize is not too large.
   4148   if (desc.buffer_size > kMaximalBufferSize) {
   4149     V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer");
   4150   }
   4151 
   4152   // Set up new buffer.
   4153   desc.buffer = NewArray<byte>(desc.buffer_size);
   4154   desc.origin = this;
   4155 
   4156   desc.instr_size = pc_offset();
   4157   desc.reloc_size =
   4158       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
   4159 
   4160   // Copy the data.
   4161   intptr_t pc_delta = desc.buffer - buffer_;
   4162   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
   4163       (buffer_ + buffer_size_);
   4164   MemMove(desc.buffer, buffer_, desc.instr_size);
   4165   MemMove(reloc_info_writer.pos() + rc_delta,
   4166               reloc_info_writer.pos(), desc.reloc_size);
   4167 
   4168   // Switch buffers.
   4169   DeleteArray(buffer_);
   4170   buffer_ = desc.buffer;
   4171   buffer_size_ = desc.buffer_size;
   4172   pc_ += pc_delta;
   4173   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
   4174                                reloc_info_writer.last_pc() + pc_delta);
   4175 
   4176   // Relocate runtime entries.
   4177   for (RelocIterator it(desc); !it.done(); it.next()) {
   4178     RelocInfo::Mode rmode = it.rinfo()->rmode();
   4179     if (rmode == RelocInfo::INTERNAL_REFERENCE) {
   4180       RelocateInternalReference(rmode, it.rinfo()->pc(), pc_delta);
   4181     }
   4182   }
   4183   DCHECK(!overflow());
   4184 }
   4185 
   4186 
   4187 void Assembler::db(uint8_t data) {
   4188   CheckForEmitInForbiddenSlot();
   4189   EmitHelper(data);
   4190 }
   4191 
   4192 
   4193 void Assembler::dd(uint32_t data) {
   4194   CheckForEmitInForbiddenSlot();
   4195   EmitHelper(data);
   4196 }
   4197 
   4198 
   4199 void Assembler::dq(uint64_t data) {
   4200   CheckForEmitInForbiddenSlot();
   4201   EmitHelper(data);
   4202 }
   4203 
   4204 
   4205 void Assembler::dd(Label* label) {
   4206   uint64_t data;
   4207   CheckForEmitInForbiddenSlot();
   4208   if (label->is_bound()) {
   4209     data = reinterpret_cast<uint64_t>(buffer_ + label->pos());
   4210   } else {
   4211     data = jump_address(label);
   4212     unbound_labels_count_++;
   4213     internal_reference_positions_.insert(label->pos());
   4214   }
   4215   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
   4216   EmitHelper(data);
   4217 }
   4218 
   4219 
   4220 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
   4221   // We do not try to reuse pool constants.
   4222   RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr);
   4223   if (!RelocInfo::IsNone(rinfo.rmode())) {
   4224     if (options().disable_reloc_info_for_patching) return;
   4225     // Don't record external references unless the heap will be serialized.
   4226     if (RelocInfo::IsOnlyForSerializer(rmode) &&
   4227         !options().record_reloc_info_for_serialization && !emit_debug_code()) {
   4228       return;
   4229     }
   4230     DCHECK_GE(buffer_space(), kMaxRelocSize);  // Too late to grow buffer here.
   4231     reloc_info_writer.Write(&rinfo);
   4232   }
   4233 }
   4234 
   4235 
   4236 void Assembler::BlockTrampolinePoolFor(int instructions) {
   4237   CheckTrampolinePoolQuick(instructions);
   4238   BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
   4239 }
   4240 
   4241 
   4242 void Assembler::CheckTrampolinePool() {
   4243   // Some small sequences of instructions must not be broken up by the
   4244   // insertion of a trampoline pool; such sequences are protected by setting
   4245   // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
   4246   // which are both checked here. Also, recursive calls to CheckTrampolinePool
   4247   // are blocked by trampoline_pool_blocked_nesting_.
   4248   if ((trampoline_pool_blocked_nesting_ > 0) ||
   4249       (pc_offset() < no_trampoline_pool_before_)) {
   4250     // Emission is currently blocked; make sure we try again as soon as
   4251     // possible.
   4252     if (trampoline_pool_blocked_nesting_ > 0) {
   4253       next_buffer_check_ = pc_offset() + kInstrSize;
   4254     } else {
   4255       next_buffer_check_ = no_trampoline_pool_before_;
   4256     }
   4257     return;
   4258   }
   4259 
   4260   DCHECK(!trampoline_emitted_);
   4261   DCHECK_GE(unbound_labels_count_, 0);
   4262   if (unbound_labels_count_ > 0) {
   4263     // First we emit jump (2 instructions), then we emit trampoline pool.
   4264     { BlockTrampolinePoolScope block_trampoline_pool(this);
   4265       Label after_pool;
   4266       if (kArchVariant == kMips64r6) {
   4267         bc(&after_pool);
   4268       } else {
   4269         b(&after_pool);
   4270       }
   4271       nop();
   4272 
   4273       int pool_start = pc_offset();
   4274       for (int i = 0; i < unbound_labels_count_; i++) {
   4275         {
   4276           if (kArchVariant == kMips64r6) {
   4277             bc(&after_pool);
   4278             nop();
   4279           } else {
   4280             or_(t8, ra, zero_reg);
   4281             nal();       // Read PC into ra register.
   4282             lui(t9, 0);  // Branch delay slot.
   4283             ori(t9, t9, 0);
   4284             daddu(t9, ra, t9);
   4285             or_(ra, t8, zero_reg);
   4286             // Instruction jr will take or_ from the next trampoline.
   4287             // in its branch delay slot. This is the expected behavior
   4288             // in order to decrease size of trampoline pool.
   4289             jr(t9);
   4290           }
   4291         }
   4292       }
   4293       nop();
   4294       bind(&after_pool);
   4295       trampoline_ = Trampoline(pool_start, unbound_labels_count_);
   4296 
   4297       trampoline_emitted_ = true;
   4298       // As we are only going to emit trampoline once, we need to prevent any
   4299       // further emission.
   4300       next_buffer_check_ = kMaxInt;
   4301     }
   4302   } else {
   4303     // Number of branches to unbound label at this point is zero, so we can
   4304     // move next buffer check to maximum.
   4305     next_buffer_check_ = pc_offset() +
   4306         kMaxBranchOffset - kTrampolineSlotsSize * 16;
   4307   }
   4308   return;
   4309 }
   4310 
   4311 
   4312 Address Assembler::target_address_at(Address pc) {
   4313   Instr instr0 = instr_at(pc);
   4314   Instr instr1 = instr_at(pc + 1 * kInstrSize);
   4315   Instr instr3 = instr_at(pc + 3 * kInstrSize);
   4316 
   4317   // Interpret 4 instructions for address generated by li: See listing in
   4318   // Assembler::set_target_address_at() just below.
   4319   if ((GetOpcodeField(instr0) == LUI) && (GetOpcodeField(instr1) == ORI) &&
   4320       (GetOpcodeField(instr3) == ORI)) {
   4321     // Assemble the 48 bit value.
   4322      int64_t addr  = static_cast<int64_t>(
   4323           ((uint64_t)(GetImmediate16(instr0)) << 32) |
   4324           ((uint64_t)(GetImmediate16(instr1)) << 16) |
   4325           ((uint64_t)(GetImmediate16(instr3))));
   4326 
   4327     // Sign extend to get canonical address.
   4328     addr = (addr << 16) >> 16;
   4329     return static_cast<Address>(addr);
   4330   }
   4331   // We should never get here, force a bad address if we do.
   4332   UNREACHABLE();
   4333 }
   4334 
   4335 
   4336 // MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
   4337 // qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
   4338 // snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
   4339 // OS::nan_value() returns a qNaN.
   4340 void Assembler::QuietNaN(HeapObject* object) {
   4341   HeapNumber::cast(object)->set_value(std::numeric_limits<double>::quiet_NaN());
   4342 }
   4343 
   4344 
   4345 // On Mips64, a target address is stored in a 4-instruction sequence:
   4346 //    0: lui(rd, (j.imm64_ >> 32) & kImm16Mask);
   4347 //    1: ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
   4348 //    2: dsll(rd, rd, 16);
   4349 //    3: ori(rd, rd, j.imm32_ & kImm16Mask);
   4350 //
   4351 // Patching the address must replace all the lui & ori instructions,
   4352 // and flush the i-cache.
   4353 //
   4354 // There is an optimization below, which emits a nop when the address
   4355 // fits in just 16 bits. This is unlikely to help, and should be benchmarked,
   4356 // and possibly removed.
   4357 void Assembler::set_target_value_at(Address pc, uint64_t target,
   4358                                     ICacheFlushMode icache_flush_mode) {
   4359   // There is an optimization where only 4 instructions are used to load address
   4360   // in code on MIP64 because only 48-bits of address is effectively used.
   4361   // It relies on fact the upper [63:48] bits are not used for virtual address
   4362   // translation and they have to be set according to value of bit 47 in order
   4363   // get canonical address.
   4364   Instr instr1 = instr_at(pc + kInstrSize);
   4365   uint32_t rt_code = GetRt(instr1);
   4366   uint32_t* p = reinterpret_cast<uint32_t*>(pc);
   4367 
   4368 #ifdef DEBUG
   4369   // Check we have the result from a li macro-instruction.
   4370   Instr instr0 = instr_at(pc);
   4371   Instr instr3 = instr_at(pc + kInstrSize * 3);
   4372   DCHECK((GetOpcodeField(instr0) == LUI && GetOpcodeField(instr1) == ORI &&
   4373           GetOpcodeField(instr3) == ORI));
   4374 #endif
   4375 
   4376   // Must use 4 instructions to insure patchable code.
   4377   // lui rt, upper-16.
   4378   // ori rt, rt, lower-16.
   4379   // dsll rt, rt, 16.
   4380   // ori rt rt, lower-16.
   4381   *p = LUI | (rt_code << kRtShift) | ((target >> 32) & kImm16Mask);
   4382   *(p + 1) = ORI | (rt_code << kRtShift) | (rt_code << kRsShift) |
   4383              ((target >> 16) & kImm16Mask);
   4384   *(p + 3) = ORI | (rt_code << kRsShift) | (rt_code << kRtShift) |
   4385              (target & kImm16Mask);
   4386 
   4387   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
   4388     Assembler::FlushICache(pc, 4 * kInstrSize);
   4389   }
   4390 }
   4391 
   4392 UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler)
   4393     : available_(assembler->GetScratchRegisterList()),
   4394       old_available_(*available_) {}
   4395 
   4396 UseScratchRegisterScope::~UseScratchRegisterScope() {
   4397   *available_ = old_available_;
   4398 }
   4399 
   4400 Register UseScratchRegisterScope::Acquire() {
   4401   DCHECK_NOT_NULL(available_);
   4402   DCHECK_NE(*available_, 0);
   4403   int index = static_cast<int>(base::bits::CountTrailingZeros32(*available_));
   4404   *available_ &= ~(1UL << index);
   4405 
   4406   return Register::from_code(index);
   4407 }
   4408 
   4409 bool UseScratchRegisterScope::hasAvailable() const { return *available_ != 0; }
   4410 
   4411 }  // namespace internal
   4412 }  // namespace v8
   4413 
   4414 #endif  // V8_TARGET_ARCH_MIPS64
   4415