11cb0ef41Sopenharmony_ci// Copyright (c) 1994-2006 Sun Microsystems Inc.
21cb0ef41Sopenharmony_ci// All Rights Reserved.
31cb0ef41Sopenharmony_ci//
41cb0ef41Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
51cb0ef41Sopenharmony_ci// modification, are permitted provided that the following conditions
61cb0ef41Sopenharmony_ci// are met:
71cb0ef41Sopenharmony_ci//
81cb0ef41Sopenharmony_ci// - Redistributions of source code must retain the above copyright notice,
91cb0ef41Sopenharmony_ci// this list of conditions and the following disclaimer.
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// - Redistribution in binary form must reproduce the above copyright
121cb0ef41Sopenharmony_ci// notice, this list of conditions and the following disclaimer in the
131cb0ef41Sopenharmony_ci// documentation and/or other materials provided with the
141cb0ef41Sopenharmony_ci// 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
211cb0ef41Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
221cb0ef41Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
231cb0ef41Sopenharmony_ci// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
241cb0ef41Sopenharmony_ci// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
251cb0ef41Sopenharmony_ci// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
261cb0ef41Sopenharmony_ci// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
271cb0ef41Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281cb0ef41Sopenharmony_ci// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
291cb0ef41Sopenharmony_ci// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
301cb0ef41Sopenharmony_ci// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
311cb0ef41Sopenharmony_ci// OF THE POSSIBILITY OF SUCH DAMAGE.
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci// The original source code covered by the above license above has been modified
341cb0ef41Sopenharmony_ci// significantly by Google Inc.
351cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_ARM_ASSEMBLER_ARM_INL_H_
381cb0ef41Sopenharmony_ci#define V8_CODEGEN_ARM_ASSEMBLER_ARM_INL_H_
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci#include "src/codegen/arm/assembler-arm.h"
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h"
431cb0ef41Sopenharmony_ci#include "src/debug/debug.h"
441cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
451cb0ef41Sopenharmony_ci#include "src/objects/smi.h"
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_cinamespace v8 {
481cb0ef41Sopenharmony_cinamespace internal {
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_cibool CpuFeatures::SupportsOptimizer() { return true; }
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciint DoubleRegister::SupportedRegisterCount() {
531cb0ef41Sopenharmony_ci  return CpuFeatures::IsSupported(VFP32DREGS) ? 32 : 16;
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_civoid RelocInfo::apply(intptr_t delta) {
571cb0ef41Sopenharmony_ci  if (RelocInfo::IsInternalReference(rmode_)) {
581cb0ef41Sopenharmony_ci    // absolute code pointer inside code object moves with the code object.
591cb0ef41Sopenharmony_ci    int32_t* p = reinterpret_cast<int32_t*>(pc_);
601cb0ef41Sopenharmony_ci    *p += delta;  // relocate entry
611cb0ef41Sopenharmony_ci  } else if (RelocInfo::IsRelativeCodeTarget(rmode_)) {
621cb0ef41Sopenharmony_ci    Instruction* branch = Instruction::At(pc_);
631cb0ef41Sopenharmony_ci    int32_t branch_offset = branch->GetBranchOffset() - delta;
641cb0ef41Sopenharmony_ci    branch->SetBranchOffset(branch_offset);
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciAddress RelocInfo::target_address() {
691cb0ef41Sopenharmony_ci  DCHECK(IsCodeTargetMode(rmode_) || IsRuntimeEntry(rmode_) ||
701cb0ef41Sopenharmony_ci         IsWasmCall(rmode_));
711cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciAddress RelocInfo::target_address_address() {
751cb0ef41Sopenharmony_ci  DCHECK(HasTargetAddressAddress());
761cb0ef41Sopenharmony_ci  if (Assembler::IsMovW(Memory<int32_t>(pc_))) {
771cb0ef41Sopenharmony_ci    return pc_;
781cb0ef41Sopenharmony_ci  } else if (Assembler::IsLdrPcImmediateOffset(Memory<int32_t>(pc_))) {
791cb0ef41Sopenharmony_ci    return constant_pool_entry_address();
801cb0ef41Sopenharmony_ci  } else {
811cb0ef41Sopenharmony_ci    DCHECK(Assembler::IsBOrBlPcImmediateOffset(Memory<int32_t>(pc_)));
821cb0ef41Sopenharmony_ci    DCHECK(IsRelativeCodeTarget(rmode_));
831cb0ef41Sopenharmony_ci    return pc_;
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciAddress RelocInfo::constant_pool_entry_address() {
881cb0ef41Sopenharmony_ci  DCHECK(IsInConstantPool());
891cb0ef41Sopenharmony_ci  return Assembler::constant_pool_entry_address(pc_, constant_pool_);
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciint RelocInfo::target_address_size() { return kPointerSize; }
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciHeapObject RelocInfo::target_object(PtrComprCageBase cage_base) {
951cb0ef41Sopenharmony_ci  DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_) ||
961cb0ef41Sopenharmony_ci         IsDataEmbeddedObject(rmode_));
971cb0ef41Sopenharmony_ci  if (IsDataEmbeddedObject(rmode_)) {
981cb0ef41Sopenharmony_ci    return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci  return HeapObject::cast(
1011cb0ef41Sopenharmony_ci      Object(Assembler::target_address_at(pc_, constant_pool_)));
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ciHandle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
1051cb0ef41Sopenharmony_ci  if (IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_)) {
1061cb0ef41Sopenharmony_ci    return Handle<HeapObject>(reinterpret_cast<Address*>(
1071cb0ef41Sopenharmony_ci        Assembler::target_address_at(pc_, constant_pool_)));
1081cb0ef41Sopenharmony_ci  } else if (IsDataEmbeddedObject(rmode_)) {
1091cb0ef41Sopenharmony_ci    return Handle<HeapObject>::cast(ReadUnalignedValue<Handle<Object>>(pc_));
1101cb0ef41Sopenharmony_ci  }
1111cb0ef41Sopenharmony_ci  DCHECK(IsRelativeCodeTarget(rmode_));
1121cb0ef41Sopenharmony_ci  return origin->relative_code_target_object_handle_at(pc_);
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_civoid RelocInfo::set_target_object(Heap* heap, HeapObject target,
1161cb0ef41Sopenharmony_ci                                  WriteBarrierMode write_barrier_mode,
1171cb0ef41Sopenharmony_ci                                  ICacheFlushMode icache_flush_mode) {
1181cb0ef41Sopenharmony_ci  DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_) ||
1191cb0ef41Sopenharmony_ci         IsDataEmbeddedObject(rmode_));
1201cb0ef41Sopenharmony_ci  if (IsDataEmbeddedObject(rmode_)) {
1211cb0ef41Sopenharmony_ci    WriteUnalignedValue(pc_, target.ptr());
1221cb0ef41Sopenharmony_ci    // No need to flush icache since no instructions were changed.
1231cb0ef41Sopenharmony_ci  } else {
1241cb0ef41Sopenharmony_ci    Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(),
1251cb0ef41Sopenharmony_ci                                     icache_flush_mode);
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci  if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() &&
1281cb0ef41Sopenharmony_ci      !FLAG_disable_write_barriers) {
1291cb0ef41Sopenharmony_ci    WriteBarrierForCode(host(), this, target);
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ciAddress RelocInfo::target_external_reference() {
1341cb0ef41Sopenharmony_ci  DCHECK(rmode_ == EXTERNAL_REFERENCE);
1351cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_civoid RelocInfo::set_target_external_reference(
1391cb0ef41Sopenharmony_ci    Address target, ICacheFlushMode icache_flush_mode) {
1401cb0ef41Sopenharmony_ci  DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
1411cb0ef41Sopenharmony_ci  Assembler::set_target_address_at(pc_, constant_pool_, target,
1421cb0ef41Sopenharmony_ci                                   icache_flush_mode);
1431cb0ef41Sopenharmony_ci}
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ciAddress RelocInfo::target_internal_reference() {
1461cb0ef41Sopenharmony_ci  DCHECK(rmode_ == INTERNAL_REFERENCE);
1471cb0ef41Sopenharmony_ci  return Memory<Address>(pc_);
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ciAddress RelocInfo::target_internal_reference_address() {
1511cb0ef41Sopenharmony_ci  DCHECK(rmode_ == INTERNAL_REFERENCE);
1521cb0ef41Sopenharmony_ci  return pc_;
1531cb0ef41Sopenharmony_ci}
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ciAddress RelocInfo::target_runtime_entry(Assembler* origin) {
1561cb0ef41Sopenharmony_ci  DCHECK(IsRuntimeEntry(rmode_));
1571cb0ef41Sopenharmony_ci  return target_address();
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_civoid RelocInfo::set_target_runtime_entry(Address target,
1611cb0ef41Sopenharmony_ci                                         WriteBarrierMode write_barrier_mode,
1621cb0ef41Sopenharmony_ci                                         ICacheFlushMode icache_flush_mode) {
1631cb0ef41Sopenharmony_ci  DCHECK(IsRuntimeEntry(rmode_));
1641cb0ef41Sopenharmony_ci  if (target_address() != target)
1651cb0ef41Sopenharmony_ci    set_target_address(target, write_barrier_mode, icache_flush_mode);
1661cb0ef41Sopenharmony_ci}
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ciAddress RelocInfo::target_off_heap_target() {
1691cb0ef41Sopenharmony_ci  DCHECK(IsOffHeapTarget(rmode_));
1701cb0ef41Sopenharmony_ci  return Assembler::target_address_at(pc_, constant_pool_);
1711cb0ef41Sopenharmony_ci}
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_civoid RelocInfo::WipeOut() {
1741cb0ef41Sopenharmony_ci  DCHECK(IsFullEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
1751cb0ef41Sopenharmony_ci         IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
1761cb0ef41Sopenharmony_ci         IsInternalReference(rmode_) || IsOffHeapTarget(rmode_));
1771cb0ef41Sopenharmony_ci  if (IsInternalReference(rmode_)) {
1781cb0ef41Sopenharmony_ci    Memory<Address>(pc_) = kNullAddress;
1791cb0ef41Sopenharmony_ci  } else {
1801cb0ef41Sopenharmony_ci    Assembler::set_target_address_at(pc_, constant_pool_, kNullAddress);
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci}
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ciHandle<Code> Assembler::relative_code_target_object_handle_at(
1851cb0ef41Sopenharmony_ci    Address pc) const {
1861cb0ef41Sopenharmony_ci  Instruction* branch = Instruction::At(pc);
1871cb0ef41Sopenharmony_ci  int code_target_index = branch->GetBranchOffset() / kInstrSize;
1881cb0ef41Sopenharmony_ci  return GetCodeTarget(code_target_index);
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciOperand Operand::Zero() { return Operand(static_cast<int32_t>(0)); }
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ciOperand::Operand(const ExternalReference& f)
1941cb0ef41Sopenharmony_ci    : rmode_(RelocInfo::EXTERNAL_REFERENCE) {
1951cb0ef41Sopenharmony_ci  value_.immediate = static_cast<int32_t>(f.address());
1961cb0ef41Sopenharmony_ci}
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ciOperand::Operand(Smi value) : rmode_(RelocInfo::NO_INFO) {
1991cb0ef41Sopenharmony_ci  value_.immediate = static_cast<intptr_t>(value.ptr());
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ciOperand::Operand(Register rm) : rm_(rm), shift_op_(LSL), shift_imm_(0) {}
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_civoid Assembler::CheckBuffer() {
2051cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(buffer_space() <= kGap)) {
2061cb0ef41Sopenharmony_ci    GrowBuffer();
2071cb0ef41Sopenharmony_ci  }
2081cb0ef41Sopenharmony_ci  MaybeCheckConstPool();
2091cb0ef41Sopenharmony_ci}
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_civoid Assembler::emit(Instr x) {
2121cb0ef41Sopenharmony_ci  CheckBuffer();
2131cb0ef41Sopenharmony_ci  *reinterpret_cast<Instr*>(pc_) = x;
2141cb0ef41Sopenharmony_ci  pc_ += kInstrSize;
2151cb0ef41Sopenharmony_ci}
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_civoid Assembler::deserialization_set_special_target_at(
2181cb0ef41Sopenharmony_ci    Address constant_pool_entry, Code code, Address target) {
2191cb0ef41Sopenharmony_ci  DCHECK(!Builtins::IsIsolateIndependentBuiltin(code));
2201cb0ef41Sopenharmony_ci  Memory<Address>(constant_pool_entry) = target;
2211cb0ef41Sopenharmony_ci}
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ciint Assembler::deserialization_special_target_size(Address location) {
2241cb0ef41Sopenharmony_ci  return kSpecialTargetSize;
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_civoid Assembler::deserialization_set_target_internal_reference_at(
2281cb0ef41Sopenharmony_ci    Address pc, Address target, RelocInfo::Mode mode) {
2291cb0ef41Sopenharmony_ci  Memory<Address>(pc) = target;
2301cb0ef41Sopenharmony_ci}
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_cibool Assembler::is_constant_pool_load(Address pc) {
2331cb0ef41Sopenharmony_ci  return IsLdrPcImmediateOffset(Memory<int32_t>(pc));
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciAddress Assembler::constant_pool_entry_address(Address pc,
2371cb0ef41Sopenharmony_ci                                               Address constant_pool) {
2381cb0ef41Sopenharmony_ci  DCHECK(Assembler::IsLdrPcImmediateOffset(Memory<int32_t>(pc)));
2391cb0ef41Sopenharmony_ci  Instr instr = Memory<int32_t>(pc);
2401cb0ef41Sopenharmony_ci  return pc + GetLdrRegisterImmediateOffset(instr) + Instruction::kPcLoadDelta;
2411cb0ef41Sopenharmony_ci}
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ciAddress Assembler::target_address_at(Address pc, Address constant_pool) {
2441cb0ef41Sopenharmony_ci  if (is_constant_pool_load(pc)) {
2451cb0ef41Sopenharmony_ci    // This is a constant pool lookup. Return the value in the constant pool.
2461cb0ef41Sopenharmony_ci    return Memory<Address>(constant_pool_entry_address(pc, constant_pool));
2471cb0ef41Sopenharmony_ci  } else if (CpuFeatures::IsSupported(ARMv7) && IsMovW(Memory<int32_t>(pc))) {
2481cb0ef41Sopenharmony_ci    // This is an movw / movt immediate load. Return the immediate.
2491cb0ef41Sopenharmony_ci    DCHECK(IsMovW(Memory<int32_t>(pc)) &&
2501cb0ef41Sopenharmony_ci           IsMovT(Memory<int32_t>(pc + kInstrSize)));
2511cb0ef41Sopenharmony_ci    Instruction* movw_instr = Instruction::At(pc);
2521cb0ef41Sopenharmony_ci    Instruction* movt_instr = Instruction::At(pc + kInstrSize);
2531cb0ef41Sopenharmony_ci    return static_cast<Address>((movt_instr->ImmedMovwMovtValue() << 16) |
2541cb0ef41Sopenharmony_ci                                movw_instr->ImmedMovwMovtValue());
2551cb0ef41Sopenharmony_ci  } else if (IsMovImmed(Memory<int32_t>(pc))) {
2561cb0ef41Sopenharmony_ci    // This is an mov / orr immediate load. Return the immediate.
2571cb0ef41Sopenharmony_ci    DCHECK(IsMovImmed(Memory<int32_t>(pc)) &&
2581cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + kInstrSize)) &&
2591cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 2 * kInstrSize)) &&
2601cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 3 * kInstrSize)));
2611cb0ef41Sopenharmony_ci    Instr mov_instr = instr_at(pc);
2621cb0ef41Sopenharmony_ci    Instr orr_instr_1 = instr_at(pc + kInstrSize);
2631cb0ef41Sopenharmony_ci    Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize);
2641cb0ef41Sopenharmony_ci    Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize);
2651cb0ef41Sopenharmony_ci    Address ret = static_cast<Address>(
2661cb0ef41Sopenharmony_ci        DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
2671cb0ef41Sopenharmony_ci        DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3));
2681cb0ef41Sopenharmony_ci    return ret;
2691cb0ef41Sopenharmony_ci  } else {
2701cb0ef41Sopenharmony_ci    Instruction* branch = Instruction::At(pc);
2711cb0ef41Sopenharmony_ci    int32_t delta = branch->GetBranchOffset();
2721cb0ef41Sopenharmony_ci    return pc + delta + Instruction::kPcLoadDelta;
2731cb0ef41Sopenharmony_ci  }
2741cb0ef41Sopenharmony_ci}
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_civoid Assembler::set_target_address_at(Address pc, Address constant_pool,
2771cb0ef41Sopenharmony_ci                                      Address target,
2781cb0ef41Sopenharmony_ci                                      ICacheFlushMode icache_flush_mode) {
2791cb0ef41Sopenharmony_ci  if (is_constant_pool_load(pc)) {
2801cb0ef41Sopenharmony_ci    // This is a constant pool lookup. Update the entry in the constant pool.
2811cb0ef41Sopenharmony_ci    Memory<Address>(constant_pool_entry_address(pc, constant_pool)) = target;
2821cb0ef41Sopenharmony_ci    // Intuitively, we would think it is necessary to always flush the
2831cb0ef41Sopenharmony_ci    // instruction cache after patching a target address in the code as follows:
2841cb0ef41Sopenharmony_ci    //   FlushInstructionCache(pc, sizeof(target));
2851cb0ef41Sopenharmony_ci    // However, on ARM, no instruction is actually patched in the case
2861cb0ef41Sopenharmony_ci    // of embedded constants of the form:
2871cb0ef41Sopenharmony_ci    // ldr   ip, [pp, #...]
2881cb0ef41Sopenharmony_ci    // since the instruction accessing this address in the constant pool remains
2891cb0ef41Sopenharmony_ci    // unchanged.
2901cb0ef41Sopenharmony_ci  } else if (CpuFeatures::IsSupported(ARMv7) && IsMovW(Memory<int32_t>(pc))) {
2911cb0ef41Sopenharmony_ci    // This is an movw / movt immediate load. Patch the immediate embedded in
2921cb0ef41Sopenharmony_ci    // the instructions.
2931cb0ef41Sopenharmony_ci    DCHECK(IsMovW(Memory<int32_t>(pc)));
2941cb0ef41Sopenharmony_ci    DCHECK(IsMovT(Memory<int32_t>(pc + kInstrSize)));
2951cb0ef41Sopenharmony_ci    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
2961cb0ef41Sopenharmony_ci    uint32_t immediate = static_cast<uint32_t>(target);
2971cb0ef41Sopenharmony_ci    instr_ptr[0] = PatchMovwImmediate(instr_ptr[0], immediate & 0xFFFF);
2981cb0ef41Sopenharmony_ci    instr_ptr[1] = PatchMovwImmediate(instr_ptr[1], immediate >> 16);
2991cb0ef41Sopenharmony_ci    DCHECK(IsMovW(Memory<int32_t>(pc)));
3001cb0ef41Sopenharmony_ci    DCHECK(IsMovT(Memory<int32_t>(pc + kInstrSize)));
3011cb0ef41Sopenharmony_ci    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3021cb0ef41Sopenharmony_ci      FlushInstructionCache(pc, 2 * kInstrSize);
3031cb0ef41Sopenharmony_ci    }
3041cb0ef41Sopenharmony_ci  } else if (IsMovImmed(Memory<int32_t>(pc))) {
3051cb0ef41Sopenharmony_ci    // This is an mov / orr immediate load. Patch the immediate embedded in
3061cb0ef41Sopenharmony_ci    // the instructions.
3071cb0ef41Sopenharmony_ci    DCHECK(IsMovImmed(Memory<int32_t>(pc)) &&
3081cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + kInstrSize)) &&
3091cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 2 * kInstrSize)) &&
3101cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 3 * kInstrSize)));
3111cb0ef41Sopenharmony_ci    uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
3121cb0ef41Sopenharmony_ci    uint32_t immediate = static_cast<uint32_t>(target);
3131cb0ef41Sopenharmony_ci    instr_ptr[0] = PatchShiftImm(instr_ptr[0], immediate & kImm8Mask);
3141cb0ef41Sopenharmony_ci    instr_ptr[1] = PatchShiftImm(instr_ptr[1], immediate & (kImm8Mask << 8));
3151cb0ef41Sopenharmony_ci    instr_ptr[2] = PatchShiftImm(instr_ptr[2], immediate & (kImm8Mask << 16));
3161cb0ef41Sopenharmony_ci    instr_ptr[3] = PatchShiftImm(instr_ptr[3], immediate & (kImm8Mask << 24));
3171cb0ef41Sopenharmony_ci    DCHECK(IsMovImmed(Memory<int32_t>(pc)) &&
3181cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + kInstrSize)) &&
3191cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 2 * kInstrSize)) &&
3201cb0ef41Sopenharmony_ci           IsOrrImmed(Memory<int32_t>(pc + 3 * kInstrSize)));
3211cb0ef41Sopenharmony_ci    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3221cb0ef41Sopenharmony_ci      FlushInstructionCache(pc, 4 * kInstrSize);
3231cb0ef41Sopenharmony_ci    }
3241cb0ef41Sopenharmony_ci  } else {
3251cb0ef41Sopenharmony_ci    intptr_t branch_offset = target - pc - Instruction::kPcLoadDelta;
3261cb0ef41Sopenharmony_ci    Instruction* branch = Instruction::At(pc);
3271cb0ef41Sopenharmony_ci    branch->SetBranchOffset(branch_offset);
3281cb0ef41Sopenharmony_ci    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3291cb0ef41Sopenharmony_ci      FlushInstructionCache(pc, kInstrSize);
3301cb0ef41Sopenharmony_ci    }
3311cb0ef41Sopenharmony_ci  }
3321cb0ef41Sopenharmony_ci}
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ciEnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_citemplate <typename T>
3371cb0ef41Sopenharmony_cibool UseScratchRegisterScope::CanAcquireVfp() const {
3381cb0ef41Sopenharmony_ci  VfpRegList* available = assembler_->GetScratchVfpRegisterList();
3391cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(available);
3401cb0ef41Sopenharmony_ci  for (int index = 0; index < T::kNumRegisters; index++) {
3411cb0ef41Sopenharmony_ci    T reg = T::from_code(index);
3421cb0ef41Sopenharmony_ci    uint64_t mask = reg.ToVfpRegList();
3431cb0ef41Sopenharmony_ci    if ((*available & mask) == mask) {
3441cb0ef41Sopenharmony_ci      return true;
3451cb0ef41Sopenharmony_ci    }
3461cb0ef41Sopenharmony_ci  }
3471cb0ef41Sopenharmony_ci  return false;
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_citemplate <typename T>
3511cb0ef41Sopenharmony_ciT UseScratchRegisterScope::AcquireVfp() {
3521cb0ef41Sopenharmony_ci  VfpRegList* available = assembler_->GetScratchVfpRegisterList();
3531cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(available);
3541cb0ef41Sopenharmony_ci  for (int index = 0; index < T::kNumRegisters; index++) {
3551cb0ef41Sopenharmony_ci    T reg = T::from_code(index);
3561cb0ef41Sopenharmony_ci    uint64_t mask = reg.ToVfpRegList();
3571cb0ef41Sopenharmony_ci    if ((*available & mask) == mask) {
3581cb0ef41Sopenharmony_ci      *available &= ~mask;
3591cb0ef41Sopenharmony_ci      return reg;
3601cb0ef41Sopenharmony_ci    }
3611cb0ef41Sopenharmony_ci  }
3621cb0ef41Sopenharmony_ci  UNREACHABLE();
3631cb0ef41Sopenharmony_ci}
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci}  // namespace internal
3661cb0ef41Sopenharmony_ci}  // namespace v8
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_ARM_ASSEMBLER_ARM_INL_H_
369