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 341cb0ef41Sopenharmony_ci// modified significantly by Google Inc. 351cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved. 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci// A light-weight ARM Assembler 381cb0ef41Sopenharmony_ci// Generates user mode instructions for the ARM architecture up to version 5 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_ARM_ASSEMBLER_ARM_H_ 411cb0ef41Sopenharmony_ci#define V8_CODEGEN_ARM_ASSEMBLER_ARM_H_ 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci#include <stdio.h> 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci#include <memory> 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci#include "src/base/numbers/double.h" 481cb0ef41Sopenharmony_ci#include "src/base/small-vector.h" 491cb0ef41Sopenharmony_ci#include "src/codegen/arm/constants-arm.h" 501cb0ef41Sopenharmony_ci#include "src/codegen/arm/register-arm.h" 511cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h" 521cb0ef41Sopenharmony_ci#include "src/codegen/constant-pool.h" 531cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h" 541cb0ef41Sopenharmony_ci#include "src/utils/boxed-float.h" 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_cinamespace v8 { 571cb0ef41Sopenharmony_cinamespace internal { 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciclass SafepointTableBuilder; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci// Coprocessor number 621cb0ef41Sopenharmony_cienum Coprocessor { 631cb0ef41Sopenharmony_ci p0 = 0, 641cb0ef41Sopenharmony_ci p1 = 1, 651cb0ef41Sopenharmony_ci p2 = 2, 661cb0ef41Sopenharmony_ci p3 = 3, 671cb0ef41Sopenharmony_ci p4 = 4, 681cb0ef41Sopenharmony_ci p5 = 5, 691cb0ef41Sopenharmony_ci p6 = 6, 701cb0ef41Sopenharmony_ci p7 = 7, 711cb0ef41Sopenharmony_ci p8 = 8, 721cb0ef41Sopenharmony_ci p9 = 9, 731cb0ef41Sopenharmony_ci p10 = 10, 741cb0ef41Sopenharmony_ci p11 = 11, 751cb0ef41Sopenharmony_ci p12 = 12, 761cb0ef41Sopenharmony_ci p13 = 13, 771cb0ef41Sopenharmony_ci p14 = 14, 781cb0ef41Sopenharmony_ci p15 = 15 791cb0ef41Sopenharmony_ci}; 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------- 821cb0ef41Sopenharmony_ci// Machine instruction Operands 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci// Class Operand represents a shifter operand in data processing instructions 851cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Operand { 861cb0ef41Sopenharmony_ci public: 871cb0ef41Sopenharmony_ci // immediate 881cb0ef41Sopenharmony_ci V8_INLINE explicit Operand(int32_t immediate, 891cb0ef41Sopenharmony_ci RelocInfo::Mode rmode = RelocInfo::NO_INFO) 901cb0ef41Sopenharmony_ci : rmode_(rmode) { 911cb0ef41Sopenharmony_ci value_.immediate = immediate; 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci V8_INLINE static Operand Zero(); 941cb0ef41Sopenharmony_ci V8_INLINE explicit Operand(const ExternalReference& f); 951cb0ef41Sopenharmony_ci explicit Operand(Handle<HeapObject> handle); 961cb0ef41Sopenharmony_ci V8_INLINE explicit Operand(Smi value); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci // rm 991cb0ef41Sopenharmony_ci V8_INLINE explicit Operand(Register rm); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // rm <shift_op> shift_imm 1021cb0ef41Sopenharmony_ci explicit Operand(Register rm, ShiftOp shift_op, int shift_imm); 1031cb0ef41Sopenharmony_ci V8_INLINE static Operand SmiUntag(Register rm) { 1041cb0ef41Sopenharmony_ci return Operand(rm, ASR, kSmiTagSize); 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci V8_INLINE static Operand PointerOffsetFromSmiKey(Register key) { 1071cb0ef41Sopenharmony_ci STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 1081cb0ef41Sopenharmony_ci return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize); 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci V8_INLINE static Operand DoubleOffsetFromSmiKey(Register key) { 1111cb0ef41Sopenharmony_ci STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); 1121cb0ef41Sopenharmony_ci return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci // rm <shift_op> rs 1161cb0ef41Sopenharmony_ci explicit Operand(Register rm, ShiftOp shift_op, Register rs); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci static Operand EmbeddedNumber(double number); // Smi or HeapNumber. 1191cb0ef41Sopenharmony_ci static Operand EmbeddedStringConstant(const StringConstantBase* str); 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci // Return true if this is a register operand. 1221cb0ef41Sopenharmony_ci bool IsRegister() const { 1231cb0ef41Sopenharmony_ci return rm_.is_valid() && rs_ == no_reg && shift_op_ == LSL && 1241cb0ef41Sopenharmony_ci shift_imm_ == 0; 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci // Return true if this is a register operand shifted with an immediate. 1271cb0ef41Sopenharmony_ci bool IsImmediateShiftedRegister() const { 1281cb0ef41Sopenharmony_ci return rm_.is_valid() && !rs_.is_valid(); 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci // Return true if this is a register operand shifted with a register. 1311cb0ef41Sopenharmony_ci bool IsRegisterShiftedRegister() const { 1321cb0ef41Sopenharmony_ci return rm_.is_valid() && rs_.is_valid(); 1331cb0ef41Sopenharmony_ci } 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci // Return the number of actual instructions required to implement the given 1361cb0ef41Sopenharmony_ci // instruction for this particular operand. This can be a single instruction, 1371cb0ef41Sopenharmony_ci // if no load into a scratch register is necessary, or anything between 2 and 1381cb0ef41Sopenharmony_ci // 4 instructions when we need to load from the constant pool (depending upon 1391cb0ef41Sopenharmony_ci // whether the constant pool entry is in the small or extended section). If 1401cb0ef41Sopenharmony_ci // the instruction this operand is used for is a MOV or MVN instruction the 1411cb0ef41Sopenharmony_ci // actual instruction to use is required for this calculation. For other 1421cb0ef41Sopenharmony_ci // instructions instr is ignored. 1431cb0ef41Sopenharmony_ci // 1441cb0ef41Sopenharmony_ci // The value returned is only valid as long as no entries are added to the 1451cb0ef41Sopenharmony_ci // constant pool between this call and the actual instruction being emitted. 1461cb0ef41Sopenharmony_ci int InstructionsRequired(const Assembler* assembler, Instr instr = 0) const; 1471cb0ef41Sopenharmony_ci bool MustOutputRelocInfo(const Assembler* assembler) const; 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci inline int32_t immediate() const { 1501cb0ef41Sopenharmony_ci DCHECK(IsImmediate()); 1511cb0ef41Sopenharmony_ci DCHECK(!IsHeapObjectRequest()); 1521cb0ef41Sopenharmony_ci return value_.immediate; 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci bool IsImmediate() const { return !rm_.is_valid(); } 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci HeapObjectRequest heap_object_request() const { 1571cb0ef41Sopenharmony_ci DCHECK(IsHeapObjectRequest()); 1581cb0ef41Sopenharmony_ci return value_.heap_object_request; 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci bool IsHeapObjectRequest() const { 1611cb0ef41Sopenharmony_ci DCHECK_IMPLIES(is_heap_object_request_, IsImmediate()); 1621cb0ef41Sopenharmony_ci DCHECK_IMPLIES(is_heap_object_request_, 1631cb0ef41Sopenharmony_ci rmode_ == RelocInfo::FULL_EMBEDDED_OBJECT || 1641cb0ef41Sopenharmony_ci rmode_ == RelocInfo::CODE_TARGET); 1651cb0ef41Sopenharmony_ci return is_heap_object_request_; 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci Register rm() const { return rm_; } 1691cb0ef41Sopenharmony_ci Register rs() const { return rs_; } 1701cb0ef41Sopenharmony_ci ShiftOp shift_op() const { return shift_op_; } 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci private: 1731cb0ef41Sopenharmony_ci Register rm_ = no_reg; 1741cb0ef41Sopenharmony_ci Register rs_ = no_reg; 1751cb0ef41Sopenharmony_ci ShiftOp shift_op_; 1761cb0ef41Sopenharmony_ci int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg 1771cb0ef41Sopenharmony_ci union Value { 1781cb0ef41Sopenharmony_ci Value() {} 1791cb0ef41Sopenharmony_ci HeapObjectRequest heap_object_request; // if is_heap_object_request_ 1801cb0ef41Sopenharmony_ci int32_t immediate; // otherwise 1811cb0ef41Sopenharmony_ci } value_; // valid if rm_ == no_reg 1821cb0ef41Sopenharmony_ci bool is_heap_object_request_ = false; 1831cb0ef41Sopenharmony_ci RelocInfo::Mode rmode_; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci friend class Assembler; 1861cb0ef41Sopenharmony_ci}; 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci// Class MemOperand represents a memory operand in load and store instructions 1891cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE MemOperand { 1901cb0ef41Sopenharmony_ci public: 1911cb0ef41Sopenharmony_ci // [rn +/- offset] Offset/NegOffset 1921cb0ef41Sopenharmony_ci // [rn +/- offset]! PreIndex/NegPreIndex 1931cb0ef41Sopenharmony_ci // [rn], +/- offset PostIndex/NegPostIndex 1941cb0ef41Sopenharmony_ci // offset is any signed 32-bit value; offset is first loaded to a scratch 1951cb0ef41Sopenharmony_ci // register if it does not fit the addressing mode (12-bit unsigned and sign 1961cb0ef41Sopenharmony_ci // bit) 1971cb0ef41Sopenharmony_ci explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset); 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci // [rn +/- rm] Offset/NegOffset 2001cb0ef41Sopenharmony_ci // [rn +/- rm]! PreIndex/NegPreIndex 2011cb0ef41Sopenharmony_ci // [rn], +/- rm PostIndex/NegPostIndex 2021cb0ef41Sopenharmony_ci explicit MemOperand(Register rn, Register rm, AddrMode am = Offset); 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci // [rn +/- rm <shift_op> shift_imm] Offset/NegOffset 2051cb0ef41Sopenharmony_ci // [rn +/- rm <shift_op> shift_imm]! PreIndex/NegPreIndex 2061cb0ef41Sopenharmony_ci // [rn], +/- rm <shift_op> shift_imm PostIndex/NegPostIndex 2071cb0ef41Sopenharmony_ci explicit MemOperand(Register rn, Register rm, ShiftOp shift_op, int shift_imm, 2081cb0ef41Sopenharmony_ci AddrMode am = Offset); 2091cb0ef41Sopenharmony_ci V8_INLINE static MemOperand PointerAddressFromSmiKey(Register array, 2101cb0ef41Sopenharmony_ci Register key, 2111cb0ef41Sopenharmony_ci AddrMode am = Offset) { 2121cb0ef41Sopenharmony_ci STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 2131cb0ef41Sopenharmony_ci return MemOperand(array, key, LSL, kPointerSizeLog2 - kSmiTagSize, am); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci void set_offset(int32_t offset) { 2171cb0ef41Sopenharmony_ci DCHECK(rm_ == no_reg); 2181cb0ef41Sopenharmony_ci offset_ = offset; 2191cb0ef41Sopenharmony_ci } 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci uint32_t offset() const { 2221cb0ef41Sopenharmony_ci DCHECK(rm_ == no_reg); 2231cb0ef41Sopenharmony_ci return offset_; 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci Register rn() const { return rn_; } 2271cb0ef41Sopenharmony_ci Register rm() const { return rm_; } 2281cb0ef41Sopenharmony_ci AddrMode am() const { return am_; } 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci bool OffsetIsUint12Encodable() const { 2311cb0ef41Sopenharmony_ci return offset_ >= 0 ? is_uint12(offset_) : is_uint12(-offset_); 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci private: 2351cb0ef41Sopenharmony_ci Register rn_; // base 2361cb0ef41Sopenharmony_ci Register rm_; // register offset 2371cb0ef41Sopenharmony_ci int32_t offset_; // valid if rm_ == no_reg 2381cb0ef41Sopenharmony_ci ShiftOp shift_op_; 2391cb0ef41Sopenharmony_ci int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg 2401cb0ef41Sopenharmony_ci AddrMode am_; // bits P, U, and W 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci friend class Assembler; 2431cb0ef41Sopenharmony_ci}; 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci// Class NeonMemOperand represents a memory operand in load and 2461cb0ef41Sopenharmony_ci// store NEON instructions 2471cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE NeonMemOperand { 2481cb0ef41Sopenharmony_ci public: 2491cb0ef41Sopenharmony_ci // [rn {:align}] Offset 2501cb0ef41Sopenharmony_ci // [rn {:align}]! PostIndex 2511cb0ef41Sopenharmony_ci explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0); 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci // [rn {:align}], rm PostIndex 2541cb0ef41Sopenharmony_ci explicit NeonMemOperand(Register rn, Register rm, int align = 0); 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci Register rn() const { return rn_; } 2571cb0ef41Sopenharmony_ci Register rm() const { return rm_; } 2581cb0ef41Sopenharmony_ci int align() const { return align_; } 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci private: 2611cb0ef41Sopenharmony_ci void SetAlignment(int align); 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci Register rn_; // base 2641cb0ef41Sopenharmony_ci Register rm_; // register increment 2651cb0ef41Sopenharmony_ci int align_; 2661cb0ef41Sopenharmony_ci}; 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci// Class NeonListOperand represents a list of NEON registers 2691cb0ef41Sopenharmony_ciclass NeonListOperand { 2701cb0ef41Sopenharmony_ci public: 2711cb0ef41Sopenharmony_ci explicit NeonListOperand(DoubleRegister base, int register_count = 1) 2721cb0ef41Sopenharmony_ci : base_(base), register_count_(register_count) {} 2731cb0ef41Sopenharmony_ci explicit NeonListOperand(QwNeonRegister q_reg) 2741cb0ef41Sopenharmony_ci : base_(q_reg.low()), register_count_(2) {} 2751cb0ef41Sopenharmony_ci DoubleRegister base() const { return base_; } 2761cb0ef41Sopenharmony_ci int register_count() { return register_count_; } 2771cb0ef41Sopenharmony_ci int length() const { return register_count_ - 1; } 2781cb0ef41Sopenharmony_ci NeonListType type() const { 2791cb0ef41Sopenharmony_ci switch (register_count_) { 2801cb0ef41Sopenharmony_ci default: 2811cb0ef41Sopenharmony_ci UNREACHABLE(); 2821cb0ef41Sopenharmony_ci // Fall through. 2831cb0ef41Sopenharmony_ci case 1: 2841cb0ef41Sopenharmony_ci return nlt_1; 2851cb0ef41Sopenharmony_ci case 2: 2861cb0ef41Sopenharmony_ci return nlt_2; 2871cb0ef41Sopenharmony_ci case 3: 2881cb0ef41Sopenharmony_ci return nlt_3; 2891cb0ef41Sopenharmony_ci case 4: 2901cb0ef41Sopenharmony_ci return nlt_4; 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci } 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci private: 2951cb0ef41Sopenharmony_ci DoubleRegister base_; 2961cb0ef41Sopenharmony_ci int register_count_; 2971cb0ef41Sopenharmony_ci}; 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Assembler : public AssemblerBase { 3001cb0ef41Sopenharmony_ci public: 3011cb0ef41Sopenharmony_ci // Create an assembler. Instructions and relocation information are emitted 3021cb0ef41Sopenharmony_ci // into a buffer, with the instructions starting from the beginning and the 3031cb0ef41Sopenharmony_ci // relocation information starting from the end of the buffer. See CodeDesc 3041cb0ef41Sopenharmony_ci // for a detailed comment on the layout (globals.h). 3051cb0ef41Sopenharmony_ci // 3061cb0ef41Sopenharmony_ci // If the provided buffer is nullptr, the assembler allocates and grows its 3071cb0ef41Sopenharmony_ci // own buffer. Otherwise it takes ownership of the provided buffer. 3081cb0ef41Sopenharmony_ci explicit Assembler(const AssemblerOptions&, 3091cb0ef41Sopenharmony_ci std::unique_ptr<AssemblerBuffer> = {}); 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci ~Assembler() override; 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci void AbortedCodeGeneration() override { 3141cb0ef41Sopenharmony_ci pending_32_bit_constants_.clear(); 3151cb0ef41Sopenharmony_ci first_const_pool_32_use_ = -1; 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci // GetCode emits any pending (non-emitted) code and fills the descriptor desc. 3191cb0ef41Sopenharmony_ci static constexpr int kNoHandlerTable = 0; 3201cb0ef41Sopenharmony_ci static constexpr SafepointTableBuilder* kNoSafepointTable = nullptr; 3211cb0ef41Sopenharmony_ci void GetCode(Isolate* isolate, CodeDesc* desc, 3221cb0ef41Sopenharmony_ci SafepointTableBuilder* safepoint_table_builder, 3231cb0ef41Sopenharmony_ci int handler_table_offset); 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci // Convenience wrapper for code without safepoint or handler tables. 3261cb0ef41Sopenharmony_ci void GetCode(Isolate* isolate, CodeDesc* desc) { 3271cb0ef41Sopenharmony_ci GetCode(isolate, desc, kNoSafepointTable, kNoHandlerTable); 3281cb0ef41Sopenharmony_ci } 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ci // Label operations & relative jumps (PPUM Appendix D) 3311cb0ef41Sopenharmony_ci // 3321cb0ef41Sopenharmony_ci // Takes a branch opcode (cc) and a label (L) and generates 3331cb0ef41Sopenharmony_ci // either a backward branch or a forward branch and links it 3341cb0ef41Sopenharmony_ci // to the label fixup chain. Usage: 3351cb0ef41Sopenharmony_ci // 3361cb0ef41Sopenharmony_ci // Label L; // unbound label 3371cb0ef41Sopenharmony_ci // j(cc, &L); // forward branch to unbound label 3381cb0ef41Sopenharmony_ci // bind(&L); // bind label to the current pc 3391cb0ef41Sopenharmony_ci // j(cc, &L); // backward branch to bound label 3401cb0ef41Sopenharmony_ci // bind(&L); // illegal: a label may be bound only once 3411cb0ef41Sopenharmony_ci // 3421cb0ef41Sopenharmony_ci // Note: The same Label can be used for forward and backward branches 3431cb0ef41Sopenharmony_ci // but it may be bound only once. 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci void bind(Label* L); // binds an unbound label L to the current code position 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci // Returns the branch offset to the given label from the current code position 3481cb0ef41Sopenharmony_ci // Links the label to the current position if it is still unbound 3491cb0ef41Sopenharmony_ci // Manages the jump elimination optimization if the second parameter is true. 3501cb0ef41Sopenharmony_ci int branch_offset(Label* L); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci // Returns true if the given pc address is the start of a constant pool load 3531cb0ef41Sopenharmony_ci // instruction sequence. 3541cb0ef41Sopenharmony_ci V8_INLINE static bool is_constant_pool_load(Address pc); 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci // Return the address in the constant pool of the code target address used by 3571cb0ef41Sopenharmony_ci // the branch/call instruction at pc, or the object in a mov. 3581cb0ef41Sopenharmony_ci V8_INLINE static Address constant_pool_entry_address(Address pc, 3591cb0ef41Sopenharmony_ci Address constant_pool); 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ci // Read/Modify the code target address in the branch/call instruction at pc. 3621cb0ef41Sopenharmony_ci // The isolate argument is unused (and may be nullptr) when skipping flushing. 3631cb0ef41Sopenharmony_ci V8_INLINE static Address target_address_at(Address pc, Address constant_pool); 3641cb0ef41Sopenharmony_ci V8_INLINE static void set_target_address_at( 3651cb0ef41Sopenharmony_ci Address pc, Address constant_pool, Address target, 3661cb0ef41Sopenharmony_ci ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_ci // This sets the branch destination (which is in the constant pool on ARM). 3691cb0ef41Sopenharmony_ci // This is for calls and branches within generated code. 3701cb0ef41Sopenharmony_ci inline static void deserialization_set_special_target_at( 3711cb0ef41Sopenharmony_ci Address constant_pool_entry, Code code, Address target); 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci // Get the size of the special target encoded at 'location'. 3741cb0ef41Sopenharmony_ci inline static int deserialization_special_target_size(Address location); 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci // This sets the internal reference at the pc. 3771cb0ef41Sopenharmony_ci inline static void deserialization_set_target_internal_reference_at( 3781cb0ef41Sopenharmony_ci Address pc, Address target, 3791cb0ef41Sopenharmony_ci RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci // Here we are patching the address in the constant pool, not the actual call 3821cb0ef41Sopenharmony_ci // instruction. The address in the constant pool is the same size as a 3831cb0ef41Sopenharmony_ci // pointer. 3841cb0ef41Sopenharmony_ci static constexpr int kSpecialTargetSize = kPointerSize; 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci RegList* GetScratchRegisterList() { return &scratch_register_list_; } 3871cb0ef41Sopenharmony_ci VfpRegList* GetScratchVfpRegisterList() { 3881cb0ef41Sopenharmony_ci return &scratch_vfp_register_list_; 3891cb0ef41Sopenharmony_ci } 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci // --------------------------------------------------------------------------- 3921cb0ef41Sopenharmony_ci // Code generation 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ci // Insert the smallest number of nop instructions 3951cb0ef41Sopenharmony_ci // possible to align the pc offset to a multiple 3961cb0ef41Sopenharmony_ci // of m. m must be a power of 2 (>= 4). 3971cb0ef41Sopenharmony_ci void Align(int m); 3981cb0ef41Sopenharmony_ci // Insert the smallest number of zero bytes possible to align the pc offset 3991cb0ef41Sopenharmony_ci // to a mulitple of m. m must be a power of 2 (>= 2). 4001cb0ef41Sopenharmony_ci void DataAlign(int m); 4011cb0ef41Sopenharmony_ci // Aligns code to something that's optimal for a jump target for the platform. 4021cb0ef41Sopenharmony_ci void CodeTargetAlign(); 4031cb0ef41Sopenharmony_ci void LoopHeaderAlign() { CodeTargetAlign(); } 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ci // Branch instructions 4061cb0ef41Sopenharmony_ci void b(int branch_offset, Condition cond = al, 4071cb0ef41Sopenharmony_ci RelocInfo::Mode rmode = RelocInfo::NO_INFO); 4081cb0ef41Sopenharmony_ci void bl(int branch_offset, Condition cond = al, 4091cb0ef41Sopenharmony_ci RelocInfo::Mode rmode = RelocInfo::NO_INFO); 4101cb0ef41Sopenharmony_ci void blx(int branch_offset); // v5 and above 4111cb0ef41Sopenharmony_ci void blx(Register target, Condition cond = al); // v5 and above 4121cb0ef41Sopenharmony_ci void bx(Register target, Condition cond = al); // v5 and above, plus v4t 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci // Convenience branch instructions using labels 4151cb0ef41Sopenharmony_ci void b(Label* L, Condition cond = al); 4161cb0ef41Sopenharmony_ci void b(Condition cond, Label* L) { b(L, cond); } 4171cb0ef41Sopenharmony_ci void bl(Label* L, Condition cond = al); 4181cb0ef41Sopenharmony_ci void bl(Condition cond, Label* L) { bl(L, cond); } 4191cb0ef41Sopenharmony_ci void blx(Label* L); // v5 and above 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci // Data-processing instructions 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci void and_(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4241cb0ef41Sopenharmony_ci Condition cond = al); 4251cb0ef41Sopenharmony_ci void and_(Register dst, Register src1, Register src2, SBit s = LeaveCC, 4261cb0ef41Sopenharmony_ci Condition cond = al); 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci void eor(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4291cb0ef41Sopenharmony_ci Condition cond = al); 4301cb0ef41Sopenharmony_ci void eor(Register dst, Register src1, Register src2, SBit s = LeaveCC, 4311cb0ef41Sopenharmony_ci Condition cond = al); 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ci void sub(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4341cb0ef41Sopenharmony_ci Condition cond = al); 4351cb0ef41Sopenharmony_ci void sub(Register dst, Register src1, Register src2, SBit s = LeaveCC, 4361cb0ef41Sopenharmony_ci Condition cond = al); 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci void rsb(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4391cb0ef41Sopenharmony_ci Condition cond = al); 4401cb0ef41Sopenharmony_ci 4411cb0ef41Sopenharmony_ci void add(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4421cb0ef41Sopenharmony_ci Condition cond = al); 4431cb0ef41Sopenharmony_ci void add(Register dst, Register src1, Register src2, SBit s = LeaveCC, 4441cb0ef41Sopenharmony_ci Condition cond = al); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci void adc(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4471cb0ef41Sopenharmony_ci Condition cond = al); 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci void sbc(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4501cb0ef41Sopenharmony_ci Condition cond = al); 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci void rsc(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4531cb0ef41Sopenharmony_ci Condition cond = al); 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci void tst(Register src1, const Operand& src2, Condition cond = al); 4561cb0ef41Sopenharmony_ci void tst(Register src1, Register src2, Condition cond = al); 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_ci void teq(Register src1, const Operand& src2, Condition cond = al); 4591cb0ef41Sopenharmony_ci 4601cb0ef41Sopenharmony_ci void cmp(Register src1, const Operand& src2, Condition cond = al); 4611cb0ef41Sopenharmony_ci void cmp(Register src1, Register src2, Condition cond = al); 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al); 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ci void cmn(Register src1, const Operand& src2, Condition cond = al); 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci void orr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4681cb0ef41Sopenharmony_ci Condition cond = al); 4691cb0ef41Sopenharmony_ci void orr(Register dst, Register src1, Register src2, SBit s = LeaveCC, 4701cb0ef41Sopenharmony_ci Condition cond = al); 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci void mov(Register dst, const Operand& src, SBit s = LeaveCC, 4731cb0ef41Sopenharmony_ci Condition cond = al); 4741cb0ef41Sopenharmony_ci void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al); 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci // Load the position of the label relative to the generated code object 4771cb0ef41Sopenharmony_ci // pointer in a register. 4781cb0ef41Sopenharmony_ci void mov_label_offset(Register dst, Label* label); 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci // ARMv7 instructions for loading a 32 bit immediate in two instructions. 4811cb0ef41Sopenharmony_ci // The constant for movw and movt should be in the range 0-0xffff. 4821cb0ef41Sopenharmony_ci void movw(Register reg, uint32_t immediate, Condition cond = al); 4831cb0ef41Sopenharmony_ci void movt(Register reg, uint32_t immediate, Condition cond = al); 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_ci void bic(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4861cb0ef41Sopenharmony_ci Condition cond = al); 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ci void mvn(Register dst, const Operand& src, SBit s = LeaveCC, 4891cb0ef41Sopenharmony_ci Condition cond = al); 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci // Shift instructions 4921cb0ef41Sopenharmony_ci 4931cb0ef41Sopenharmony_ci void asr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4941cb0ef41Sopenharmony_ci Condition cond = al); 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci void lsl(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 4971cb0ef41Sopenharmony_ci Condition cond = al); 4981cb0ef41Sopenharmony_ci 4991cb0ef41Sopenharmony_ci void lsr(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, 5001cb0ef41Sopenharmony_ci Condition cond = al); 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci // Multiply instructions 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ci void mla(Register dst, Register src1, Register src2, Register srcA, 5051cb0ef41Sopenharmony_ci SBit s = LeaveCC, Condition cond = al); 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ci void mls(Register dst, Register src1, Register src2, Register srcA, 5081cb0ef41Sopenharmony_ci Condition cond = al); 5091cb0ef41Sopenharmony_ci 5101cb0ef41Sopenharmony_ci void sdiv(Register dst, Register src1, Register src2, Condition cond = al); 5111cb0ef41Sopenharmony_ci 5121cb0ef41Sopenharmony_ci void udiv(Register dst, Register src1, Register src2, Condition cond = al); 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci void mul(Register dst, Register src1, Register src2, SBit s = LeaveCC, 5151cb0ef41Sopenharmony_ci Condition cond = al); 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ci void smmla(Register dst, Register src1, Register src2, Register srcA, 5181cb0ef41Sopenharmony_ci Condition cond = al); 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci void smmul(Register dst, Register src1, Register src2, Condition cond = al); 5211cb0ef41Sopenharmony_ci 5221cb0ef41Sopenharmony_ci void smlal(Register dstL, Register dstH, Register src1, Register src2, 5231cb0ef41Sopenharmony_ci SBit s = LeaveCC, Condition cond = al); 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci void smull(Register dstL, Register dstH, Register src1, Register src2, 5261cb0ef41Sopenharmony_ci SBit s = LeaveCC, Condition cond = al); 5271cb0ef41Sopenharmony_ci 5281cb0ef41Sopenharmony_ci void umlal(Register dstL, Register dstH, Register src1, Register src2, 5291cb0ef41Sopenharmony_ci SBit s = LeaveCC, Condition cond = al); 5301cb0ef41Sopenharmony_ci 5311cb0ef41Sopenharmony_ci void umull(Register dstL, Register dstH, Register src1, Register src2, 5321cb0ef41Sopenharmony_ci SBit s = LeaveCC, Condition cond = al); 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci // Miscellaneous arithmetic instructions 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_ci void clz(Register dst, Register src, Condition cond = al); // v5 and above 5371cb0ef41Sopenharmony_ci 5381cb0ef41Sopenharmony_ci // Saturating instructions. v6 and above. 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_ci // Unsigned saturate. 5411cb0ef41Sopenharmony_ci // 5421cb0ef41Sopenharmony_ci // Saturate an optionally shifted signed value to an unsigned range. 5431cb0ef41Sopenharmony_ci // 5441cb0ef41Sopenharmony_ci // usat dst, #satpos, src 5451cb0ef41Sopenharmony_ci // usat dst, #satpos, src, lsl #sh 5461cb0ef41Sopenharmony_ci // usat dst, #satpos, src, asr #sh 5471cb0ef41Sopenharmony_ci // 5481cb0ef41Sopenharmony_ci // Register dst will contain: 5491cb0ef41Sopenharmony_ci // 5501cb0ef41Sopenharmony_ci // 0, if s < 0 5511cb0ef41Sopenharmony_ci // (1 << satpos) - 1, if s > ((1 << satpos) - 1) 5521cb0ef41Sopenharmony_ci // s, otherwise 5531cb0ef41Sopenharmony_ci // 5541cb0ef41Sopenharmony_ci // where s is the contents of src after shifting (if used.) 5551cb0ef41Sopenharmony_ci void usat(Register dst, int satpos, const Operand& src, Condition cond = al); 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci // Bitfield manipulation instructions. v7 and above. 5581cb0ef41Sopenharmony_ci 5591cb0ef41Sopenharmony_ci void ubfx(Register dst, Register src, int lsb, int width, 5601cb0ef41Sopenharmony_ci Condition cond = al); 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci void sbfx(Register dst, Register src, int lsb, int width, 5631cb0ef41Sopenharmony_ci Condition cond = al); 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci void bfc(Register dst, int lsb, int width, Condition cond = al); 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ci void bfi(Register dst, Register src, int lsb, int width, Condition cond = al); 5681cb0ef41Sopenharmony_ci 5691cb0ef41Sopenharmony_ci void pkhbt(Register dst, Register src1, const Operand& src2, 5701cb0ef41Sopenharmony_ci Condition cond = al); 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ci void pkhtb(Register dst, Register src1, const Operand& src2, 5731cb0ef41Sopenharmony_ci Condition cond = al); 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_ci void sxtb(Register dst, Register src, int rotate = 0, Condition cond = al); 5761cb0ef41Sopenharmony_ci void sxtab(Register dst, Register src1, Register src2, int rotate = 0, 5771cb0ef41Sopenharmony_ci Condition cond = al); 5781cb0ef41Sopenharmony_ci void sxth(Register dst, Register src, int rotate = 0, Condition cond = al); 5791cb0ef41Sopenharmony_ci void sxtah(Register dst, Register src1, Register src2, int rotate = 0, 5801cb0ef41Sopenharmony_ci Condition cond = al); 5811cb0ef41Sopenharmony_ci 5821cb0ef41Sopenharmony_ci void uxtb(Register dst, Register src, int rotate = 0, Condition cond = al); 5831cb0ef41Sopenharmony_ci void uxtab(Register dst, Register src1, Register src2, int rotate = 0, 5841cb0ef41Sopenharmony_ci Condition cond = al); 5851cb0ef41Sopenharmony_ci void uxtb16(Register dst, Register src, int rotate = 0, Condition cond = al); 5861cb0ef41Sopenharmony_ci void uxth(Register dst, Register src, int rotate = 0, Condition cond = al); 5871cb0ef41Sopenharmony_ci void uxtah(Register dst, Register src1, Register src2, int rotate = 0, 5881cb0ef41Sopenharmony_ci Condition cond = al); 5891cb0ef41Sopenharmony_ci 5901cb0ef41Sopenharmony_ci // Reverse the bits in a register. 5911cb0ef41Sopenharmony_ci void rbit(Register dst, Register src, Condition cond = al); 5921cb0ef41Sopenharmony_ci void rev(Register dst, Register src, Condition cond = al); 5931cb0ef41Sopenharmony_ci 5941cb0ef41Sopenharmony_ci // Status register access instructions 5951cb0ef41Sopenharmony_ci 5961cb0ef41Sopenharmony_ci void mrs(Register dst, SRegister s, Condition cond = al); 5971cb0ef41Sopenharmony_ci void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al); 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci // Load/Store instructions 6001cb0ef41Sopenharmony_ci void ldr(Register dst, const MemOperand& src, Condition cond = al); 6011cb0ef41Sopenharmony_ci void str(Register src, const MemOperand& dst, Condition cond = al); 6021cb0ef41Sopenharmony_ci void ldrb(Register dst, const MemOperand& src, Condition cond = al); 6031cb0ef41Sopenharmony_ci void strb(Register src, const MemOperand& dst, Condition cond = al); 6041cb0ef41Sopenharmony_ci void ldrh(Register dst, const MemOperand& src, Condition cond = al); 6051cb0ef41Sopenharmony_ci void strh(Register src, const MemOperand& dst, Condition cond = al); 6061cb0ef41Sopenharmony_ci void ldrsb(Register dst, const MemOperand& src, Condition cond = al); 6071cb0ef41Sopenharmony_ci void ldrsh(Register dst, const MemOperand& src, Condition cond = al); 6081cb0ef41Sopenharmony_ci void ldrd(Register dst1, Register dst2, const MemOperand& src, 6091cb0ef41Sopenharmony_ci Condition cond = al); 6101cb0ef41Sopenharmony_ci void strd(Register src1, Register src2, const MemOperand& dst, 6111cb0ef41Sopenharmony_ci Condition cond = al); 6121cb0ef41Sopenharmony_ci 6131cb0ef41Sopenharmony_ci // Load literal from a pc relative address. 6141cb0ef41Sopenharmony_ci void ldr_pcrel(Register dst, int imm12, Condition cond = al); 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci // Load/Store exclusive instructions 6171cb0ef41Sopenharmony_ci void ldrex(Register dst, Register src, Condition cond = al); 6181cb0ef41Sopenharmony_ci void strex(Register src1, Register src2, Register dst, Condition cond = al); 6191cb0ef41Sopenharmony_ci void ldrexb(Register dst, Register src, Condition cond = al); 6201cb0ef41Sopenharmony_ci void strexb(Register src1, Register src2, Register dst, Condition cond = al); 6211cb0ef41Sopenharmony_ci void ldrexh(Register dst, Register src, Condition cond = al); 6221cb0ef41Sopenharmony_ci void strexh(Register src1, Register src2, Register dst, Condition cond = al); 6231cb0ef41Sopenharmony_ci void ldrexd(Register dst1, Register dst2, Register src, Condition cond = al); 6241cb0ef41Sopenharmony_ci void strexd(Register res, Register src1, Register src2, Register dst, 6251cb0ef41Sopenharmony_ci Condition cond = al); 6261cb0ef41Sopenharmony_ci 6271cb0ef41Sopenharmony_ci // Preload instructions 6281cb0ef41Sopenharmony_ci void pld(const MemOperand& address); 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci // Load/Store multiple instructions 6311cb0ef41Sopenharmony_ci void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); 6321cb0ef41Sopenharmony_ci void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); 6331cb0ef41Sopenharmony_ci 6341cb0ef41Sopenharmony_ci // Exception-generating instructions and debugging support 6351cb0ef41Sopenharmony_ci void stop(Condition cond = al, int32_t code = kDefaultStopCode); 6361cb0ef41Sopenharmony_ci 6371cb0ef41Sopenharmony_ci void bkpt(uint32_t imm16); // v5 and above 6381cb0ef41Sopenharmony_ci void svc(uint32_t imm24, Condition cond = al); 6391cb0ef41Sopenharmony_ci 6401cb0ef41Sopenharmony_ci // Synchronization instructions. 6411cb0ef41Sopenharmony_ci // On ARMv6, an equivalent CP15 operation will be used. 6421cb0ef41Sopenharmony_ci void dmb(BarrierOption option); 6431cb0ef41Sopenharmony_ci void dsb(BarrierOption option); 6441cb0ef41Sopenharmony_ci void isb(BarrierOption option); 6451cb0ef41Sopenharmony_ci 6461cb0ef41Sopenharmony_ci // Conditional speculation barrier. 6471cb0ef41Sopenharmony_ci void csdb(); 6481cb0ef41Sopenharmony_ci 6491cb0ef41Sopenharmony_ci // Coprocessor instructions 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci void cdp(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, 6521cb0ef41Sopenharmony_ci CRegister crm, int opcode_2, Condition cond = al); 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci void cdp2(Coprocessor coproc, int opcode_1, CRegister crd, CRegister crn, 6551cb0ef41Sopenharmony_ci CRegister crm, 6561cb0ef41Sopenharmony_ci int opcode_2); // v5 and above 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci void mcr(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, 6591cb0ef41Sopenharmony_ci CRegister crm, int opcode_2 = 0, Condition cond = al); 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci void mcr2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, 6621cb0ef41Sopenharmony_ci CRegister crm, 6631cb0ef41Sopenharmony_ci int opcode_2 = 0); // v5 and above 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci void mrc(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, 6661cb0ef41Sopenharmony_ci CRegister crm, int opcode_2 = 0, Condition cond = al); 6671cb0ef41Sopenharmony_ci 6681cb0ef41Sopenharmony_ci void mrc2(Coprocessor coproc, int opcode_1, Register rd, CRegister crn, 6691cb0ef41Sopenharmony_ci CRegister crm, 6701cb0ef41Sopenharmony_ci int opcode_2 = 0); // v5 and above 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src, 6731cb0ef41Sopenharmony_ci LFlag l = Short, Condition cond = al); 6741cb0ef41Sopenharmony_ci void ldc(Coprocessor coproc, CRegister crd, Register base, int option, 6751cb0ef41Sopenharmony_ci LFlag l = Short, Condition cond = al); 6761cb0ef41Sopenharmony_ci 6771cb0ef41Sopenharmony_ci void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src, 6781cb0ef41Sopenharmony_ci LFlag l = Short); // v5 and above 6791cb0ef41Sopenharmony_ci void ldc2(Coprocessor coproc, CRegister crd, Register base, int option, 6801cb0ef41Sopenharmony_ci LFlag l = Short); // v5 and above 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci // Support for VFP. 6831cb0ef41Sopenharmony_ci // All these APIs support S0 to S31 and D0 to D31. 6841cb0ef41Sopenharmony_ci 6851cb0ef41Sopenharmony_ci void vldr(const DwVfpRegister dst, const Register base, int offset, 6861cb0ef41Sopenharmony_ci const Condition cond = al); 6871cb0ef41Sopenharmony_ci void vldr(const DwVfpRegister dst, const MemOperand& src, 6881cb0ef41Sopenharmony_ci const Condition cond = al); 6891cb0ef41Sopenharmony_ci 6901cb0ef41Sopenharmony_ci void vldr(const SwVfpRegister dst, const Register base, int offset, 6911cb0ef41Sopenharmony_ci const Condition cond = al); 6921cb0ef41Sopenharmony_ci void vldr(const SwVfpRegister dst, const MemOperand& src, 6931cb0ef41Sopenharmony_ci const Condition cond = al); 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci void vstr(const DwVfpRegister src, const Register base, int offset, 6961cb0ef41Sopenharmony_ci const Condition cond = al); 6971cb0ef41Sopenharmony_ci void vstr(const DwVfpRegister src, const MemOperand& dst, 6981cb0ef41Sopenharmony_ci const Condition cond = al); 6991cb0ef41Sopenharmony_ci 7001cb0ef41Sopenharmony_ci void vstr(const SwVfpRegister src, const Register base, int offset, 7011cb0ef41Sopenharmony_ci const Condition cond = al); 7021cb0ef41Sopenharmony_ci void vstr(const SwVfpRegister src, const MemOperand& dst, 7031cb0ef41Sopenharmony_ci const Condition cond = al); 7041cb0ef41Sopenharmony_ci 7051cb0ef41Sopenharmony_ci void vldm(BlockAddrMode am, Register base, DwVfpRegister first, 7061cb0ef41Sopenharmony_ci DwVfpRegister last, Condition cond = al); 7071cb0ef41Sopenharmony_ci 7081cb0ef41Sopenharmony_ci void vstm(BlockAddrMode am, Register base, DwVfpRegister first, 7091cb0ef41Sopenharmony_ci DwVfpRegister last, Condition cond = al); 7101cb0ef41Sopenharmony_ci 7111cb0ef41Sopenharmony_ci void vldm(BlockAddrMode am, Register base, SwVfpRegister first, 7121cb0ef41Sopenharmony_ci SwVfpRegister last, Condition cond = al); 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_ci void vstm(BlockAddrMode am, Register base, SwVfpRegister first, 7151cb0ef41Sopenharmony_ci SwVfpRegister last, Condition cond = al); 7161cb0ef41Sopenharmony_ci 7171cb0ef41Sopenharmony_ci void vmov(const SwVfpRegister dst, Float32 imm); 7181cb0ef41Sopenharmony_ci void vmov(const DwVfpRegister dst, base::Double imm, 7191cb0ef41Sopenharmony_ci const Register extra_scratch = no_reg); 7201cb0ef41Sopenharmony_ci void vmov(const SwVfpRegister dst, const SwVfpRegister src, 7211cb0ef41Sopenharmony_ci const Condition cond = al); 7221cb0ef41Sopenharmony_ci void vmov(const DwVfpRegister dst, const DwVfpRegister src, 7231cb0ef41Sopenharmony_ci const Condition cond = al); 7241cb0ef41Sopenharmony_ci void vmov(const DwVfpRegister dst, const Register src1, const Register src2, 7251cb0ef41Sopenharmony_ci const Condition cond = al); 7261cb0ef41Sopenharmony_ci void vmov(const Register dst1, const Register dst2, const DwVfpRegister src, 7271cb0ef41Sopenharmony_ci const Condition cond = al); 7281cb0ef41Sopenharmony_ci void vmov(const SwVfpRegister dst, const Register src, 7291cb0ef41Sopenharmony_ci const Condition cond = al); 7301cb0ef41Sopenharmony_ci void vmov(const Register dst, const SwVfpRegister src, 7311cb0ef41Sopenharmony_ci const Condition cond = al); 7321cb0ef41Sopenharmony_ci void vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, 7331cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7341cb0ef41Sopenharmony_ci const Condition cond = al); 7351cb0ef41Sopenharmony_ci void vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, 7361cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7371cb0ef41Sopenharmony_ci const Condition cond = al); 7381cb0ef41Sopenharmony_ci void vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, 7391cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7401cb0ef41Sopenharmony_ci const Condition cond = al); 7411cb0ef41Sopenharmony_ci void vcvt_f32_u32(const SwVfpRegister dst, const SwVfpRegister src, 7421cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7431cb0ef41Sopenharmony_ci const Condition cond = al); 7441cb0ef41Sopenharmony_ci void vcvt_s32_f32(const SwVfpRegister dst, const SwVfpRegister src, 7451cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7461cb0ef41Sopenharmony_ci const Condition cond = al); 7471cb0ef41Sopenharmony_ci void vcvt_u32_f32(const SwVfpRegister dst, const SwVfpRegister src, 7481cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7491cb0ef41Sopenharmony_ci const Condition cond = al); 7501cb0ef41Sopenharmony_ci void vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, 7511cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7521cb0ef41Sopenharmony_ci const Condition cond = al); 7531cb0ef41Sopenharmony_ci void vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, 7541cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7551cb0ef41Sopenharmony_ci const Condition cond = al); 7561cb0ef41Sopenharmony_ci void vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, 7571cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7581cb0ef41Sopenharmony_ci const Condition cond = al); 7591cb0ef41Sopenharmony_ci void vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, 7601cb0ef41Sopenharmony_ci VFPConversionMode mode = kDefaultRoundToZero, 7611cb0ef41Sopenharmony_ci const Condition cond = al); 7621cb0ef41Sopenharmony_ci void vcvt_f64_s32(const DwVfpRegister dst, int fraction_bits, 7631cb0ef41Sopenharmony_ci const Condition cond = al); 7641cb0ef41Sopenharmony_ci 7651cb0ef41Sopenharmony_ci void vmrs(const Register dst, const Condition cond = al); 7661cb0ef41Sopenharmony_ci void vmsr(const Register dst, const Condition cond = al); 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ci void vneg(const DwVfpRegister dst, const DwVfpRegister src, 7691cb0ef41Sopenharmony_ci const Condition cond = al); 7701cb0ef41Sopenharmony_ci void vneg(const SwVfpRegister dst, const SwVfpRegister src, 7711cb0ef41Sopenharmony_ci const Condition cond = al); 7721cb0ef41Sopenharmony_ci void vabs(const DwVfpRegister dst, const DwVfpRegister src, 7731cb0ef41Sopenharmony_ci const Condition cond = al); 7741cb0ef41Sopenharmony_ci void vabs(const SwVfpRegister dst, const SwVfpRegister src, 7751cb0ef41Sopenharmony_ci const Condition cond = al); 7761cb0ef41Sopenharmony_ci void vadd(const DwVfpRegister dst, const DwVfpRegister src1, 7771cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7781cb0ef41Sopenharmony_ci void vadd(const SwVfpRegister dst, const SwVfpRegister src1, 7791cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 7801cb0ef41Sopenharmony_ci void vsub(const DwVfpRegister dst, const DwVfpRegister src1, 7811cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7821cb0ef41Sopenharmony_ci void vsub(const SwVfpRegister dst, const SwVfpRegister src1, 7831cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 7841cb0ef41Sopenharmony_ci void vmul(const DwVfpRegister dst, const DwVfpRegister src1, 7851cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7861cb0ef41Sopenharmony_ci void vmul(const SwVfpRegister dst, const SwVfpRegister src1, 7871cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 7881cb0ef41Sopenharmony_ci void vmla(const DwVfpRegister dst, const DwVfpRegister src1, 7891cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7901cb0ef41Sopenharmony_ci void vmla(const SwVfpRegister dst, const SwVfpRegister src1, 7911cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 7921cb0ef41Sopenharmony_ci void vmls(const DwVfpRegister dst, const DwVfpRegister src1, 7931cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7941cb0ef41Sopenharmony_ci void vmls(const SwVfpRegister dst, const SwVfpRegister src1, 7951cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 7961cb0ef41Sopenharmony_ci void vdiv(const DwVfpRegister dst, const DwVfpRegister src1, 7971cb0ef41Sopenharmony_ci const DwVfpRegister src2, const Condition cond = al); 7981cb0ef41Sopenharmony_ci void vdiv(const SwVfpRegister dst, const SwVfpRegister src1, 7991cb0ef41Sopenharmony_ci const SwVfpRegister src2, const Condition cond = al); 8001cb0ef41Sopenharmony_ci void vcmp(const DwVfpRegister src1, const DwVfpRegister src2, 8011cb0ef41Sopenharmony_ci const Condition cond = al); 8021cb0ef41Sopenharmony_ci void vcmp(const SwVfpRegister src1, const SwVfpRegister src2, 8031cb0ef41Sopenharmony_ci const Condition cond = al); 8041cb0ef41Sopenharmony_ci void vcmp(const DwVfpRegister src1, const double src2, 8051cb0ef41Sopenharmony_ci const Condition cond = al); 8061cb0ef41Sopenharmony_ci void vcmp(const SwVfpRegister src1, const float src2, 8071cb0ef41Sopenharmony_ci const Condition cond = al); 8081cb0ef41Sopenharmony_ci 8091cb0ef41Sopenharmony_ci void vmaxnm(const DwVfpRegister dst, const DwVfpRegister src1, 8101cb0ef41Sopenharmony_ci const DwVfpRegister src2); 8111cb0ef41Sopenharmony_ci void vmaxnm(const SwVfpRegister dst, const SwVfpRegister src1, 8121cb0ef41Sopenharmony_ci const SwVfpRegister src2); 8131cb0ef41Sopenharmony_ci void vminnm(const DwVfpRegister dst, const DwVfpRegister src1, 8141cb0ef41Sopenharmony_ci const DwVfpRegister src2); 8151cb0ef41Sopenharmony_ci void vminnm(const SwVfpRegister dst, const SwVfpRegister src1, 8161cb0ef41Sopenharmony_ci const SwVfpRegister src2); 8171cb0ef41Sopenharmony_ci 8181cb0ef41Sopenharmony_ci // VSEL supports cond in {eq, ne, ge, lt, gt, le, vs, vc}. 8191cb0ef41Sopenharmony_ci void vsel(const Condition cond, const DwVfpRegister dst, 8201cb0ef41Sopenharmony_ci const DwVfpRegister src1, const DwVfpRegister src2); 8211cb0ef41Sopenharmony_ci void vsel(const Condition cond, const SwVfpRegister dst, 8221cb0ef41Sopenharmony_ci const SwVfpRegister src1, const SwVfpRegister src2); 8231cb0ef41Sopenharmony_ci 8241cb0ef41Sopenharmony_ci void vsqrt(const DwVfpRegister dst, const DwVfpRegister src, 8251cb0ef41Sopenharmony_ci const Condition cond = al); 8261cb0ef41Sopenharmony_ci void vsqrt(const SwVfpRegister dst, const SwVfpRegister src, 8271cb0ef41Sopenharmony_ci const Condition cond = al); 8281cb0ef41Sopenharmony_ci 8291cb0ef41Sopenharmony_ci // ARMv8 rounding instructions (Scalar). 8301cb0ef41Sopenharmony_ci void vrinta(const SwVfpRegister dst, const SwVfpRegister src); 8311cb0ef41Sopenharmony_ci void vrinta(const DwVfpRegister dst, const DwVfpRegister src); 8321cb0ef41Sopenharmony_ci void vrintn(const SwVfpRegister dst, const SwVfpRegister src); 8331cb0ef41Sopenharmony_ci void vrintn(const DwVfpRegister dst, const DwVfpRegister src); 8341cb0ef41Sopenharmony_ci void vrintm(const SwVfpRegister dst, const SwVfpRegister src); 8351cb0ef41Sopenharmony_ci void vrintm(const DwVfpRegister dst, const DwVfpRegister src); 8361cb0ef41Sopenharmony_ci void vrintp(const SwVfpRegister dst, const SwVfpRegister src); 8371cb0ef41Sopenharmony_ci void vrintp(const DwVfpRegister dst, const DwVfpRegister src); 8381cb0ef41Sopenharmony_ci void vrintz(const SwVfpRegister dst, const SwVfpRegister src, 8391cb0ef41Sopenharmony_ci const Condition cond = al); 8401cb0ef41Sopenharmony_ci void vrintz(const DwVfpRegister dst, const DwVfpRegister src, 8411cb0ef41Sopenharmony_ci const Condition cond = al); 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_ci // Support for NEON. 8441cb0ef41Sopenharmony_ci 8451cb0ef41Sopenharmony_ci // All these APIs support D0 to D31 and Q0 to Q15. 8461cb0ef41Sopenharmony_ci void vld1(NeonSize size, const NeonListOperand& dst, 8471cb0ef41Sopenharmony_ci const NeonMemOperand& src); 8481cb0ef41Sopenharmony_ci // vld1s(ingle element to one lane). 8491cb0ef41Sopenharmony_ci void vld1s(NeonSize size, const NeonListOperand& dst, uint8_t index, 8501cb0ef41Sopenharmony_ci const NeonMemOperand& src); 8511cb0ef41Sopenharmony_ci void vld1r(NeonSize size, const NeonListOperand& dst, 8521cb0ef41Sopenharmony_ci const NeonMemOperand& src); 8531cb0ef41Sopenharmony_ci void vst1(NeonSize size, const NeonListOperand& src, 8541cb0ef41Sopenharmony_ci const NeonMemOperand& dst); 8551cb0ef41Sopenharmony_ci // vst1s(single element from one lane). 8561cb0ef41Sopenharmony_ci void vst1s(NeonSize size, const NeonListOperand& src, uint8_t index, 8571cb0ef41Sopenharmony_ci const NeonMemOperand& dst); 8581cb0ef41Sopenharmony_ci // dt represents the narrower type 8591cb0ef41Sopenharmony_ci void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src); 8601cb0ef41Sopenharmony_ci // dst_dt represents the narrower type, src_dt represents the src type. 8611cb0ef41Sopenharmony_ci void vqmovn(NeonDataType dst_dt, NeonDataType src_dt, DwVfpRegister dst, 8621cb0ef41Sopenharmony_ci QwNeonRegister src); 8631cb0ef41Sopenharmony_ci 8641cb0ef41Sopenharmony_ci // Only unconditional core <-> scalar moves are currently supported. 8651cb0ef41Sopenharmony_ci void vmov(NeonDataType dt, DwVfpRegister dst, int index, Register src); 8661cb0ef41Sopenharmony_ci void vmov(NeonDataType dt, Register dst, DwVfpRegister src, int index); 8671cb0ef41Sopenharmony_ci 8681cb0ef41Sopenharmony_ci void vmov(DwVfpRegister dst, uint64_t imm); 8691cb0ef41Sopenharmony_ci void vmov(QwNeonRegister dst, uint64_t imm); 8701cb0ef41Sopenharmony_ci void vmov(QwNeonRegister dst, QwNeonRegister src); 8711cb0ef41Sopenharmony_ci void vdup(NeonSize size, QwNeonRegister dst, Register src); 8721cb0ef41Sopenharmony_ci void vdup(NeonSize size, QwNeonRegister dst, DwVfpRegister src, int index); 8731cb0ef41Sopenharmony_ci void vdup(NeonSize size, DwVfpRegister dst, DwVfpRegister src, int index); 8741cb0ef41Sopenharmony_ci 8751cb0ef41Sopenharmony_ci void vcvt_f32_s32(QwNeonRegister dst, QwNeonRegister src); 8761cb0ef41Sopenharmony_ci void vcvt_f32_u32(QwNeonRegister dst, QwNeonRegister src); 8771cb0ef41Sopenharmony_ci void vcvt_s32_f32(QwNeonRegister dst, QwNeonRegister src); 8781cb0ef41Sopenharmony_ci void vcvt_u32_f32(QwNeonRegister dst, QwNeonRegister src); 8791cb0ef41Sopenharmony_ci 8801cb0ef41Sopenharmony_ci void vmvn(QwNeonRegister dst, QwNeonRegister src); 8811cb0ef41Sopenharmony_ci void vswp(DwVfpRegister dst, DwVfpRegister src); 8821cb0ef41Sopenharmony_ci void vswp(QwNeonRegister dst, QwNeonRegister src); 8831cb0ef41Sopenharmony_ci void vabs(QwNeonRegister dst, QwNeonRegister src); 8841cb0ef41Sopenharmony_ci void vabs(NeonSize size, QwNeonRegister dst, QwNeonRegister src); 8851cb0ef41Sopenharmony_ci void vneg(QwNeonRegister dst, QwNeonRegister src); 8861cb0ef41Sopenharmony_ci void vneg(NeonSize size, QwNeonRegister dst, QwNeonRegister src); 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_ci void vand(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8891cb0ef41Sopenharmony_ci void vbic(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8901cb0ef41Sopenharmony_ci void veor(DwVfpRegister dst, DwVfpRegister src1, DwVfpRegister src2); 8911cb0ef41Sopenharmony_ci void veor(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8921cb0ef41Sopenharmony_ci void vbsl(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8931cb0ef41Sopenharmony_ci void vorr(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8941cb0ef41Sopenharmony_ci void vorn(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8951cb0ef41Sopenharmony_ci void vadd(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 8961cb0ef41Sopenharmony_ci void vadd(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, 8971cb0ef41Sopenharmony_ci QwNeonRegister src2); 8981cb0ef41Sopenharmony_ci void vqadd(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 8991cb0ef41Sopenharmony_ci QwNeonRegister src2); 9001cb0ef41Sopenharmony_ci void vsub(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9011cb0ef41Sopenharmony_ci void vsub(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, 9021cb0ef41Sopenharmony_ci QwNeonRegister src2); 9031cb0ef41Sopenharmony_ci void vqsub(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9041cb0ef41Sopenharmony_ci QwNeonRegister src2); 9051cb0ef41Sopenharmony_ci void vmlal(NeonDataType size, QwNeonRegister dst, DwVfpRegister src1, 9061cb0ef41Sopenharmony_ci DwVfpRegister src2); 9071cb0ef41Sopenharmony_ci void vmul(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9081cb0ef41Sopenharmony_ci void vmul(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, 9091cb0ef41Sopenharmony_ci QwNeonRegister src2); 9101cb0ef41Sopenharmony_ci void vmull(NeonDataType size, QwNeonRegister dst, DwVfpRegister src1, 9111cb0ef41Sopenharmony_ci DwVfpRegister src2); 9121cb0ef41Sopenharmony_ci void vmin(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9131cb0ef41Sopenharmony_ci void vmin(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9141cb0ef41Sopenharmony_ci QwNeonRegister src2); 9151cb0ef41Sopenharmony_ci void vmax(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9161cb0ef41Sopenharmony_ci void vmax(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9171cb0ef41Sopenharmony_ci QwNeonRegister src2); 9181cb0ef41Sopenharmony_ci void vpadd(DwVfpRegister dst, DwVfpRegister src1, DwVfpRegister src2); 9191cb0ef41Sopenharmony_ci void vpadd(NeonSize size, DwVfpRegister dst, DwVfpRegister src1, 9201cb0ef41Sopenharmony_ci DwVfpRegister src2); 9211cb0ef41Sopenharmony_ci void vpmin(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, 9221cb0ef41Sopenharmony_ci DwVfpRegister src2); 9231cb0ef41Sopenharmony_ci void vpmax(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, 9241cb0ef41Sopenharmony_ci DwVfpRegister src2); 9251cb0ef41Sopenharmony_ci 9261cb0ef41Sopenharmony_ci void vpadal(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src); 9271cb0ef41Sopenharmony_ci void vpaddl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src); 9281cb0ef41Sopenharmony_ci void vqrdmulh(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9291cb0ef41Sopenharmony_ci QwNeonRegister src2); 9301cb0ef41Sopenharmony_ci 9311cb0ef41Sopenharmony_ci // ARMv8 rounding instructions (NEON). 9321cb0ef41Sopenharmony_ci void vrintm(NeonDataType dt, const QwNeonRegister dst, 9331cb0ef41Sopenharmony_ci const QwNeonRegister src); 9341cb0ef41Sopenharmony_ci void vrintn(NeonDataType dt, const QwNeonRegister dst, 9351cb0ef41Sopenharmony_ci const QwNeonRegister src); 9361cb0ef41Sopenharmony_ci void vrintp(NeonDataType dt, const QwNeonRegister dst, 9371cb0ef41Sopenharmony_ci const QwNeonRegister src); 9381cb0ef41Sopenharmony_ci void vrintz(NeonDataType dt, const QwNeonRegister dst, 9391cb0ef41Sopenharmony_ci const QwNeonRegister src); 9401cb0ef41Sopenharmony_ci 9411cb0ef41Sopenharmony_ci void vshl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, int shift); 9421cb0ef41Sopenharmony_ci void vshl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, 9431cb0ef41Sopenharmony_ci QwNeonRegister shift); 9441cb0ef41Sopenharmony_ci void vshr(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src, int shift); 9451cb0ef41Sopenharmony_ci void vshr(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, int shift); 9461cb0ef41Sopenharmony_ci void vsli(NeonSize size, DwVfpRegister dst, DwVfpRegister src, int shift); 9471cb0ef41Sopenharmony_ci void vsri(NeonSize size, DwVfpRegister dst, DwVfpRegister src, int shift); 9481cb0ef41Sopenharmony_ci void vsra(NeonDataType size, DwVfpRegister dst, DwVfpRegister src, int imm); 9491cb0ef41Sopenharmony_ci 9501cb0ef41Sopenharmony_ci // vrecpe and vrsqrte only support floating point lanes. 9511cb0ef41Sopenharmony_ci void vrecpe(QwNeonRegister dst, QwNeonRegister src); 9521cb0ef41Sopenharmony_ci void vrsqrte(QwNeonRegister dst, QwNeonRegister src); 9531cb0ef41Sopenharmony_ci void vrecps(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9541cb0ef41Sopenharmony_ci void vrsqrts(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9551cb0ef41Sopenharmony_ci void vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, 9561cb0ef41Sopenharmony_ci QwNeonRegister src2); 9571cb0ef41Sopenharmony_ci void vceq(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9581cb0ef41Sopenharmony_ci void vceq(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, 9591cb0ef41Sopenharmony_ci QwNeonRegister src2); 9601cb0ef41Sopenharmony_ci void vceq(NeonSize size, QwNeonRegister dst, QwNeonRegister src, int value); 9611cb0ef41Sopenharmony_ci void vcge(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9621cb0ef41Sopenharmony_ci void vcge(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9631cb0ef41Sopenharmony_ci QwNeonRegister src2); 9641cb0ef41Sopenharmony_ci void vcgt(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2); 9651cb0ef41Sopenharmony_ci void vcgt(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9661cb0ef41Sopenharmony_ci QwNeonRegister src2); 9671cb0ef41Sopenharmony_ci void vclt(NeonSize size, QwNeonRegister dst, QwNeonRegister src, int value); 9681cb0ef41Sopenharmony_ci void vrhadd(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 9691cb0ef41Sopenharmony_ci QwNeonRegister src2); 9701cb0ef41Sopenharmony_ci void vext(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2, 9711cb0ef41Sopenharmony_ci int bytes); 9721cb0ef41Sopenharmony_ci void vzip(NeonSize size, DwVfpRegister src1, DwVfpRegister src2); 9731cb0ef41Sopenharmony_ci void vzip(NeonSize size, QwNeonRegister src1, QwNeonRegister src2); 9741cb0ef41Sopenharmony_ci void vuzp(NeonSize size, DwVfpRegister src1, DwVfpRegister src2); 9751cb0ef41Sopenharmony_ci void vuzp(NeonSize size, QwNeonRegister src1, QwNeonRegister src2); 9761cb0ef41Sopenharmony_ci void vrev16(NeonSize size, QwNeonRegister dst, QwNeonRegister src); 9771cb0ef41Sopenharmony_ci void vrev32(NeonSize size, QwNeonRegister dst, QwNeonRegister src); 9781cb0ef41Sopenharmony_ci void vrev64(NeonSize size, QwNeonRegister dst, QwNeonRegister src); 9791cb0ef41Sopenharmony_ci void vtrn(NeonSize size, DwVfpRegister src1, DwVfpRegister src2); 9801cb0ef41Sopenharmony_ci void vtrn(NeonSize size, QwNeonRegister src1, QwNeonRegister src2); 9811cb0ef41Sopenharmony_ci void vtbl(DwVfpRegister dst, const NeonListOperand& list, 9821cb0ef41Sopenharmony_ci DwVfpRegister index); 9831cb0ef41Sopenharmony_ci void vtbx(DwVfpRegister dst, const NeonListOperand& list, 9841cb0ef41Sopenharmony_ci DwVfpRegister index); 9851cb0ef41Sopenharmony_ci 9861cb0ef41Sopenharmony_ci void vcnt(QwNeonRegister dst, QwNeonRegister src); 9871cb0ef41Sopenharmony_ci 9881cb0ef41Sopenharmony_ci // Pseudo instructions 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci // Different nop operations are used by the code generator to detect certain 9911cb0ef41Sopenharmony_ci // states of the generated code. 9921cb0ef41Sopenharmony_ci enum NopMarkerTypes { 9931cb0ef41Sopenharmony_ci NON_MARKING_NOP = 0, 9941cb0ef41Sopenharmony_ci DEBUG_BREAK_NOP, 9951cb0ef41Sopenharmony_ci // IC markers. 9961cb0ef41Sopenharmony_ci PROPERTY_ACCESS_INLINED, 9971cb0ef41Sopenharmony_ci PROPERTY_ACCESS_INLINED_CONTEXT, 9981cb0ef41Sopenharmony_ci PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, 9991cb0ef41Sopenharmony_ci // Helper values. 10001cb0ef41Sopenharmony_ci LAST_CODE_MARKER, 10011cb0ef41Sopenharmony_ci FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED 10021cb0ef41Sopenharmony_ci }; 10031cb0ef41Sopenharmony_ci 10041cb0ef41Sopenharmony_ci void nop(int type = 0); // 0 is the default non-marking type. 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ci void push(Register src, Condition cond = al) { 10071cb0ef41Sopenharmony_ci str(src, MemOperand(sp, 4, NegPreIndex), cond); 10081cb0ef41Sopenharmony_ci } 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci void pop(Register dst, Condition cond = al) { 10111cb0ef41Sopenharmony_ci ldr(dst, MemOperand(sp, 4, PostIndex), cond); 10121cb0ef41Sopenharmony_ci } 10131cb0ef41Sopenharmony_ci 10141cb0ef41Sopenharmony_ci void pop(); 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_ci void vpush(QwNeonRegister src, Condition cond = al) { 10171cb0ef41Sopenharmony_ci vstm(db_w, sp, src.low(), src.high(), cond); 10181cb0ef41Sopenharmony_ci } 10191cb0ef41Sopenharmony_ci 10201cb0ef41Sopenharmony_ci void vpush(DwVfpRegister src, Condition cond = al) { 10211cb0ef41Sopenharmony_ci vstm(db_w, sp, src, src, cond); 10221cb0ef41Sopenharmony_ci } 10231cb0ef41Sopenharmony_ci 10241cb0ef41Sopenharmony_ci void vpush(SwVfpRegister src, Condition cond = al) { 10251cb0ef41Sopenharmony_ci vstm(db_w, sp, src, src, cond); 10261cb0ef41Sopenharmony_ci } 10271cb0ef41Sopenharmony_ci 10281cb0ef41Sopenharmony_ci void vpop(DwVfpRegister dst, Condition cond = al) { 10291cb0ef41Sopenharmony_ci vldm(ia_w, sp, dst, dst, cond); 10301cb0ef41Sopenharmony_ci } 10311cb0ef41Sopenharmony_ci 10321cb0ef41Sopenharmony_ci // Jump unconditionally to given label. 10331cb0ef41Sopenharmony_ci void jmp(Label* L) { b(L, al); } 10341cb0ef41Sopenharmony_ci 10351cb0ef41Sopenharmony_ci // Check the code size generated from label to here. 10361cb0ef41Sopenharmony_ci int SizeOfCodeGeneratedSince(Label* label) { 10371cb0ef41Sopenharmony_ci return pc_offset() - label->pos(); 10381cb0ef41Sopenharmony_ci } 10391cb0ef41Sopenharmony_ci 10401cb0ef41Sopenharmony_ci // Check the number of instructions generated from label to here. 10411cb0ef41Sopenharmony_ci int InstructionsGeneratedSince(Label* label) { 10421cb0ef41Sopenharmony_ci return SizeOfCodeGeneratedSince(label) / kInstrSize; 10431cb0ef41Sopenharmony_ci } 10441cb0ef41Sopenharmony_ci 10451cb0ef41Sopenharmony_ci // Check whether an immediate fits an addressing mode 1 instruction. 10461cb0ef41Sopenharmony_ci static bool ImmediateFitsAddrMode1Instruction(int32_t imm32); 10471cb0ef41Sopenharmony_ci 10481cb0ef41Sopenharmony_ci // Check whether an immediate fits an addressing mode 2 instruction. 10491cb0ef41Sopenharmony_ci bool ImmediateFitsAddrMode2Instruction(int32_t imm32); 10501cb0ef41Sopenharmony_ci 10511cb0ef41Sopenharmony_ci // Class for scoping postponing the constant pool generation. 10521cb0ef41Sopenharmony_ci class V8_NODISCARD BlockConstPoolScope { 10531cb0ef41Sopenharmony_ci public: 10541cb0ef41Sopenharmony_ci explicit BlockConstPoolScope(Assembler* assem) : assem_(assem) { 10551cb0ef41Sopenharmony_ci assem_->StartBlockConstPool(); 10561cb0ef41Sopenharmony_ci } 10571cb0ef41Sopenharmony_ci ~BlockConstPoolScope() { assem_->EndBlockConstPool(); } 10581cb0ef41Sopenharmony_ci 10591cb0ef41Sopenharmony_ci private: 10601cb0ef41Sopenharmony_ci Assembler* const assem_; 10611cb0ef41Sopenharmony_ci 10621cb0ef41Sopenharmony_ci DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); 10631cb0ef41Sopenharmony_ci }; 10641cb0ef41Sopenharmony_ci 10651cb0ef41Sopenharmony_ci // Unused on this architecture. 10661cb0ef41Sopenharmony_ci void MaybeEmitOutOfLineConstantPool() {} 10671cb0ef41Sopenharmony_ci 10681cb0ef41Sopenharmony_ci // Record a deoptimization reason that can be used by a log or cpu profiler. 10691cb0ef41Sopenharmony_ci // Use --trace-deopt to enable. 10701cb0ef41Sopenharmony_ci void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id, 10711cb0ef41Sopenharmony_ci SourcePosition position, int id); 10721cb0ef41Sopenharmony_ci 10731cb0ef41Sopenharmony_ci // Record the emission of a constant pool. 10741cb0ef41Sopenharmony_ci // 10751cb0ef41Sopenharmony_ci // The emission of constant pool depends on the size of the code generated and 10761cb0ef41Sopenharmony_ci // the number of RelocInfo recorded. 10771cb0ef41Sopenharmony_ci // The Debug mechanism needs to map code offsets between two versions of a 10781cb0ef41Sopenharmony_ci // function, compiled with and without debugger support (see for example 10791cb0ef41Sopenharmony_ci // Debug::PrepareForBreakPoints()). 10801cb0ef41Sopenharmony_ci // Compiling functions with debugger support generates additional code 10811cb0ef41Sopenharmony_ci // (DebugCodegen::GenerateSlot()). This may affect the emission of the 10821cb0ef41Sopenharmony_ci // constant pools and cause the version of the code with debugger support to 10831cb0ef41Sopenharmony_ci // have constant pools generated in different places. 10841cb0ef41Sopenharmony_ci // Recording the position and size of emitted constant pools allows to 10851cb0ef41Sopenharmony_ci // correctly compute the offset mappings between the different versions of a 10861cb0ef41Sopenharmony_ci // function in all situations. 10871cb0ef41Sopenharmony_ci // 10881cb0ef41Sopenharmony_ci // The parameter indicates the size of the constant pool (in bytes), including 10891cb0ef41Sopenharmony_ci // the marker and branch over the data. 10901cb0ef41Sopenharmony_ci void RecordConstPool(int size); 10911cb0ef41Sopenharmony_ci 10921cb0ef41Sopenharmony_ci // Writes a single byte or word of data in the code stream. Used 10931cb0ef41Sopenharmony_ci // for inline tables, e.g., jump-tables. CheckConstantPool() should be 10941cb0ef41Sopenharmony_ci // called before any use of db/dd/dq/dp to ensure that constant pools 10951cb0ef41Sopenharmony_ci // are not emitted as part of the tables generated. 10961cb0ef41Sopenharmony_ci void db(uint8_t data); 10971cb0ef41Sopenharmony_ci void dd(uint32_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO); 10981cb0ef41Sopenharmony_ci void dq(uint64_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO); 10991cb0ef41Sopenharmony_ci void dp(uintptr_t data, RelocInfo::Mode rmode = RelocInfo::NO_INFO) { 11001cb0ef41Sopenharmony_ci dd(data, rmode); 11011cb0ef41Sopenharmony_ci } 11021cb0ef41Sopenharmony_ci 11031cb0ef41Sopenharmony_ci // Read/patch instructions 11041cb0ef41Sopenharmony_ci Instr instr_at(int pos) { 11051cb0ef41Sopenharmony_ci return *reinterpret_cast<Instr*>(buffer_start_ + pos); 11061cb0ef41Sopenharmony_ci } 11071cb0ef41Sopenharmony_ci void instr_at_put(int pos, Instr instr) { 11081cb0ef41Sopenharmony_ci *reinterpret_cast<Instr*>(buffer_start_ + pos) = instr; 11091cb0ef41Sopenharmony_ci } 11101cb0ef41Sopenharmony_ci static Instr instr_at(Address pc) { return *reinterpret_cast<Instr*>(pc); } 11111cb0ef41Sopenharmony_ci static void instr_at_put(Address pc, Instr instr) { 11121cb0ef41Sopenharmony_ci *reinterpret_cast<Instr*>(pc) = instr; 11131cb0ef41Sopenharmony_ci } 11141cb0ef41Sopenharmony_ci static Condition GetCondition(Instr instr); 11151cb0ef41Sopenharmony_ci static bool IsLdrRegisterImmediate(Instr instr); 11161cb0ef41Sopenharmony_ci static bool IsVldrDRegisterImmediate(Instr instr); 11171cb0ef41Sopenharmony_ci static int GetLdrRegisterImmediateOffset(Instr instr); 11181cb0ef41Sopenharmony_ci static int GetVldrDRegisterImmediateOffset(Instr instr); 11191cb0ef41Sopenharmony_ci static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); 11201cb0ef41Sopenharmony_ci static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); 11211cb0ef41Sopenharmony_ci static bool IsStrRegisterImmediate(Instr instr); 11221cb0ef41Sopenharmony_ci static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); 11231cb0ef41Sopenharmony_ci static bool IsAddRegisterImmediate(Instr instr); 11241cb0ef41Sopenharmony_ci static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); 11251cb0ef41Sopenharmony_ci static Register GetRd(Instr instr); 11261cb0ef41Sopenharmony_ci static Register GetRn(Instr instr); 11271cb0ef41Sopenharmony_ci static Register GetRm(Instr instr); 11281cb0ef41Sopenharmony_ci static bool IsPush(Instr instr); 11291cb0ef41Sopenharmony_ci static bool IsPop(Instr instr); 11301cb0ef41Sopenharmony_ci static bool IsStrRegFpOffset(Instr instr); 11311cb0ef41Sopenharmony_ci static bool IsLdrRegFpOffset(Instr instr); 11321cb0ef41Sopenharmony_ci static bool IsStrRegFpNegOffset(Instr instr); 11331cb0ef41Sopenharmony_ci static bool IsLdrRegFpNegOffset(Instr instr); 11341cb0ef41Sopenharmony_ci static bool IsLdrPcImmediateOffset(Instr instr); 11351cb0ef41Sopenharmony_ci static bool IsBOrBlPcImmediateOffset(Instr instr); 11361cb0ef41Sopenharmony_ci static bool IsVldrDPcImmediateOffset(Instr instr); 11371cb0ef41Sopenharmony_ci static bool IsBlxReg(Instr instr); 11381cb0ef41Sopenharmony_ci static bool IsBlxIp(Instr instr); 11391cb0ef41Sopenharmony_ci static bool IsTstImmediate(Instr instr); 11401cb0ef41Sopenharmony_ci static bool IsCmpRegister(Instr instr); 11411cb0ef41Sopenharmony_ci static bool IsCmpImmediate(Instr instr); 11421cb0ef41Sopenharmony_ci static Register GetCmpImmediateRegister(Instr instr); 11431cb0ef41Sopenharmony_ci static int GetCmpImmediateRawImmediate(Instr instr); 11441cb0ef41Sopenharmony_ci static bool IsNop(Instr instr, int type = NON_MARKING_NOP); 11451cb0ef41Sopenharmony_ci static bool IsMovImmed(Instr instr); 11461cb0ef41Sopenharmony_ci static bool IsOrrImmed(Instr instr); 11471cb0ef41Sopenharmony_ci static bool IsMovT(Instr instr); 11481cb0ef41Sopenharmony_ci static Instr GetMovTPattern(); 11491cb0ef41Sopenharmony_ci static bool IsMovW(Instr instr); 11501cb0ef41Sopenharmony_ci static Instr GetMovWPattern(); 11511cb0ef41Sopenharmony_ci static Instr EncodeMovwImmediate(uint32_t immediate); 11521cb0ef41Sopenharmony_ci static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate); 11531cb0ef41Sopenharmony_ci static int DecodeShiftImm(Instr instr); 11541cb0ef41Sopenharmony_ci static Instr PatchShiftImm(Instr instr, int immed); 11551cb0ef41Sopenharmony_ci 11561cb0ef41Sopenharmony_ci // Constants are accessed via pc relative addressing, which can reach −4095 to 11571cb0ef41Sopenharmony_ci // 4095 for integer PC-relative loads, and −1020 to 1020 for floating-point 11581cb0ef41Sopenharmony_ci // PC-relative loads, thereby defining a maximum distance between the 11591cb0ef41Sopenharmony_ci // instruction and the accessed constant. Additionally, PC-relative loads 11601cb0ef41Sopenharmony_ci // start at a delta from the actual load instruction's PC, so we can add this 11611cb0ef41Sopenharmony_ci // on to the (positive) distance. 11621cb0ef41Sopenharmony_ci static constexpr int kMaxDistToPcRelativeConstant = 11631cb0ef41Sopenharmony_ci 4095 + Instruction::kPcLoadDelta; 11641cb0ef41Sopenharmony_ci // The constant pool needs to be jumped over, and has a marker, so the actual 11651cb0ef41Sopenharmony_ci // distance from the instruction and start of the constant pool has to include 11661cb0ef41Sopenharmony_ci // space for these two instructions. 11671cb0ef41Sopenharmony_ci static constexpr int kMaxDistToIntPool = 11681cb0ef41Sopenharmony_ci kMaxDistToPcRelativeConstant - 2 * kInstrSize; 11691cb0ef41Sopenharmony_ci // Experimentally derived as sufficient for ~95% of compiles. 11701cb0ef41Sopenharmony_ci static constexpr int kTypicalNumPending32Constants = 32; 11711cb0ef41Sopenharmony_ci // The maximum number of pending constants is reached by a sequence of only 11721cb0ef41Sopenharmony_ci // constant loads, which limits it to the number of constant loads that can 11731cb0ef41Sopenharmony_ci // fit between the first constant load and the distance to the constant pool. 11741cb0ef41Sopenharmony_ci static constexpr int kMaxNumPending32Constants = 11751cb0ef41Sopenharmony_ci kMaxDistToIntPool / kInstrSize; 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_ci // Postpone the generation of the constant pool for the specified number of 11781cb0ef41Sopenharmony_ci // instructions. 11791cb0ef41Sopenharmony_ci void BlockConstPoolFor(int instructions); 11801cb0ef41Sopenharmony_ci 11811cb0ef41Sopenharmony_ci // Check if is time to emit a constant pool. 11821cb0ef41Sopenharmony_ci void CheckConstPool(bool force_emit, bool require_jump); 11831cb0ef41Sopenharmony_ci 11841cb0ef41Sopenharmony_ci V8_INLINE void MaybeCheckConstPool() { 11851cb0ef41Sopenharmony_ci if (V8_UNLIKELY(pc_offset() >= constant_pool_deadline_)) { 11861cb0ef41Sopenharmony_ci CheckConstPool(false, true); 11871cb0ef41Sopenharmony_ci } 11881cb0ef41Sopenharmony_ci } 11891cb0ef41Sopenharmony_ci 11901cb0ef41Sopenharmony_ci // Move a 32-bit immediate into a register, potentially via the constant pool. 11911cb0ef41Sopenharmony_ci void Move32BitImmediate(Register rd, const Operand& x, Condition cond = al); 11921cb0ef41Sopenharmony_ci 11931cb0ef41Sopenharmony_ci // Get the code target object for a pc-relative call or jump. 11941cb0ef41Sopenharmony_ci V8_INLINE Handle<Code> relative_code_target_object_handle_at( 11951cb0ef41Sopenharmony_ci Address pc_) const; 11961cb0ef41Sopenharmony_ci 11971cb0ef41Sopenharmony_ci protected: 11981cb0ef41Sopenharmony_ci int buffer_space() const { return reloc_info_writer.pos() - pc_; } 11991cb0ef41Sopenharmony_ci 12001cb0ef41Sopenharmony_ci // Decode branch instruction at pos and return branch target pos 12011cb0ef41Sopenharmony_ci int target_at(int pos); 12021cb0ef41Sopenharmony_ci 12031cb0ef41Sopenharmony_ci // Patch branch instruction at pos to branch to given branch target pos 12041cb0ef41Sopenharmony_ci void target_at_put(int pos, int target_pos); 12051cb0ef41Sopenharmony_ci 12061cb0ef41Sopenharmony_ci // Prevent contant pool emission until EndBlockConstPool is called. 12071cb0ef41Sopenharmony_ci // Calls to this function can be nested but must be followed by an equal 12081cb0ef41Sopenharmony_ci // number of call to EndBlockConstpool. 12091cb0ef41Sopenharmony_ci void StartBlockConstPool() { 12101cb0ef41Sopenharmony_ci if (const_pool_blocked_nesting_++ == 0) { 12111cb0ef41Sopenharmony_ci // Prevent constant pool checks happening by resetting the deadline. 12121cb0ef41Sopenharmony_ci constant_pool_deadline_ = kMaxInt; 12131cb0ef41Sopenharmony_ci } 12141cb0ef41Sopenharmony_ci } 12151cb0ef41Sopenharmony_ci 12161cb0ef41Sopenharmony_ci // Resume constant pool emission. Needs to be called as many times as 12171cb0ef41Sopenharmony_ci // StartBlockConstPool to have an effect. 12181cb0ef41Sopenharmony_ci void EndBlockConstPool() { 12191cb0ef41Sopenharmony_ci if (--const_pool_blocked_nesting_ == 0) { 12201cb0ef41Sopenharmony_ci if (first_const_pool_32_use_ >= 0) { 12211cb0ef41Sopenharmony_ci#ifdef DEBUG 12221cb0ef41Sopenharmony_ci // Check the constant pool hasn't been blocked for too long. 12231cb0ef41Sopenharmony_ci DCHECK_LE(pc_offset(), first_const_pool_32_use_ + kMaxDistToIntPool); 12241cb0ef41Sopenharmony_ci#endif 12251cb0ef41Sopenharmony_ci // Reset the constant pool check back to the deadline. 12261cb0ef41Sopenharmony_ci constant_pool_deadline_ = first_const_pool_32_use_ + kCheckPoolDeadline; 12271cb0ef41Sopenharmony_ci } 12281cb0ef41Sopenharmony_ci } 12291cb0ef41Sopenharmony_ci } 12301cb0ef41Sopenharmony_ci 12311cb0ef41Sopenharmony_ci bool is_const_pool_blocked() const { 12321cb0ef41Sopenharmony_ci return (const_pool_blocked_nesting_ > 0) || 12331cb0ef41Sopenharmony_ci (pc_offset() < no_const_pool_before_); 12341cb0ef41Sopenharmony_ci } 12351cb0ef41Sopenharmony_ci 12361cb0ef41Sopenharmony_ci bool has_pending_constants() const { 12371cb0ef41Sopenharmony_ci bool result = !pending_32_bit_constants_.empty(); 12381cb0ef41Sopenharmony_ci DCHECK_EQ(result, first_const_pool_32_use_ != -1); 12391cb0ef41Sopenharmony_ci return result; 12401cb0ef41Sopenharmony_ci } 12411cb0ef41Sopenharmony_ci 12421cb0ef41Sopenharmony_ci bool VfpRegisterIsAvailable(DwVfpRegister reg) { 12431cb0ef41Sopenharmony_ci DCHECK(reg.is_valid()); 12441cb0ef41Sopenharmony_ci return IsEnabled(VFP32DREGS) || 12451cb0ef41Sopenharmony_ci (reg.code() < LowDwVfpRegister::kNumRegisters); 12461cb0ef41Sopenharmony_ci } 12471cb0ef41Sopenharmony_ci 12481cb0ef41Sopenharmony_ci bool VfpRegisterIsAvailable(QwNeonRegister reg) { 12491cb0ef41Sopenharmony_ci DCHECK(reg.is_valid()); 12501cb0ef41Sopenharmony_ci return IsEnabled(VFP32DREGS) || 12511cb0ef41Sopenharmony_ci (reg.code() < LowDwVfpRegister::kNumRegisters / 2); 12521cb0ef41Sopenharmony_ci } 12531cb0ef41Sopenharmony_ci 12541cb0ef41Sopenharmony_ci inline void emit(Instr x); 12551cb0ef41Sopenharmony_ci 12561cb0ef41Sopenharmony_ci // Code generation 12571cb0ef41Sopenharmony_ci // The relocation writer's position is at least kGap bytes below the end of 12581cb0ef41Sopenharmony_ci // the generated instructions. This is so that multi-instruction sequences do 12591cb0ef41Sopenharmony_ci // not have to check for overflow. The same is true for writes of large 12601cb0ef41Sopenharmony_ci // relocation info entries. 12611cb0ef41Sopenharmony_ci static constexpr int kGap = 32; 12621cb0ef41Sopenharmony_ci STATIC_ASSERT(AssemblerBase::kMinimalBufferSize >= 2 * kGap); 12631cb0ef41Sopenharmony_ci 12641cb0ef41Sopenharmony_ci // Relocation info generation 12651cb0ef41Sopenharmony_ci // Each relocation is encoded as a variable size value 12661cb0ef41Sopenharmony_ci static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; 12671cb0ef41Sopenharmony_ci RelocInfoWriter reloc_info_writer; 12681cb0ef41Sopenharmony_ci 12691cb0ef41Sopenharmony_ci // ConstantPoolEntry records are used during code generation as temporary 12701cb0ef41Sopenharmony_ci // containers for constants and code target addresses until they are emitted 12711cb0ef41Sopenharmony_ci // to the constant pool. These records are temporarily stored in a separate 12721cb0ef41Sopenharmony_ci // buffer until a constant pool is emitted. 12731cb0ef41Sopenharmony_ci // If every instruction in a long sequence is accessing the pool, we need one 12741cb0ef41Sopenharmony_ci // pending relocation entry per instruction. 12751cb0ef41Sopenharmony_ci 12761cb0ef41Sopenharmony_ci // The buffers of pending constant pool entries. 12771cb0ef41Sopenharmony_ci base::SmallVector<ConstantPoolEntry, kTypicalNumPending32Constants> 12781cb0ef41Sopenharmony_ci pending_32_bit_constants_; 12791cb0ef41Sopenharmony_ci 12801cb0ef41Sopenharmony_ci // Scratch registers available for use by the Assembler. 12811cb0ef41Sopenharmony_ci RegList scratch_register_list_; 12821cb0ef41Sopenharmony_ci VfpRegList scratch_vfp_register_list_; 12831cb0ef41Sopenharmony_ci 12841cb0ef41Sopenharmony_ci private: 12851cb0ef41Sopenharmony_ci // Avoid overflows for displacements etc. 12861cb0ef41Sopenharmony_ci static const int kMaximalBufferSize = 512 * MB; 12871cb0ef41Sopenharmony_ci 12881cb0ef41Sopenharmony_ci // Constant pool generation 12891cb0ef41Sopenharmony_ci // Pools are emitted in the instruction stream, preferably after unconditional 12901cb0ef41Sopenharmony_ci // jumps or after returns from functions (in dead code locations). 12911cb0ef41Sopenharmony_ci // If a long code sequence does not contain unconditional jumps, it is 12921cb0ef41Sopenharmony_ci // necessary to emit the constant pool before the pool gets too far from the 12931cb0ef41Sopenharmony_ci // location it is accessed from. In this case, we emit a jump over the emitted 12941cb0ef41Sopenharmony_ci // constant pool. 12951cb0ef41Sopenharmony_ci // Constants in the pool may be addresses of functions that gets relocated; 12961cb0ef41Sopenharmony_ci // if so, a relocation info entry is associated to the constant pool entry. 12971cb0ef41Sopenharmony_ci 12981cb0ef41Sopenharmony_ci // Repeated checking whether the constant pool should be emitted is rather 12991cb0ef41Sopenharmony_ci // expensive. Instead, we check once a deadline is hit; the deadline being 13001cb0ef41Sopenharmony_ci // when there is a possibility that MaybeCheckConstPool won't be called before 13011cb0ef41Sopenharmony_ci // kMaxDistToIntPoolWithHeader is exceeded. Since MaybeCheckConstPool is 13021cb0ef41Sopenharmony_ci // called in CheckBuffer, this means that kGap is an upper bound on this 13031cb0ef41Sopenharmony_ci // check. Use 2 * kGap just to give it some slack around BlockConstPoolScopes. 13041cb0ef41Sopenharmony_ci static constexpr int kCheckPoolDeadline = kMaxDistToIntPool - 2 * kGap; 13051cb0ef41Sopenharmony_ci 13061cb0ef41Sopenharmony_ci // pc offset of the upcoming constant pool deadline. Equivalent to 13071cb0ef41Sopenharmony_ci // first_const_pool_32_use_ + kCheckPoolDeadline. 13081cb0ef41Sopenharmony_ci int constant_pool_deadline_; 13091cb0ef41Sopenharmony_ci 13101cb0ef41Sopenharmony_ci // Emission of the constant pool may be blocked in some code sequences. 13111cb0ef41Sopenharmony_ci int const_pool_blocked_nesting_; // Block emission if this is not zero. 13121cb0ef41Sopenharmony_ci int no_const_pool_before_; // Block emission before this pc offset. 13131cb0ef41Sopenharmony_ci 13141cb0ef41Sopenharmony_ci // Keep track of the first instruction requiring a constant pool entry 13151cb0ef41Sopenharmony_ci // since the previous constant pool was emitted. 13161cb0ef41Sopenharmony_ci int first_const_pool_32_use_; 13171cb0ef41Sopenharmony_ci 13181cb0ef41Sopenharmony_ci // The bound position, before this we cannot do instruction elimination. 13191cb0ef41Sopenharmony_ci int last_bound_pos_; 13201cb0ef41Sopenharmony_ci 13211cb0ef41Sopenharmony_ci V8_INLINE void CheckBuffer(); 13221cb0ef41Sopenharmony_ci void GrowBuffer(); 13231cb0ef41Sopenharmony_ci 13241cb0ef41Sopenharmony_ci // Instruction generation 13251cb0ef41Sopenharmony_ci void AddrMode1(Instr instr, Register rd, Register rn, const Operand& x); 13261cb0ef41Sopenharmony_ci // Attempt to encode operand |x| for instruction |instr| and return true on 13271cb0ef41Sopenharmony_ci // success. The result will be encoded in |instr| directly. This method may 13281cb0ef41Sopenharmony_ci // change the opcode if deemed beneficial, for instance, MOV may be turned 13291cb0ef41Sopenharmony_ci // into MVN, ADD into SUB, AND into BIC, ...etc. The only reason this method 13301cb0ef41Sopenharmony_ci // may fail is that the operand is an immediate that cannot be encoded. 13311cb0ef41Sopenharmony_ci bool AddrMode1TryEncodeOperand(Instr* instr, const Operand& x); 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ci void AddrMode2(Instr instr, Register rd, const MemOperand& x); 13341cb0ef41Sopenharmony_ci void AddrMode3(Instr instr, Register rd, const MemOperand& x); 13351cb0ef41Sopenharmony_ci void AddrMode4(Instr instr, Register rn, RegList rl); 13361cb0ef41Sopenharmony_ci void AddrMode5(Instr instr, CRegister crd, const MemOperand& x); 13371cb0ef41Sopenharmony_ci 13381cb0ef41Sopenharmony_ci // Labels 13391cb0ef41Sopenharmony_ci void print(const Label* L); 13401cb0ef41Sopenharmony_ci void bind_to(Label* L, int pos); 13411cb0ef41Sopenharmony_ci void next(Label* L); 13421cb0ef41Sopenharmony_ci 13431cb0ef41Sopenharmony_ci // Record reloc info for current pc_ 13441cb0ef41Sopenharmony_ci void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 13451cb0ef41Sopenharmony_ci void ConstantPoolAddEntry(int position, RelocInfo::Mode rmode, 13461cb0ef41Sopenharmony_ci intptr_t value); 13471cb0ef41Sopenharmony_ci void AllocateAndInstallRequestedHeapObjects(Isolate* isolate); 13481cb0ef41Sopenharmony_ci 13491cb0ef41Sopenharmony_ci int WriteCodeComments(); 13501cb0ef41Sopenharmony_ci 13511cb0ef41Sopenharmony_ci friend class RelocInfo; 13521cb0ef41Sopenharmony_ci friend class BlockConstPoolScope; 13531cb0ef41Sopenharmony_ci friend class EnsureSpace; 13541cb0ef41Sopenharmony_ci friend class UseScratchRegisterScope; 13551cb0ef41Sopenharmony_ci}; 13561cb0ef41Sopenharmony_ci 13571cb0ef41Sopenharmony_ciclass EnsureSpace { 13581cb0ef41Sopenharmony_ci public: 13591cb0ef41Sopenharmony_ci V8_INLINE explicit EnsureSpace(Assembler* assembler); 13601cb0ef41Sopenharmony_ci}; 13611cb0ef41Sopenharmony_ci 13621cb0ef41Sopenharmony_ciclass PatchingAssembler : public Assembler { 13631cb0ef41Sopenharmony_ci public: 13641cb0ef41Sopenharmony_ci PatchingAssembler(const AssemblerOptions& options, byte* address, 13651cb0ef41Sopenharmony_ci int instructions); 13661cb0ef41Sopenharmony_ci ~PatchingAssembler(); 13671cb0ef41Sopenharmony_ci 13681cb0ef41Sopenharmony_ci void Emit(Address addr); 13691cb0ef41Sopenharmony_ci void PadWithNops(); 13701cb0ef41Sopenharmony_ci}; 13711cb0ef41Sopenharmony_ci 13721cb0ef41Sopenharmony_ci// This scope utility allows scratch registers to be managed safely. The 13731cb0ef41Sopenharmony_ci// Assembler's GetScratchRegisterList() is used as a pool of scratch 13741cb0ef41Sopenharmony_ci// registers. These registers can be allocated on demand, and will be returned 13751cb0ef41Sopenharmony_ci// at the end of the scope. 13761cb0ef41Sopenharmony_ci// 13771cb0ef41Sopenharmony_ci// When the scope ends, the Assembler's list will be restored to its original 13781cb0ef41Sopenharmony_ci// state, even if the list is modified by some other means. Note that this scope 13791cb0ef41Sopenharmony_ci// can be nested but the destructors need to run in the opposite order as the 13801cb0ef41Sopenharmony_ci// constructors. We do not have assertions for this. 13811cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE V8_NODISCARD UseScratchRegisterScope { 13821cb0ef41Sopenharmony_ci public: 13831cb0ef41Sopenharmony_ci explicit UseScratchRegisterScope(Assembler* assembler); 13841cb0ef41Sopenharmony_ci ~UseScratchRegisterScope(); 13851cb0ef41Sopenharmony_ci 13861cb0ef41Sopenharmony_ci // Take a register from the list and return it. 13871cb0ef41Sopenharmony_ci Register Acquire(); 13881cb0ef41Sopenharmony_ci SwVfpRegister AcquireS() { return AcquireVfp<SwVfpRegister>(); } 13891cb0ef41Sopenharmony_ci LowDwVfpRegister AcquireLowD() { return AcquireVfp<LowDwVfpRegister>(); } 13901cb0ef41Sopenharmony_ci DwVfpRegister AcquireD() { 13911cb0ef41Sopenharmony_ci DwVfpRegister reg = AcquireVfp<DwVfpRegister>(); 13921cb0ef41Sopenharmony_ci DCHECK(assembler_->VfpRegisterIsAvailable(reg)); 13931cb0ef41Sopenharmony_ci return reg; 13941cb0ef41Sopenharmony_ci } 13951cb0ef41Sopenharmony_ci QwNeonRegister AcquireQ() { 13961cb0ef41Sopenharmony_ci QwNeonRegister reg = AcquireVfp<QwNeonRegister>(); 13971cb0ef41Sopenharmony_ci DCHECK(assembler_->VfpRegisterIsAvailable(reg)); 13981cb0ef41Sopenharmony_ci return reg; 13991cb0ef41Sopenharmony_ci } 14001cb0ef41Sopenharmony_ci 14011cb0ef41Sopenharmony_ci // Check if we have registers available to acquire. 14021cb0ef41Sopenharmony_ci bool CanAcquire() const { 14031cb0ef41Sopenharmony_ci return !assembler_->GetScratchRegisterList()->is_empty(); 14041cb0ef41Sopenharmony_ci } 14051cb0ef41Sopenharmony_ci bool CanAcquireD() const { return CanAcquireVfp<DwVfpRegister>(); } 14061cb0ef41Sopenharmony_ci 14071cb0ef41Sopenharmony_ci void Include(const Register& reg1, const Register& reg2 = no_reg) { 14081cb0ef41Sopenharmony_ci RegList* available = assembler_->GetScratchRegisterList(); 14091cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(available); 14101cb0ef41Sopenharmony_ci DCHECK(!available->has(reg1)); 14111cb0ef41Sopenharmony_ci DCHECK(!available->has(reg2)); 14121cb0ef41Sopenharmony_ci available->set(reg1); 14131cb0ef41Sopenharmony_ci available->set(reg2); 14141cb0ef41Sopenharmony_ci } 14151cb0ef41Sopenharmony_ci void Exclude(const Register& reg1, const Register& reg2 = no_reg) { 14161cb0ef41Sopenharmony_ci RegList* available = assembler_->GetScratchRegisterList(); 14171cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(available); 14181cb0ef41Sopenharmony_ci DCHECK(available->has(reg1)); 14191cb0ef41Sopenharmony_ci DCHECK_IMPLIES(reg2.is_valid(), available->has(reg2)); 14201cb0ef41Sopenharmony_ci available->clear(RegList{reg1, reg2}); 14211cb0ef41Sopenharmony_ci } 14221cb0ef41Sopenharmony_ci 14231cb0ef41Sopenharmony_ci private: 14241cb0ef41Sopenharmony_ci friend class Assembler; 14251cb0ef41Sopenharmony_ci friend class TurboAssembler; 14261cb0ef41Sopenharmony_ci 14271cb0ef41Sopenharmony_ci template <typename T> 14281cb0ef41Sopenharmony_ci bool CanAcquireVfp() const; 14291cb0ef41Sopenharmony_ci 14301cb0ef41Sopenharmony_ci template <typename T> 14311cb0ef41Sopenharmony_ci T AcquireVfp(); 14321cb0ef41Sopenharmony_ci 14331cb0ef41Sopenharmony_ci Assembler* assembler_; 14341cb0ef41Sopenharmony_ci // Available scratch registers at the start of this scope. 14351cb0ef41Sopenharmony_ci RegList old_available_; 14361cb0ef41Sopenharmony_ci VfpRegList old_available_vfp_; 14371cb0ef41Sopenharmony_ci}; 14381cb0ef41Sopenharmony_ci 14391cb0ef41Sopenharmony_ci// Helper struct for load lane and store lane to indicate which opcode to use 14401cb0ef41Sopenharmony_ci// and what memory size to be encoded in the opcode, and the new lane index. 14411cb0ef41Sopenharmony_ciclass LoadStoreLaneParams { 14421cb0ef41Sopenharmony_ci public: 14431cb0ef41Sopenharmony_ci bool low_op; 14441cb0ef41Sopenharmony_ci NeonSize sz; 14451cb0ef41Sopenharmony_ci uint8_t laneidx; 14461cb0ef41Sopenharmony_ci // The register mapping on ARM (1 Q to 2 D), means that loading/storing high 14471cb0ef41Sopenharmony_ci // lanes of a Q register is equivalent to loading/storing the high D reg, 14481cb0ef41Sopenharmony_ci // modulo number of lanes in a D reg. This constructor decides, based on the 14491cb0ef41Sopenharmony_ci // laneidx and load/store size, whether the low or high D reg is accessed, and 14501cb0ef41Sopenharmony_ci // what the new lane index is. 14511cb0ef41Sopenharmony_ci LoadStoreLaneParams(MachineRepresentation rep, uint8_t laneidx); 14521cb0ef41Sopenharmony_ci 14531cb0ef41Sopenharmony_ci private: 14541cb0ef41Sopenharmony_ci LoadStoreLaneParams(uint8_t laneidx, NeonSize sz, int lanes) 14551cb0ef41Sopenharmony_ci : low_op(laneidx < lanes), sz(sz), laneidx(laneidx % lanes) {} 14561cb0ef41Sopenharmony_ci}; 14571cb0ef41Sopenharmony_ci 14581cb0ef41Sopenharmony_ci} // namespace internal 14591cb0ef41Sopenharmony_ci} // namespace v8 14601cb0ef41Sopenharmony_ci 14611cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_ARM_ASSEMBLER_ARM_H_ 1462