11cb0ef41Sopenharmony_ci
21cb0ef41Sopenharmony_ci// Copyright (c) 1994-2006 Sun Microsystems Inc.
31cb0ef41Sopenharmony_ci// All Rights Reserved.
41cb0ef41Sopenharmony_ci//
51cb0ef41Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
61cb0ef41Sopenharmony_ci// modification, are permitted provided that the following conditions are
71cb0ef41Sopenharmony_ci// met:
81cb0ef41Sopenharmony_ci//
91cb0ef41Sopenharmony_ci// - Redistributions of source code must retain the above copyright notice,
101cb0ef41Sopenharmony_ci// this list of conditions and the following disclaimer.
111cb0ef41Sopenharmony_ci//
121cb0ef41Sopenharmony_ci// - Redistribution in binary form must reproduce the above copyright
131cb0ef41Sopenharmony_ci// notice, this list of conditions and the following disclaimer in the
141cb0ef41Sopenharmony_ci// documentation and/or other materials provided with the distribution.
151cb0ef41Sopenharmony_ci//
161cb0ef41Sopenharmony_ci// - Neither the name of Sun Microsystems or the names of contributors may
171cb0ef41Sopenharmony_ci// be used to endorse or promote products derived from this software without
181cb0ef41Sopenharmony_ci// specific prior written permission.
191cb0ef41Sopenharmony_ci//
201cb0ef41Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
211cb0ef41Sopenharmony_ci// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
221cb0ef41Sopenharmony_ci// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
231cb0ef41Sopenharmony_ci// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
241cb0ef41Sopenharmony_ci// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
251cb0ef41Sopenharmony_ci// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
261cb0ef41Sopenharmony_ci// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
271cb0ef41Sopenharmony_ci// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
281cb0ef41Sopenharmony_ci// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
291cb0ef41Sopenharmony_ci// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
301cb0ef41Sopenharmony_ci// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// The original source code covered by the above license above has been
331cb0ef41Sopenharmony_ci// modified significantly by Google Inc.
341cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_MIPS_ASSEMBLER_MIPS_INL_H_
371cb0ef41Sopenharmony_ci#define V8_CODEGEN_MIPS_ASSEMBLER_MIPS_INL_H_
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci#include "src/codegen/mips/assembler-mips.h"
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h"
421cb0ef41Sopenharmony_ci#include "src/debug/debug.h"
431cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_cinamespace v8 {
461cb0ef41Sopenharmony_cinamespace internal {
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cibool CpuFeatures::SupportsOptimizer() { return IsSupported(FPU); }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
511cb0ef41Sopenharmony_ci// Operand and MemOperand.
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_cibool Operand::is_reg() const { return rm_.is_valid(); }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ciint32_t Operand::immediate() const {
561cb0ef41Sopenharmony_ci  DCHECK(!is_reg());
571cb0ef41Sopenharmony_ci  DCHECK(!IsHeapObjectRequest());
581cb0ef41Sopenharmony_ci  return value_.immediate;
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
621cb0ef41Sopenharmony_ci// RelocInfo.
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_civoid RelocInfo::apply(intptr_t delta) {
651cb0ef41Sopenharmony_ci  if (IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)) {
661cb0ef41Sopenharmony_ci    // Absolute code pointer inside code object moves with the code object.
671cb0ef41Sopenharmony_ci    Assembler::RelocateInternalReference(rmode_, pc_, delta);
681cb0ef41Sopenharmony_ci  } else if (IsRelativeCodeTarget(rmode_)) {
691cb0ef41Sopenharmony_ci    Assembler::RelocateRelativeReference(rmode_, pc_, delta);
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciAddress RelocInfo::target_address() {
741cb0ef41Sopenharmony_ci  DCHECK(IsCodeTargetMode(rmode_) || IsRuntimeEntry(rmode_) ||
751cb0ef41Sopenharmony_ci         IsWasmCall(rmode_));
761cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciAddress RelocInfo::target_address_address() {
801cb0ef41Sopenharmony_ci  DCHECK(HasTargetAddressAddress());
811cb0ef41Sopenharmony_ci  // Read the address of the word containing the target_address in an
821cb0ef41Sopenharmony_ci  // instruction stream.
831cb0ef41Sopenharmony_ci  // The only architecture-independent user of this function is the serializer.
841cb0ef41Sopenharmony_ci  // The serializer uses it to find out how many raw bytes of instruction to
851cb0ef41Sopenharmony_ci  // output before the next target.
861cb0ef41Sopenharmony_ci  // For an instruction like LUI/ORI where the target bits are mixed into the
871cb0ef41Sopenharmony_ci  // instruction bits, the size of the target will be zero, indicating that the
881cb0ef41Sopenharmony_ci  // serializer should not step forward in memory after a target is resolved
891cb0ef41Sopenharmony_ci  // and written. In this case the target_address_address function should
901cb0ef41Sopenharmony_ci  // return the end of the instructions to be patched, allowing the
911cb0ef41Sopenharmony_ci  // deserializer to deserialize the instructions as raw bytes and put them in
921cb0ef41Sopenharmony_ci  // place, ready to be patched with the target. After jump optimization,
931cb0ef41Sopenharmony_ci  // that is the address of the instruction that follows J/JAL/JR/JALR
941cb0ef41Sopenharmony_ci  // instruction.
951cb0ef41Sopenharmony_ci  if (IsMipsArchVariant(kMips32r6)) {
961cb0ef41Sopenharmony_ci    // On R6 we don't move to the end of the instructions to be patched, but one
971cb0ef41Sopenharmony_ci    // instruction before, because if these instructions are at the end of the
981cb0ef41Sopenharmony_ci    // code object it can cause errors in the deserializer.
991cb0ef41Sopenharmony_ci    return pc_ + (Assembler::kInstructionsFor32BitConstant - 1) * kInstrSize;
1001cb0ef41Sopenharmony_ci  } else {
1011cb0ef41Sopenharmony_ci    return pc_ + Assembler::kInstructionsFor32BitConstant * kInstrSize;
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ciAddress RelocInfo::constant_pool_entry_address() { UNREACHABLE(); }
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ciint RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_civoid Assembler::deserialization_set_special_target_at(
1101cb0ef41Sopenharmony_ci    Address instruction_payload, Code code, Address target) {
1111cb0ef41Sopenharmony_ci  set_target_address_at(instruction_payload,
1121cb0ef41Sopenharmony_ci                        !code.is_null() ? code.constant_pool() : kNullAddress,
1131cb0ef41Sopenharmony_ci                        target);
1141cb0ef41Sopenharmony_ci}
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciint Assembler::deserialization_special_target_size(
1171cb0ef41Sopenharmony_ci    Address instruction_payload) {
1181cb0ef41Sopenharmony_ci  return kSpecialTargetSize;
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_civoid Assembler::set_target_internal_reference_encoded_at(Address pc,
1221cb0ef41Sopenharmony_ci                                                         Address target) {
1231cb0ef41Sopenharmony_ci  Instr instr1 = Assembler::instr_at(pc + 0 * kInstrSize);
1241cb0ef41Sopenharmony_ci  Instr instr2 = Assembler::instr_at(pc + 1 * kInstrSize);
1251cb0ef41Sopenharmony_ci  DCHECK(Assembler::IsLui(instr1));
1261cb0ef41Sopenharmony_ci  DCHECK(Assembler::IsOri(instr2) || Assembler::IsJicOrJialc(instr2));
1271cb0ef41Sopenharmony_ci  instr1 &= ~kImm16Mask;
1281cb0ef41Sopenharmony_ci  instr2 &= ~kImm16Mask;
1291cb0ef41Sopenharmony_ci  int32_t imm = static_cast<int32_t>(target);
1301cb0ef41Sopenharmony_ci  DCHECK_EQ(imm & 3, 0);
1311cb0ef41Sopenharmony_ci  if (Assembler::IsJicOrJialc(instr2)) {
1321cb0ef41Sopenharmony_ci    // Encoded internal references are lui/jic load of 32-bit absolute address.
1331cb0ef41Sopenharmony_ci    uint32_t lui_offset_u, jic_offset_u;
1341cb0ef41Sopenharmony_ci    Assembler::UnpackTargetAddressUnsigned(imm, &lui_offset_u, &jic_offset_u);
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci    Assembler::instr_at_put(pc + 0 * kInstrSize, instr1 | lui_offset_u);
1371cb0ef41Sopenharmony_ci    Assembler::instr_at_put(pc + 1 * kInstrSize, instr2 | jic_offset_u);
1381cb0ef41Sopenharmony_ci  } else {
1391cb0ef41Sopenharmony_ci    // Encoded internal references are lui/ori load of 32-bit absolute address.
1401cb0ef41Sopenharmony_ci    PatchLuiOriImmediate(pc, imm, instr1, 0 * kInstrSize, instr2,
1411cb0ef41Sopenharmony_ci                         1 * kInstrSize);
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  // Currently used only by deserializer, and all code will be flushed
1451cb0ef41Sopenharmony_ci  // after complete deserialization, no need to flush on each reference.
1461cb0ef41Sopenharmony_ci}
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_civoid Assembler::deserialization_set_target_internal_reference_at(
1491cb0ef41Sopenharmony_ci    Address pc, Address target, RelocInfo::Mode mode) {
1501cb0ef41Sopenharmony_ci  if (RelocInfo::IsInternalReferenceEncoded(mode)) {
1511cb0ef41Sopenharmony_ci    DCHECK(IsLui(instr_at(pc)));
1521cb0ef41Sopenharmony_ci    set_target_internal_reference_encoded_at(pc, target);
1531cb0ef41Sopenharmony_ci  } else {
1541cb0ef41Sopenharmony_ci    DCHECK(RelocInfo::IsInternalReference(mode));
1551cb0ef41Sopenharmony_ci    Memory<Address>(pc) = target;
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ciHeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
1601cb0ef41Sopenharmony_ci  DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_) ||
1611cb0ef41Sopenharmony_ci         IsDataEmbeddedObject(rmode_));
1621cb0ef41Sopenharmony_ci  if (IsDataEmbeddedObject(rmode_)) {
1631cb0ef41Sopenharmony_ci    return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci  return HeapObject::cast(
1661cb0ef41Sopenharmony_ci      Object(Assembler::target_address_at(pc_, constant_pool_)));
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ciHandle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
1701cb0ef41Sopenharmony_ci  if (IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_)) {
1711cb0ef41Sopenharmony_ci    return Handle<HeapObject>(reinterpret_cast<Address*>(
1721cb0ef41Sopenharmony_ci        Assembler::target_address_at(pc_, constant_pool_)));
1731cb0ef41Sopenharmony_ci  } else if (IsDataEmbeddedObject(rmode_)) {
1741cb0ef41Sopenharmony_ci    return Handle<HeapObject>::cast(ReadUnalignedValue<Handle<Object>>(pc_));
1751cb0ef41Sopenharmony_ci  }
1761cb0ef41Sopenharmony_ci  DCHECK(IsRelativeCodeTarget(rmode_));
1771cb0ef41Sopenharmony_ci  return origin->relative_code_target_object_handle_at(pc_);
1781cb0ef41Sopenharmony_ci}
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_civoid RelocInfo::set_target_object(Heap* heap, HeapObject target,
1811cb0ef41Sopenharmony_ci                                  WriteBarrierMode write_barrier_mode,
1821cb0ef41Sopenharmony_ci                                  ICacheFlushMode icache_flush_mode) {
1831cb0ef41Sopenharmony_ci  DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_) ||
1841cb0ef41Sopenharmony_ci         IsDataEmbeddedObject(rmode_));
1851cb0ef41Sopenharmony_ci  if (IsDataEmbeddedObject(rmode_)) {
1861cb0ef41Sopenharmony_ci    WriteUnalignedValue(pc_, target.ptr());
1871cb0ef41Sopenharmony_ci    // No need to flush icache since no instructions were changed.
1881cb0ef41Sopenharmony_ci  } else {
1891cb0ef41Sopenharmony_ci    Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
1901cb0ef41Sopenharmony_ci                                     icache_flush_mode);
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci  if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
1931cb0ef41Sopenharmony_ci      !FLAG_disable_write_barriers) {
1941cb0ef41Sopenharmony_ci    WriteBarrierForCode(host(), this, target);
1951cb0ef41Sopenharmony_ci  }
1961cb0ef41Sopenharmony_ci}
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ciAddress RelocInfo::target_external_reference() {
1991cb0ef41Sopenharmony_ci  DCHECK(IsExternalReference(rmode_));
2001cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
2011cb0ef41Sopenharmony_ci}
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_civoid RelocInfo::set_target_external_reference(
2041cb0ef41Sopenharmony_ci    Address target, ICacheFlushMode icache_flush_mode) {
2051cb0ef41Sopenharmony_ci  DCHECK(IsExternalReference(rmode_));
2061cb0ef41Sopenharmony_ci  Assembler::set_target_address_at(pc_, constant_pool_, target,
2071cb0ef41Sopenharmony_ci                                   icache_flush_mode);
2081cb0ef41Sopenharmony_ci}
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ciAddress RelocInfo::target_internal_reference() {
2111cb0ef41Sopenharmony_ci  if (IsInternalReference(rmode_)) {
2121cb0ef41Sopenharmony_ci    return Memory<Address>(pc_);
2131cb0ef41Sopenharmony_ci  } else {
2141cb0ef41Sopenharmony_ci    // Encoded internal references are lui/ori or lui/jic load of 32-bit
2151cb0ef41Sopenharmony_ci    // absolute address.
2161cb0ef41Sopenharmony_ci    DCHECK(IsInternalReferenceEncoded(rmode_));
2171cb0ef41Sopenharmony_ci    Instr instr1 = Assembler::instr_at(pc_ + 0 * kInstrSize);
2181cb0ef41Sopenharmony_ci    Instr instr2 = Assembler::instr_at(pc_ + 1 * kInstrSize);
2191cb0ef41Sopenharmony_ci    DCHECK(Assembler::IsLui(instr1));
2201cb0ef41Sopenharmony_ci    DCHECK(Assembler::IsOri(instr2) || Assembler::IsJicOrJialc(instr2));
2211cb0ef41Sopenharmony_ci    if (Assembler::IsJicOrJialc(instr2)) {
2221cb0ef41Sopenharmony_ci      return static_cast<Address>(
2231cb0ef41Sopenharmony_ci          Assembler::CreateTargetAddress(instr1, instr2));
2241cb0ef41Sopenharmony_ci    }
2251cb0ef41Sopenharmony_ci    return static_cast<Address>(Assembler::GetLuiOriImmediate(instr1, instr2));
2261cb0ef41Sopenharmony_ci  }
2271cb0ef41Sopenharmony_ci}
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ciAddress RelocInfo::target_internal_reference_address() {
2301cb0ef41Sopenharmony_ci  DCHECK(IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_));
2311cb0ef41Sopenharmony_ci  return pc_;
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ciAddress RelocInfo::target_runtime_entry(Assembler* origin) {
2351cb0ef41Sopenharmony_ci  DCHECK(IsRuntimeEntry(rmode_));
2361cb0ef41Sopenharmony_ci  return target_address();
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_civoid RelocInfo::set_target_runtime_entry(Address target,
2401cb0ef41Sopenharmony_ci                                         WriteBarrierMode write_barrier_mode,
2411cb0ef41Sopenharmony_ci                                         ICacheFlushMode icache_flush_mode) {
2421cb0ef41Sopenharmony_ci  DCHECK(IsRuntimeEntry(rmode_));
2431cb0ef41Sopenharmony_ci  if (target_address() != target)
2441cb0ef41Sopenharmony_ci    set_target_address(target, write_barrier_mode, icache_flush_mode);
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ciAddress RelocInfo::target_off_heap_target() {
2481cb0ef41Sopenharmony_ci  DCHECK(IsOffHeapTarget(rmode_));
2491cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
2501cb0ef41Sopenharmony_ci}
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_civoid RelocInfo::WipeOut() {
2531cb0ef41Sopenharmony_ci  DCHECK(IsFullEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
2541cb0ef41Sopenharmony_ci         IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
2551cb0ef41Sopenharmony_ci         IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_) ||
2561cb0ef41Sopenharmony_ci         IsOffHeapTarget(rmode_));
2571cb0ef41Sopenharmony_ci  if (IsInternalReference(rmode_)) {
2581cb0ef41Sopenharmony_ci    Memory<Address>(pc_) = kNullAddress;
2591cb0ef41Sopenharmony_ci  } else if (IsInternalReferenceEncoded(rmode_)) {
2601cb0ef41Sopenharmony_ci    Assembler::set_target_internal_reference_encoded_at(pc_, kNullAddress);
2611cb0ef41Sopenharmony_ci  } else {
2621cb0ef41Sopenharmony_ci    Assembler::set_target_address_at(pc_, constant_pool_, kNullAddress);
2631cb0ef41Sopenharmony_ci  }
2641cb0ef41Sopenharmony_ci}
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ciHandle<Code> Assembler::relative_code_target_object_handle_at(
2671cb0ef41Sopenharmony_ci    Address pc) const {
2681cb0ef41Sopenharmony_ci  Instr instr1 = instr_at(pc);
2691cb0ef41Sopenharmony_ci  Instr instr2 = instr_at(pc + kInstrSize);
2701cb0ef41Sopenharmony_ci  DCHECK(IsLui(instr1));
2711cb0ef41Sopenharmony_ci  DCHECK(IsOri(instr2) || IsNal(instr2));
2721cb0ef41Sopenharmony_ci  DCHECK(IsNal(instr2) || IsNal(instr_at(pc - kInstrSize)));
2731cb0ef41Sopenharmony_ci  if (IsNal(instr2)) {
2741cb0ef41Sopenharmony_ci    instr2 = instr_at(pc + 2 * kInstrSize);
2751cb0ef41Sopenharmony_ci  }
2761cb0ef41Sopenharmony_ci  // Interpret 2 instructions generated by li (lui/ori).
2771cb0ef41Sopenharmony_ci  int code_target_index = GetLuiOriImmediate(instr1, instr2);
2781cb0ef41Sopenharmony_ci  return GetCodeTarget(code_target_index);
2791cb0ef41Sopenharmony_ci}
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
2821cb0ef41Sopenharmony_ci// Assembler.
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_civoid Assembler::CheckBuffer() {
2851cb0ef41Sopenharmony_ci  if (buffer_space() <= kGap) {
2861cb0ef41Sopenharmony_ci    GrowBuffer();
2871cb0ef41Sopenharmony_ci  }
2881cb0ef41Sopenharmony_ci}
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_civoid Assembler::CheckForEmitInForbiddenSlot() {
2911cb0ef41Sopenharmony_ci  if (!is_buffer_growth_blocked()) {
2921cb0ef41Sopenharmony_ci    CheckBuffer();
2931cb0ef41Sopenharmony_ci  }
2941cb0ef41Sopenharmony_ci  if (IsPrevInstrCompactBranch()) {
2951cb0ef41Sopenharmony_ci    // Nop instruction to precede a CTI in forbidden slot:
2961cb0ef41Sopenharmony_ci    Instr nop = SPECIAL | SLL;
2971cb0ef41Sopenharmony_ci    *reinterpret_cast<Instr*>(pc_) = nop;
2981cb0ef41Sopenharmony_ci    pc_ += kInstrSize;
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci    ClearCompactBranchState();
3011cb0ef41Sopenharmony_ci  }
3021cb0ef41Sopenharmony_ci}
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_civoid Assembler::EmitHelper(Instr x, CompactBranchType is_compact_branch) {
3051cb0ef41Sopenharmony_ci  if (IsPrevInstrCompactBranch()) {
3061cb0ef41Sopenharmony_ci    if (Instruction::IsForbiddenAfterBranchInstr(x)) {
3071cb0ef41Sopenharmony_ci      // Nop instruction to precede a CTI in forbidden slot:
3081cb0ef41Sopenharmony_ci      Instr nop = SPECIAL | SLL;
3091cb0ef41Sopenharmony_ci      *reinterpret_cast<Instr*>(pc_) = nop;
3101cb0ef41Sopenharmony_ci      pc_ += kInstrSize;
3111cb0ef41Sopenharmony_ci    }
3121cb0ef41Sopenharmony_ci    ClearCompactBranchState();
3131cb0ef41Sopenharmony_ci  }
3141cb0ef41Sopenharmony_ci  *reinterpret_cast<Instr*>(pc_) = x;
3151cb0ef41Sopenharmony_ci  pc_ += kInstrSize;
3161cb0ef41Sopenharmony_ci  if (is_compact_branch == CompactBranchType::COMPACT_BRANCH) {
3171cb0ef41Sopenharmony_ci    EmittedCompactBranchInstruction();
3181cb0ef41Sopenharmony_ci  }
3191cb0ef41Sopenharmony_ci  CheckTrampolinePoolQuick();
3201cb0ef41Sopenharmony_ci}
3211cb0ef41Sopenharmony_ci
3221cb0ef41Sopenharmony_citemplate <>
3231cb0ef41Sopenharmony_ciinline void Assembler::EmitHelper(uint8_t x);
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_citemplate <typename T>
3261cb0ef41Sopenharmony_civoid Assembler::EmitHelper(T x) {
3271cb0ef41Sopenharmony_ci  *reinterpret_cast<T*>(pc_) = x;
3281cb0ef41Sopenharmony_ci  pc_ += sizeof(x);
3291cb0ef41Sopenharmony_ci  CheckTrampolinePoolQuick();
3301cb0ef41Sopenharmony_ci}
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_citemplate <>
3331cb0ef41Sopenharmony_civoid Assembler::EmitHelper(uint8_t x) {
3341cb0ef41Sopenharmony_ci  *reinterpret_cast<uint8_t*>(pc_) = x;
3351cb0ef41Sopenharmony_ci  pc_ += sizeof(x);
3361cb0ef41Sopenharmony_ci  if (reinterpret_cast<intptr_t>(pc_) % kInstrSize == 0) {
3371cb0ef41Sopenharmony_ci    CheckTrampolinePoolQuick();
3381cb0ef41Sopenharmony_ci  }
3391cb0ef41Sopenharmony_ci}
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_civoid Assembler::emit(Instr x, CompactBranchType is_compact_branch) {
3421cb0ef41Sopenharmony_ci  if (!is_buffer_growth_blocked()) {
3431cb0ef41Sopenharmony_ci    CheckBuffer();
3441cb0ef41Sopenharmony_ci  }
3451cb0ef41Sopenharmony_ci  EmitHelper(x, is_compact_branch);
3461cb0ef41Sopenharmony_ci}
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ciEnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci}  // namespace internal
3511cb0ef41Sopenharmony_ci}  // namespace v8
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_MIPS_ASSEMBLER_MIPS_INL_H_
354