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