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