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