11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H
61cb0ef41Sopenharmony_ci#error This header must be included via macro-assembler.h
71cb0ef41Sopenharmony_ci#endif
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_ARM_MACRO_ASSEMBLER_ARM_H_
101cb0ef41Sopenharmony_ci#define V8_CODEGEN_ARM_MACRO_ASSEMBLER_ARM_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "src/codegen/arm/assembler-arm.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/bailout-reason.h"
141cb0ef41Sopenharmony_ci#include "src/common/globals.h"
151cb0ef41Sopenharmony_ci#include "src/objects/tagged-index.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace v8 {
181cb0ef41Sopenharmony_cinamespace internal {
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// TODO(victorgomes): Move definition to macro-assembler.h, once all other
211cb0ef41Sopenharmony_ci// platforms are updated.
221cb0ef41Sopenharmony_cienum class StackLimitKind { kInterruptStackLimit, kRealStackLimit };
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
251cb0ef41Sopenharmony_ci// Static helper functions
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci// Generate a MemOperand for loading a field from an object.
281cb0ef41Sopenharmony_ciinline MemOperand FieldMemOperand(Register object, int offset) {
291cb0ef41Sopenharmony_ci  return MemOperand(object, offset - kHeapObjectTag);
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cienum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciRegister GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
351cb0ef41Sopenharmony_ci                                   Register reg3 = no_reg,
361cb0ef41Sopenharmony_ci                                   Register reg4 = no_reg,
371cb0ef41Sopenharmony_ci                                   Register reg5 = no_reg,
381cb0ef41Sopenharmony_ci                                   Register reg6 = no_reg);
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cienum TargetAddressStorageMode {
411cb0ef41Sopenharmony_ci  CAN_INLINE_TARGET_ADDRESS,
421cb0ef41Sopenharmony_ci  NEVER_INLINE_TARGET_ADDRESS
431cb0ef41Sopenharmony_ci};
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
461cb0ef41Sopenharmony_ci public:
471cb0ef41Sopenharmony_ci  using TurboAssemblerBase::TurboAssemblerBase;
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // Activation support.
501cb0ef41Sopenharmony_ci  void EnterFrame(StackFrame::Type type,
511cb0ef41Sopenharmony_ci                  bool load_constant_pool_pointer_reg = false);
521cb0ef41Sopenharmony_ci  // Returns the pc offset at which the frame ends.
531cb0ef41Sopenharmony_ci  int LeaveFrame(StackFrame::Type type);
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci// Allocate stack space of given size (i.e. decrement {sp} by the value
561cb0ef41Sopenharmony_ci// stored in the given register, or by a constant). If you need to perform a
571cb0ef41Sopenharmony_ci// stack check, do it before calling this function because this function may
581cb0ef41Sopenharmony_ci// write into the newly allocated space. It may also overwrite the given
591cb0ef41Sopenharmony_ci// register's value, in the version that takes a register.
601cb0ef41Sopenharmony_ci#ifdef V8_OS_WIN
611cb0ef41Sopenharmony_ci  void AllocateStackSpace(Register bytes_scratch);
621cb0ef41Sopenharmony_ci  void AllocateStackSpace(int bytes);
631cb0ef41Sopenharmony_ci#else
641cb0ef41Sopenharmony_ci  void AllocateStackSpace(Register bytes) { sub(sp, sp, bytes); }
651cb0ef41Sopenharmony_ci  void AllocateStackSpace(int bytes) {
661cb0ef41Sopenharmony_ci    DCHECK_GE(bytes, 0);
671cb0ef41Sopenharmony_ci    if (bytes == 0) return;
681cb0ef41Sopenharmony_ci    sub(sp, sp, Operand(bytes));
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci#endif
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  // Push a fixed frame, consisting of lr, fp
731cb0ef41Sopenharmony_ci  void PushCommonFrame(Register marker_reg = no_reg);
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  // Generates function and stub prologue code.
761cb0ef41Sopenharmony_ci  void StubPrologue(StackFrame::Type type);
771cb0ef41Sopenharmony_ci  void Prologue();
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
801cb0ef41Sopenharmony_ci  enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
811cb0ef41Sopenharmony_ci  void DropArguments(Register count, ArgumentsCountType type,
821cb0ef41Sopenharmony_ci                     ArgumentsCountMode mode);
831cb0ef41Sopenharmony_ci  void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
841cb0ef41Sopenharmony_ci                                       ArgumentsCountType type,
851cb0ef41Sopenharmony_ci                                       ArgumentsCountMode mode);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  // Push a standard frame, consisting of lr, fp, context and JS function
881cb0ef41Sopenharmony_ci  void PushStandardFrame(Register function_reg);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  void InitializeRootRegister();
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  void Push(Register src) { push(src); }
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  void Push(Handle<HeapObject> handle);
951cb0ef41Sopenharmony_ci  void Push(Smi smi);
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  // Push two registers.  Pushes leftmost register first (to highest address).
981cb0ef41Sopenharmony_ci  void Push(Register src1, Register src2, Condition cond = al) {
991cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1001cb0ef41Sopenharmony_ci      stm(db_w, sp, {src1, src2}, cond);
1011cb0ef41Sopenharmony_ci    } else {
1021cb0ef41Sopenharmony_ci      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1031cb0ef41Sopenharmony_ci      str(src2, MemOperand(sp, 4, NegPreIndex), cond);
1041cb0ef41Sopenharmony_ci    }
1051cb0ef41Sopenharmony_ci  }
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  // Push three registers.  Pushes leftmost register first (to highest address).
1081cb0ef41Sopenharmony_ci  void Push(Register src1, Register src2, Register src3, Condition cond = al) {
1091cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1101cb0ef41Sopenharmony_ci      if (src2.code() > src3.code()) {
1111cb0ef41Sopenharmony_ci        stm(db_w, sp, {src1, src2, src3}, cond);
1121cb0ef41Sopenharmony_ci      } else {
1131cb0ef41Sopenharmony_ci        stm(db_w, sp, {src1, src2}, cond);
1141cb0ef41Sopenharmony_ci        str(src3, MemOperand(sp, 4, NegPreIndex), cond);
1151cb0ef41Sopenharmony_ci      }
1161cb0ef41Sopenharmony_ci    } else {
1171cb0ef41Sopenharmony_ci      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1181cb0ef41Sopenharmony_ci      Push(src2, src3, cond);
1191cb0ef41Sopenharmony_ci    }
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  // Push four registers.  Pushes leftmost register first (to highest address).
1231cb0ef41Sopenharmony_ci  void Push(Register src1, Register src2, Register src3, Register src4,
1241cb0ef41Sopenharmony_ci            Condition cond = al) {
1251cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1261cb0ef41Sopenharmony_ci      if (src2.code() > src3.code()) {
1271cb0ef41Sopenharmony_ci        if (src3.code() > src4.code()) {
1281cb0ef41Sopenharmony_ci          stm(db_w, sp, {src1, src2, src3, src4}, cond);
1291cb0ef41Sopenharmony_ci        } else {
1301cb0ef41Sopenharmony_ci          stm(db_w, sp, {src1, src2, src3}, cond);
1311cb0ef41Sopenharmony_ci          str(src4, MemOperand(sp, 4, NegPreIndex), cond);
1321cb0ef41Sopenharmony_ci        }
1331cb0ef41Sopenharmony_ci      } else {
1341cb0ef41Sopenharmony_ci        stm(db_w, sp, {src1, src2}, cond);
1351cb0ef41Sopenharmony_ci        Push(src3, src4, cond);
1361cb0ef41Sopenharmony_ci      }
1371cb0ef41Sopenharmony_ci    } else {
1381cb0ef41Sopenharmony_ci      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1391cb0ef41Sopenharmony_ci      Push(src2, src3, src4, cond);
1401cb0ef41Sopenharmony_ci    }
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  // Push five registers.  Pushes leftmost register first (to highest address).
1441cb0ef41Sopenharmony_ci  void Push(Register src1, Register src2, Register src3, Register src4,
1451cb0ef41Sopenharmony_ci            Register src5, Condition cond = al) {
1461cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1471cb0ef41Sopenharmony_ci      if (src2.code() > src3.code()) {
1481cb0ef41Sopenharmony_ci        if (src3.code() > src4.code()) {
1491cb0ef41Sopenharmony_ci          if (src4.code() > src5.code()) {
1501cb0ef41Sopenharmony_ci            stm(db_w, sp, {src1, src2, src3, src4, src5}, cond);
1511cb0ef41Sopenharmony_ci          } else {
1521cb0ef41Sopenharmony_ci            stm(db_w, sp, {src1, src2, src3, src4}, cond);
1531cb0ef41Sopenharmony_ci            str(src5, MemOperand(sp, 4, NegPreIndex), cond);
1541cb0ef41Sopenharmony_ci          }
1551cb0ef41Sopenharmony_ci        } else {
1561cb0ef41Sopenharmony_ci          stm(db_w, sp, {src1, src2, src3}, cond);
1571cb0ef41Sopenharmony_ci          Push(src4, src5, cond);
1581cb0ef41Sopenharmony_ci        }
1591cb0ef41Sopenharmony_ci      } else {
1601cb0ef41Sopenharmony_ci        stm(db_w, sp, {src1, src2}, cond);
1611cb0ef41Sopenharmony_ci        Push(src3, src4, src5, cond);
1621cb0ef41Sopenharmony_ci      }
1631cb0ef41Sopenharmony_ci    } else {
1641cb0ef41Sopenharmony_ci      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1651cb0ef41Sopenharmony_ci      Push(src2, src3, src4, src5, cond);
1661cb0ef41Sopenharmony_ci    }
1671cb0ef41Sopenharmony_ci  }
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  enum class PushArrayOrder { kNormal, kReverse };
1701cb0ef41Sopenharmony_ci  // `array` points to the first element (the lowest address).
1711cb0ef41Sopenharmony_ci  // `array` and `size` are not modified.
1721cb0ef41Sopenharmony_ci  void PushArray(Register array, Register size, Register scratch,
1731cb0ef41Sopenharmony_ci                 PushArrayOrder order = PushArrayOrder::kNormal);
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  void Pop(Register dst) { pop(dst); }
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  // Pop two registers. Pops rightmost register first (from lower address).
1781cb0ef41Sopenharmony_ci  void Pop(Register src1, Register src2, Condition cond = al) {
1791cb0ef41Sopenharmony_ci    DCHECK(src1 != src2);
1801cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1811cb0ef41Sopenharmony_ci      ldm(ia_w, sp, {src1, src2}, cond);
1821cb0ef41Sopenharmony_ci    } else {
1831cb0ef41Sopenharmony_ci      ldr(src2, MemOperand(sp, 4, PostIndex), cond);
1841cb0ef41Sopenharmony_ci      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
1851cb0ef41Sopenharmony_ci    }
1861cb0ef41Sopenharmony_ci  }
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  // Pop three registers.  Pops rightmost register first (from lower address).
1891cb0ef41Sopenharmony_ci  void Pop(Register src1, Register src2, Register src3, Condition cond = al) {
1901cb0ef41Sopenharmony_ci    DCHECK(!AreAliased(src1, src2, src3));
1911cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
1921cb0ef41Sopenharmony_ci      if (src2.code() > src3.code()) {
1931cb0ef41Sopenharmony_ci        ldm(ia_w, sp, {src1, src2, src3}, cond);
1941cb0ef41Sopenharmony_ci      } else {
1951cb0ef41Sopenharmony_ci        ldr(src3, MemOperand(sp, 4, PostIndex), cond);
1961cb0ef41Sopenharmony_ci        ldm(ia_w, sp, {src1, src2}, cond);
1971cb0ef41Sopenharmony_ci      }
1981cb0ef41Sopenharmony_ci    } else {
1991cb0ef41Sopenharmony_ci      Pop(src2, src3, cond);
2001cb0ef41Sopenharmony_ci      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
2011cb0ef41Sopenharmony_ci    }
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  // Pop four registers.  Pops rightmost register first (from lower address).
2051cb0ef41Sopenharmony_ci  void Pop(Register src1, Register src2, Register src3, Register src4,
2061cb0ef41Sopenharmony_ci           Condition cond = al) {
2071cb0ef41Sopenharmony_ci    DCHECK(!AreAliased(src1, src2, src3, src4));
2081cb0ef41Sopenharmony_ci    if (src1.code() > src2.code()) {
2091cb0ef41Sopenharmony_ci      if (src2.code() > src3.code()) {
2101cb0ef41Sopenharmony_ci        if (src3.code() > src4.code()) {
2111cb0ef41Sopenharmony_ci          ldm(ia_w, sp, {src1, src2, src3, src4}, cond);
2121cb0ef41Sopenharmony_ci        } else {
2131cb0ef41Sopenharmony_ci          ldr(src4, MemOperand(sp, 4, PostIndex), cond);
2141cb0ef41Sopenharmony_ci          ldm(ia_w, sp, {src1, src2, src3}, cond);
2151cb0ef41Sopenharmony_ci        }
2161cb0ef41Sopenharmony_ci      } else {
2171cb0ef41Sopenharmony_ci        Pop(src3, src4, cond);
2181cb0ef41Sopenharmony_ci        ldm(ia_w, sp, {src1, src2}, cond);
2191cb0ef41Sopenharmony_ci      }
2201cb0ef41Sopenharmony_ci    } else {
2211cb0ef41Sopenharmony_ci      Pop(src2, src3, src4, cond);
2221cb0ef41Sopenharmony_ci      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
2231cb0ef41Sopenharmony_ci    }
2241cb0ef41Sopenharmony_ci  }
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  // Before calling a C-function from generated code, align arguments on stack.
2271cb0ef41Sopenharmony_ci  // After aligning the frame, non-register arguments must be stored in
2281cb0ef41Sopenharmony_ci  // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
2291cb0ef41Sopenharmony_ci  // are word sized. If double arguments are used, this function assumes that
2301cb0ef41Sopenharmony_ci  // all double arguments are stored before core registers; otherwise the
2311cb0ef41Sopenharmony_ci  // correct alignment of the double values is not guaranteed.
2321cb0ef41Sopenharmony_ci  // Some compilers/platforms require the stack to be aligned when calling
2331cb0ef41Sopenharmony_ci  // C++ code.
2341cb0ef41Sopenharmony_ci  // Needs a scratch register to do some arithmetic. This register will be
2351cb0ef41Sopenharmony_ci  // trashed.
2361cb0ef41Sopenharmony_ci  void PrepareCallCFunction(int num_reg_arguments, int num_double_registers = 0,
2371cb0ef41Sopenharmony_ci                            Register scratch = no_reg);
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  // There are two ways of passing double arguments on ARM, depending on
2401cb0ef41Sopenharmony_ci  // whether soft or hard floating point ABI is used. These functions
2411cb0ef41Sopenharmony_ci  // abstract parameter passing for the three different ways we call
2421cb0ef41Sopenharmony_ci  // C functions from generated code.
2431cb0ef41Sopenharmony_ci  void MovToFloatParameter(DwVfpRegister src);
2441cb0ef41Sopenharmony_ci  void MovToFloatParameters(DwVfpRegister src1, DwVfpRegister src2);
2451cb0ef41Sopenharmony_ci  void MovToFloatResult(DwVfpRegister src);
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  // Calls a C function and cleans up the space for arguments allocated
2481cb0ef41Sopenharmony_ci  // by PrepareCallCFunction. The called function is not allowed to trigger a
2491cb0ef41Sopenharmony_ci  // garbage collection, since that might move the code and invalidate the
2501cb0ef41Sopenharmony_ci  // return address (unless this is somehow accounted for by the called
2511cb0ef41Sopenharmony_ci  // function).
2521cb0ef41Sopenharmony_ci  void CallCFunction(ExternalReference function, int num_arguments);
2531cb0ef41Sopenharmony_ci  void CallCFunction(Register function, int num_arguments);
2541cb0ef41Sopenharmony_ci  void CallCFunction(ExternalReference function, int num_reg_arguments,
2551cb0ef41Sopenharmony_ci                     int num_double_arguments);
2561cb0ef41Sopenharmony_ci  void CallCFunction(Register function, int num_reg_arguments,
2571cb0ef41Sopenharmony_ci                     int num_double_arguments);
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci  void MovFromFloatParameter(DwVfpRegister dst);
2601cb0ef41Sopenharmony_ci  void MovFromFloatResult(DwVfpRegister dst);
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci  void Trap();
2631cb0ef41Sopenharmony_ci  void DebugBreak();
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci  // Calls Abort(msg) if the condition cond is not satisfied.
2661cb0ef41Sopenharmony_ci  // Use --debug-code to enable.
2671cb0ef41Sopenharmony_ci  void Assert(Condition cond, AbortReason reason);
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  // Like Assert(), but without condition.
2701cb0ef41Sopenharmony_ci  // Use --debug-code to enable.
2711cb0ef41Sopenharmony_ci  void AssertUnreachable(AbortReason reason);
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci  // Like Assert(), but always enabled.
2741cb0ef41Sopenharmony_ci  void Check(Condition cond, AbortReason reason);
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  // Print a message to stdout and abort execution.
2771cb0ef41Sopenharmony_ci  void Abort(AbortReason msg);
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  void LslPair(Register dst_low, Register dst_high, Register src_low,
2801cb0ef41Sopenharmony_ci               Register src_high, Register shift);
2811cb0ef41Sopenharmony_ci  void LslPair(Register dst_low, Register dst_high, Register src_low,
2821cb0ef41Sopenharmony_ci               Register src_high, uint32_t shift);
2831cb0ef41Sopenharmony_ci  void LsrPair(Register dst_low, Register dst_high, Register src_low,
2841cb0ef41Sopenharmony_ci               Register src_high, Register shift);
2851cb0ef41Sopenharmony_ci  void LsrPair(Register dst_low, Register dst_high, Register src_low,
2861cb0ef41Sopenharmony_ci               Register src_high, uint32_t shift);
2871cb0ef41Sopenharmony_ci  void AsrPair(Register dst_low, Register dst_high, Register src_low,
2881cb0ef41Sopenharmony_ci               Register src_high, Register shift);
2891cb0ef41Sopenharmony_ci  void AsrPair(Register dst_low, Register dst_high, Register src_low,
2901cb0ef41Sopenharmony_ci               Register src_high, uint32_t shift);
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci  void LoadFromConstantsTable(Register destination, int constant_index) final;
2931cb0ef41Sopenharmony_ci  void LoadRootRegisterOffset(Register destination, intptr_t offset) final;
2941cb0ef41Sopenharmony_ci  void LoadRootRelative(Register destination, int32_t offset) final;
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci  // Jump, Call, and Ret pseudo instructions implementing inter-working.
2971cb0ef41Sopenharmony_ci  void Call(Register target, Condition cond = al);
2981cb0ef41Sopenharmony_ci  void Call(Address target, RelocInfo::Mode rmode, Condition cond = al,
2991cb0ef41Sopenharmony_ci            TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS,
3001cb0ef41Sopenharmony_ci            bool check_constant_pool = true);
3011cb0ef41Sopenharmony_ci  void Call(Handle<Code> code, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
3021cb0ef41Sopenharmony_ci            Condition cond = al,
3031cb0ef41Sopenharmony_ci            TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS,
3041cb0ef41Sopenharmony_ci            bool check_constant_pool = true);
3051cb0ef41Sopenharmony_ci  void Call(Label* target);
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  MemOperand EntryFromBuiltinAsOperand(Builtin builtin);
3081cb0ef41Sopenharmony_ci  void LoadEntryFromBuiltin(Builtin builtin, Register destination);
3091cb0ef41Sopenharmony_ci  // Load the builtin given by the Smi in |builtin| into the same
3101cb0ef41Sopenharmony_ci  // register.
3111cb0ef41Sopenharmony_ci  void LoadEntryFromBuiltinIndex(Register builtin_index);
3121cb0ef41Sopenharmony_ci  void CallBuiltinByIndex(Register builtin_index);
3131cb0ef41Sopenharmony_ci  void CallBuiltin(Builtin builtin, Condition cond = al);
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci  void LoadCodeObjectEntry(Register destination, Register code_object);
3161cb0ef41Sopenharmony_ci  void CallCodeObject(Register code_object);
3171cb0ef41Sopenharmony_ci  void JumpCodeObject(Register code_object,
3181cb0ef41Sopenharmony_ci                      JumpMode jump_mode = JumpMode::kJump);
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  // Generates an instruction sequence s.t. the return address points to the
3211cb0ef41Sopenharmony_ci  // instruction following the call.
3221cb0ef41Sopenharmony_ci  // The return address on the stack is used by frame iteration.
3231cb0ef41Sopenharmony_ci  void StoreReturnAddressAndCall(Register target);
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci  void CallForDeoptimization(Builtin target, int deopt_id, Label* exit,
3261cb0ef41Sopenharmony_ci                             DeoptimizeKind kind, Label* ret,
3271cb0ef41Sopenharmony_ci                             Label* jump_deoptimization_entry_label);
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  // Emit code to discard a non-negative number of pointer-sized elements
3301cb0ef41Sopenharmony_ci  // from the stack, clobbering only the sp register.
3311cb0ef41Sopenharmony_ci  void Drop(int count, Condition cond = al);
3321cb0ef41Sopenharmony_ci  void Drop(Register count, Condition cond = al);
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci  void Ret(Condition cond = al);
3351cb0ef41Sopenharmony_ci  void Ret(int drop, Condition cond = al);
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  // Compare single values and move the result to the normal condition flags.
3381cb0ef41Sopenharmony_ci  void VFPCompareAndSetFlags(const SwVfpRegister src1, const SwVfpRegister src2,
3391cb0ef41Sopenharmony_ci                             const Condition cond = al);
3401cb0ef41Sopenharmony_ci  void VFPCompareAndSetFlags(const SwVfpRegister src1, const float src2,
3411cb0ef41Sopenharmony_ci                             const Condition cond = al);
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  // Compare double values and move the result to the normal condition flags.
3441cb0ef41Sopenharmony_ci  void VFPCompareAndSetFlags(const DwVfpRegister src1, const DwVfpRegister src2,
3451cb0ef41Sopenharmony_ci                             const Condition cond = al);
3461cb0ef41Sopenharmony_ci  void VFPCompareAndSetFlags(const DwVfpRegister src1, const double src2,
3471cb0ef41Sopenharmony_ci                             const Condition cond = al);
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  // If the value is a NaN, canonicalize the value else, do nothing.
3501cb0ef41Sopenharmony_ci  void VFPCanonicalizeNaN(const DwVfpRegister dst, const DwVfpRegister src,
3511cb0ef41Sopenharmony_ci                          const Condition cond = al);
3521cb0ef41Sopenharmony_ci  void VFPCanonicalizeNaN(const DwVfpRegister value,
3531cb0ef41Sopenharmony_ci                          const Condition cond = al) {
3541cb0ef41Sopenharmony_ci    VFPCanonicalizeNaN(value, value, cond);
3551cb0ef41Sopenharmony_ci  }
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  void VmovHigh(Register dst, DwVfpRegister src);
3581cb0ef41Sopenharmony_ci  void VmovHigh(DwVfpRegister dst, Register src);
3591cb0ef41Sopenharmony_ci  void VmovLow(Register dst, DwVfpRegister src);
3601cb0ef41Sopenharmony_ci  void VmovLow(DwVfpRegister dst, Register src);
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci  void CheckPageFlag(Register object, int mask, Condition cc,
3631cb0ef41Sopenharmony_ci                     Label* condition_met);
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci  // Check whether d16-d31 are available on the CPU. The result is given by the
3661cb0ef41Sopenharmony_ci  // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
3671cb0ef41Sopenharmony_ci  void CheckFor32DRegs(Register scratch);
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  void MaybeSaveRegisters(RegList registers);
3701cb0ef41Sopenharmony_ci  void MaybeRestoreRegisters(RegList registers);
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  void CallEphemeronKeyBarrier(Register object, Operand offset,
3731cb0ef41Sopenharmony_ci                               SaveFPRegsMode fp_mode);
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  void CallRecordWriteStubSaveRegisters(
3761cb0ef41Sopenharmony_ci      Register object, Operand offset,
3771cb0ef41Sopenharmony_ci      RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
3781cb0ef41Sopenharmony_ci      StubCallMode mode = StubCallMode::kCallBuiltinPointer);
3791cb0ef41Sopenharmony_ci  void CallRecordWriteStub(
3801cb0ef41Sopenharmony_ci      Register object, Register slot_address,
3811cb0ef41Sopenharmony_ci      RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
3821cb0ef41Sopenharmony_ci      StubCallMode mode = StubCallMode::kCallBuiltinPointer);
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ci  // For a given |object| and |offset|:
3851cb0ef41Sopenharmony_ci  //   - Move |object| to |dst_object|.
3861cb0ef41Sopenharmony_ci  //   - Compute the address of the slot pointed to by |offset| in |object| and
3871cb0ef41Sopenharmony_ci  //     write it to |dst_slot|. |offset| can be either an immediate or a
3881cb0ef41Sopenharmony_ci  //     register.
3891cb0ef41Sopenharmony_ci  // This method makes sure |object| and |offset| are allowed to overlap with
3901cb0ef41Sopenharmony_ci  // the destination registers.
3911cb0ef41Sopenharmony_ci  void MoveObjectAndSlot(Register dst_object, Register dst_slot,
3921cb0ef41Sopenharmony_ci                         Register object, Operand offset);
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  // Does a runtime check for 16/32 FP registers. Either way, pushes 32 double
3951cb0ef41Sopenharmony_ci  // values to location, saving [d0..(d15|d31)].
3961cb0ef41Sopenharmony_ci  void SaveFPRegs(Register location, Register scratch);
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  // Does a runtime check for 16/32 FP registers. Either way, pops 32 double
3991cb0ef41Sopenharmony_ci  // values to location, restoring [d0..(d15|d31)].
4001cb0ef41Sopenharmony_ci  void RestoreFPRegs(Register location, Register scratch);
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci  // As above, but with heap semantics instead of stack semantics, i.e.: the
4031cb0ef41Sopenharmony_ci  // location starts at the lowest address and grows towards higher addresses,
4041cb0ef41Sopenharmony_ci  // for both saves and restores.
4051cb0ef41Sopenharmony_ci  void SaveFPRegsToHeap(Register location, Register scratch);
4061cb0ef41Sopenharmony_ci  void RestoreFPRegsFromHeap(Register location, Register scratch);
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci  // Calculate how much stack space (in bytes) are required to store caller
4091cb0ef41Sopenharmony_ci  // registers excluding those specified in the arguments.
4101cb0ef41Sopenharmony_ci  int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
4111cb0ef41Sopenharmony_ci                                      Register exclusion1 = no_reg,
4121cb0ef41Sopenharmony_ci                                      Register exclusion2 = no_reg,
4131cb0ef41Sopenharmony_ci                                      Register exclusion3 = no_reg) const;
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci  // Push caller saved registers on the stack, and return the number of bytes
4161cb0ef41Sopenharmony_ci  // stack pointer is adjusted.
4171cb0ef41Sopenharmony_ci  int PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
4181cb0ef41Sopenharmony_ci                      Register exclusion2 = no_reg,
4191cb0ef41Sopenharmony_ci                      Register exclusion3 = no_reg);
4201cb0ef41Sopenharmony_ci  // Restore caller saved registers from the stack, and return the number of
4211cb0ef41Sopenharmony_ci  // bytes stack pointer is adjusted.
4221cb0ef41Sopenharmony_ci  int PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
4231cb0ef41Sopenharmony_ci                     Register exclusion2 = no_reg,
4241cb0ef41Sopenharmony_ci                     Register exclusion3 = no_reg);
4251cb0ef41Sopenharmony_ci  void Jump(Register target, Condition cond = al);
4261cb0ef41Sopenharmony_ci  void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al);
4271cb0ef41Sopenharmony_ci  void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
4281cb0ef41Sopenharmony_ci  void Jump(const ExternalReference& reference);
4291cb0ef41Sopenharmony_ci
4301cb0ef41Sopenharmony_ci  // Perform a floating-point min or max operation with the
4311cb0ef41Sopenharmony_ci  // (IEEE-754-compatible) semantics of ARM64's fmin/fmax. Some cases, typically
4321cb0ef41Sopenharmony_ci  // NaNs or +/-0.0, are expected to be rare and are handled in out-of-line
4331cb0ef41Sopenharmony_ci  // code. The specific behaviour depends on supported instructions.
4341cb0ef41Sopenharmony_ci  //
4351cb0ef41Sopenharmony_ci  // These functions assume (and assert) that left!=right. It is permitted
4361cb0ef41Sopenharmony_ci  // for the result to alias either input register.
4371cb0ef41Sopenharmony_ci  void FloatMax(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right,
4381cb0ef41Sopenharmony_ci                Label* out_of_line);
4391cb0ef41Sopenharmony_ci  void FloatMin(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right,
4401cb0ef41Sopenharmony_ci                Label* out_of_line);
4411cb0ef41Sopenharmony_ci  void FloatMax(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right,
4421cb0ef41Sopenharmony_ci                Label* out_of_line);
4431cb0ef41Sopenharmony_ci  void FloatMin(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right,
4441cb0ef41Sopenharmony_ci                Label* out_of_line);
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  // Generate out-of-line cases for the macros above.
4471cb0ef41Sopenharmony_ci  void FloatMaxOutOfLine(SwVfpRegister result, SwVfpRegister left,
4481cb0ef41Sopenharmony_ci                         SwVfpRegister right);
4491cb0ef41Sopenharmony_ci  void FloatMinOutOfLine(SwVfpRegister result, SwVfpRegister left,
4501cb0ef41Sopenharmony_ci                         SwVfpRegister right);
4511cb0ef41Sopenharmony_ci  void FloatMaxOutOfLine(DwVfpRegister result, DwVfpRegister left,
4521cb0ef41Sopenharmony_ci                         DwVfpRegister right);
4531cb0ef41Sopenharmony_ci  void FloatMinOutOfLine(DwVfpRegister result, DwVfpRegister left,
4541cb0ef41Sopenharmony_ci                         DwVfpRegister right);
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  void ExtractLane(Register dst, QwNeonRegister src, NeonDataType dt, int lane);
4571cb0ef41Sopenharmony_ci  void ExtractLane(Register dst, DwVfpRegister src, NeonDataType dt, int lane);
4581cb0ef41Sopenharmony_ci  void ExtractLane(SwVfpRegister dst, QwNeonRegister src, int lane);
4591cb0ef41Sopenharmony_ci  void ExtractLane(DwVfpRegister dst, QwNeonRegister src, int lane);
4601cb0ef41Sopenharmony_ci  void ReplaceLane(QwNeonRegister dst, QwNeonRegister src, Register src_lane,
4611cb0ef41Sopenharmony_ci                   NeonDataType dt, int lane);
4621cb0ef41Sopenharmony_ci  void ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
4631cb0ef41Sopenharmony_ci                   SwVfpRegister src_lane, int lane);
4641cb0ef41Sopenharmony_ci  void ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
4651cb0ef41Sopenharmony_ci                   DwVfpRegister src_lane, int lane);
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci  void LoadLane(NeonSize sz, NeonListOperand dst_list, uint8_t lane,
4681cb0ef41Sopenharmony_ci                NeonMemOperand src);
4691cb0ef41Sopenharmony_ci  void StoreLane(NeonSize sz, NeonListOperand src_list, uint8_t lane,
4701cb0ef41Sopenharmony_ci                 NeonMemOperand dst);
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci  // Register move. May do nothing if the registers are identical.
4731cb0ef41Sopenharmony_ci  void Move(Register dst, Smi smi);
4741cb0ef41Sopenharmony_ci  void Move(Register dst, Handle<HeapObject> value);
4751cb0ef41Sopenharmony_ci  void Move(Register dst, ExternalReference reference);
4761cb0ef41Sopenharmony_ci  void Move(Register dst, Register src, Condition cond = al);
4771cb0ef41Sopenharmony_ci  void Move(Register dst, const MemOperand& src) { ldr(dst, src); }
4781cb0ef41Sopenharmony_ci  void Move(Register dst, const Operand& src, SBit sbit = LeaveCC,
4791cb0ef41Sopenharmony_ci            Condition cond = al) {
4801cb0ef41Sopenharmony_ci    if (!src.IsRegister() || src.rm() != dst || sbit != LeaveCC) {
4811cb0ef41Sopenharmony_ci      mov(dst, src, sbit, cond);
4821cb0ef41Sopenharmony_ci    }
4831cb0ef41Sopenharmony_ci  }
4841cb0ef41Sopenharmony_ci  // Move src0 to dst0 and src1 to dst1, handling possible overlaps.
4851cb0ef41Sopenharmony_ci  void MovePair(Register dst0, Register src0, Register dst1, Register src1);
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci  void Move(SwVfpRegister dst, SwVfpRegister src, Condition cond = al);
4881cb0ef41Sopenharmony_ci  void Move(DwVfpRegister dst, DwVfpRegister src, Condition cond = al);
4891cb0ef41Sopenharmony_ci  void Move(QwNeonRegister dst, QwNeonRegister src);
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  // Simulate s-register moves for imaginary s32 - s63 registers.
4921cb0ef41Sopenharmony_ci  void VmovExtended(Register dst, int src_code);
4931cb0ef41Sopenharmony_ci  void VmovExtended(int dst_code, Register src);
4941cb0ef41Sopenharmony_ci  // Move between s-registers and imaginary s-registers.
4951cb0ef41Sopenharmony_ci  void VmovExtended(int dst_code, int src_code);
4961cb0ef41Sopenharmony_ci  void VmovExtended(int dst_code, const MemOperand& src);
4971cb0ef41Sopenharmony_ci  void VmovExtended(const MemOperand& dst, int src_code);
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ci  // Register swap. Note that the register operands should be distinct.
5001cb0ef41Sopenharmony_ci  void Swap(Register srcdst0, Register srcdst1);
5011cb0ef41Sopenharmony_ci  void Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1);
5021cb0ef41Sopenharmony_ci  void Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1);
5031cb0ef41Sopenharmony_ci
5041cb0ef41Sopenharmony_ci  // Get the actual activation frame alignment for target environment.
5051cb0ef41Sopenharmony_ci  static int ActivationFrameAlignment();
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_ci  void Bfc(Register dst, Register src, int lsb, int width, Condition cond = al);
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  void SmiUntag(Register reg, SBit s = LeaveCC) {
5101cb0ef41Sopenharmony_ci    mov(reg, Operand::SmiUntag(reg), s);
5111cb0ef41Sopenharmony_ci  }
5121cb0ef41Sopenharmony_ci  void SmiUntag(Register dst, Register src, SBit s = LeaveCC) {
5131cb0ef41Sopenharmony_ci    mov(dst, Operand::SmiUntag(src), s);
5141cb0ef41Sopenharmony_ci  }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  void SmiToInt32(Register smi) { SmiUntag(smi); }
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  // Load an object from the root table.
5191cb0ef41Sopenharmony_ci  void LoadRoot(Register destination, RootIndex index) final {
5201cb0ef41Sopenharmony_ci    LoadRoot(destination, index, al);
5211cb0ef41Sopenharmony_ci  }
5221cb0ef41Sopenharmony_ci  void LoadRoot(Register destination, RootIndex index, Condition cond);
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  // Jump if the register contains a smi.
5251cb0ef41Sopenharmony_ci  void JumpIfSmi(Register value, Label* smi_label);
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci  void JumpIfEqual(Register x, int32_t y, Label* dest);
5281cb0ef41Sopenharmony_ci  void JumpIfLessThan(Register x, int32_t y, Label* dest);
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci  void LoadMap(Register destination, Register object);
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ci  // Performs a truncating conversion of a floating point number as used by
5331cb0ef41Sopenharmony_ci  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
5341cb0ef41Sopenharmony_ci  // succeeds, otherwise falls through if result is saturated. On return
5351cb0ef41Sopenharmony_ci  // 'result' either holds answer, or is clobbered on fall through.
5361cb0ef41Sopenharmony_ci  void TryInlineTruncateDoubleToI(Register result, DwVfpRegister input,
5371cb0ef41Sopenharmony_ci                                  Label* done);
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  // Performs a truncating conversion of a floating point number as used by
5401cb0ef41Sopenharmony_ci  // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
5411cb0ef41Sopenharmony_ci  // Exits with 'result' holding the answer.
5421cb0ef41Sopenharmony_ci  void TruncateDoubleToI(Isolate* isolate, Zone* zone, Register result,
5431cb0ef41Sopenharmony_ci                         DwVfpRegister double_input, StubCallMode stub_mode);
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  // EABI variant for double arguments in use.
5461cb0ef41Sopenharmony_ci  bool use_eabi_hardfloat() {
5471cb0ef41Sopenharmony_ci#ifdef __arm__
5481cb0ef41Sopenharmony_ci    return base::OS::ArmUsingHardFloat();
5491cb0ef41Sopenharmony_ci#elif USE_EABI_HARDFLOAT
5501cb0ef41Sopenharmony_ci    return true;
5511cb0ef41Sopenharmony_ci#else
5521cb0ef41Sopenharmony_ci    return false;
5531cb0ef41Sopenharmony_ci#endif
5541cb0ef41Sopenharmony_ci  }
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci  // Compute the start of the generated instruction stream from the current PC.
5571cb0ef41Sopenharmony_ci  // This is an alternative to embedding the {CodeObject} handle as a reference.
5581cb0ef41Sopenharmony_ci  void ComputeCodeStartAddress(Register dst);
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci  // Control-flow integrity:
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  // Define a function entrypoint. This doesn't emit any code for this
5631cb0ef41Sopenharmony_ci  // architecture, as control-flow integrity is not supported for it.
5641cb0ef41Sopenharmony_ci  void CodeEntry() {}
5651cb0ef41Sopenharmony_ci  // Define an exception handler.
5661cb0ef41Sopenharmony_ci  void ExceptionHandler() {}
5671cb0ef41Sopenharmony_ci  // Define an exception handler and bind a label.
5681cb0ef41Sopenharmony_ci  void BindExceptionHandler(Label* label) { bind(label); }
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci  // Wasm SIMD helpers. These instructions don't have direct lowering to native
5711cb0ef41Sopenharmony_ci  // instructions. These helpers allow us to define the optimal code sequence,
5721cb0ef41Sopenharmony_ci  // and be used in both TurboFan and Liftoff.
5731cb0ef41Sopenharmony_ci  void I64x2BitMask(Register dst, QwNeonRegister src);
5741cb0ef41Sopenharmony_ci  void I64x2Eq(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
5751cb0ef41Sopenharmony_ci  void I64x2Ne(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
5761cb0ef41Sopenharmony_ci  void I64x2GtS(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
5771cb0ef41Sopenharmony_ci  void I64x2GeS(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2);
5781cb0ef41Sopenharmony_ci  void I64x2AllTrue(Register dst, QwNeonRegister src);
5791cb0ef41Sopenharmony_ci  void I64x2Abs(QwNeonRegister dst, QwNeonRegister src);
5801cb0ef41Sopenharmony_ci  void F64x2ConvertLowI32x4S(QwNeonRegister dst, QwNeonRegister src);
5811cb0ef41Sopenharmony_ci  void F64x2ConvertLowI32x4U(QwNeonRegister dst, QwNeonRegister src);
5821cb0ef41Sopenharmony_ci  void F64x2PromoteLowF32x4(QwNeonRegister dst, QwNeonRegister src);
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci private:
5851cb0ef41Sopenharmony_ci  // Compare single values and then load the fpscr flags to a register.
5861cb0ef41Sopenharmony_ci  void VFPCompareAndLoadFlags(const SwVfpRegister src1,
5871cb0ef41Sopenharmony_ci                              const SwVfpRegister src2,
5881cb0ef41Sopenharmony_ci                              const Register fpscr_flags,
5891cb0ef41Sopenharmony_ci                              const Condition cond = al);
5901cb0ef41Sopenharmony_ci  void VFPCompareAndLoadFlags(const SwVfpRegister src1, const float src2,
5911cb0ef41Sopenharmony_ci                              const Register fpscr_flags,
5921cb0ef41Sopenharmony_ci                              const Condition cond = al);
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_ci  // Compare double values and then load the fpscr flags to a register.
5951cb0ef41Sopenharmony_ci  void VFPCompareAndLoadFlags(const DwVfpRegister src1,
5961cb0ef41Sopenharmony_ci                              const DwVfpRegister src2,
5971cb0ef41Sopenharmony_ci                              const Register fpscr_flags,
5981cb0ef41Sopenharmony_ci                              const Condition cond = al);
5991cb0ef41Sopenharmony_ci  void VFPCompareAndLoadFlags(const DwVfpRegister src1, const double src2,
6001cb0ef41Sopenharmony_ci                              const Register fpscr_flags,
6011cb0ef41Sopenharmony_ci                              const Condition cond = al);
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ci  void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
6041cb0ef41Sopenharmony_ci
6051cb0ef41Sopenharmony_ci  // Implementation helpers for FloatMin and FloatMax.
6061cb0ef41Sopenharmony_ci  template <typename T>
6071cb0ef41Sopenharmony_ci  void FloatMaxHelper(T result, T left, T right, Label* out_of_line);
6081cb0ef41Sopenharmony_ci  template <typename T>
6091cb0ef41Sopenharmony_ci  void FloatMinHelper(T result, T left, T right, Label* out_of_line);
6101cb0ef41Sopenharmony_ci  template <typename T>
6111cb0ef41Sopenharmony_ci  void FloatMaxOutOfLineHelper(T result, T left, T right);
6121cb0ef41Sopenharmony_ci  template <typename T>
6131cb0ef41Sopenharmony_ci  void FloatMinOutOfLineHelper(T result, T left, T right);
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ci  int CalculateStackPassedWords(int num_reg_arguments,
6161cb0ef41Sopenharmony_ci                                int num_double_arguments);
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  void CallCFunctionHelper(Register function, int num_reg_arguments,
6191cb0ef41Sopenharmony_ci                           int num_double_arguments);
6201cb0ef41Sopenharmony_ci};
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci// MacroAssembler implements a collection of frequently used macros.
6231cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
6241cb0ef41Sopenharmony_ci public:
6251cb0ef41Sopenharmony_ci  using TurboAssembler::TurboAssembler;
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci  void Mls(Register dst, Register src1, Register src2, Register srcA,
6281cb0ef41Sopenharmony_ci           Condition cond = al);
6291cb0ef41Sopenharmony_ci  void And(Register dst, Register src1, const Operand& src2,
6301cb0ef41Sopenharmony_ci           Condition cond = al);
6311cb0ef41Sopenharmony_ci  void Ubfx(Register dst, Register src, int lsb, int width,
6321cb0ef41Sopenharmony_ci            Condition cond = al);
6331cb0ef41Sopenharmony_ci  void Sbfx(Register dst, Register src, int lsb, int width,
6341cb0ef41Sopenharmony_ci            Condition cond = al);
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
6371cb0ef41Sopenharmony_ci  // GC Support
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  // Notify the garbage collector that we wrote a pointer into an object.
6401cb0ef41Sopenharmony_ci  // |object| is the object being stored into, |value| is the object being
6411cb0ef41Sopenharmony_ci  // stored.
6421cb0ef41Sopenharmony_ci  // The offset is the offset from the start of the object, not the offset from
6431cb0ef41Sopenharmony_ci  // the tagged HeapObject pointer.  For use with FieldMemOperand(reg, off).
6441cb0ef41Sopenharmony_ci  void RecordWriteField(
6451cb0ef41Sopenharmony_ci      Register object, int offset, Register value, LinkRegisterStatus lr_status,
6461cb0ef41Sopenharmony_ci      SaveFPRegsMode save_fp,
6471cb0ef41Sopenharmony_ci      RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
6481cb0ef41Sopenharmony_ci      SmiCheck smi_check = SmiCheck::kInline);
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci  // For a given |object| notify the garbage collector that the slot at |offset|
6511cb0ef41Sopenharmony_ci  // has been written. |value| is the object being stored.
6521cb0ef41Sopenharmony_ci  void RecordWrite(
6531cb0ef41Sopenharmony_ci      Register object, Operand offset, Register value,
6541cb0ef41Sopenharmony_ci      LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
6551cb0ef41Sopenharmony_ci      RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
6561cb0ef41Sopenharmony_ci      SmiCheck smi_check = SmiCheck::kInline);
6571cb0ef41Sopenharmony_ci
6581cb0ef41Sopenharmony_ci  // Enter exit frame.
6591cb0ef41Sopenharmony_ci  // stack_space - extra stack space, used for alignment before call to C.
6601cb0ef41Sopenharmony_ci  void EnterExitFrame(bool save_doubles, int stack_space = 0,
6611cb0ef41Sopenharmony_ci                      StackFrame::Type frame_type = StackFrame::EXIT);
6621cb0ef41Sopenharmony_ci
6631cb0ef41Sopenharmony_ci  // Leave the current exit frame. Expects the return value in r0.
6641cb0ef41Sopenharmony_ci  // Expect the number of values, pushed prior to the exit frame, to
6651cb0ef41Sopenharmony_ci  // remove in a register (or no_reg, if there is nothing to remove).
6661cb0ef41Sopenharmony_ci  void LeaveExitFrame(bool save_doubles, Register argument_count,
6671cb0ef41Sopenharmony_ci                      bool argument_count_is_length = false);
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  // Load the global proxy from the current context.
6701cb0ef41Sopenharmony_ci  void LoadGlobalProxy(Register dst);
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci  void LoadNativeContextSlot(Register dst, int index);
6731cb0ef41Sopenharmony_ci
6741cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
6751cb0ef41Sopenharmony_ci  // JavaScript invokes
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci  // Invoke the JavaScript function code by either calling or jumping.
6781cb0ef41Sopenharmony_ci  void InvokeFunctionCode(Register function, Register new_target,
6791cb0ef41Sopenharmony_ci                          Register expected_parameter_count,
6801cb0ef41Sopenharmony_ci                          Register actual_parameter_count, InvokeType type);
6811cb0ef41Sopenharmony_ci
6821cb0ef41Sopenharmony_ci  // On function call, call into the debugger.
6831cb0ef41Sopenharmony_ci  void CallDebugOnFunctionCall(Register fun, Register new_target,
6841cb0ef41Sopenharmony_ci                               Register expected_parameter_count,
6851cb0ef41Sopenharmony_ci                               Register actual_parameter_count);
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci  // Invoke the JavaScript function in the given register. Changes the
6881cb0ef41Sopenharmony_ci  // current context to the context in the function before invoking.
6891cb0ef41Sopenharmony_ci  void InvokeFunctionWithNewTarget(Register function, Register new_target,
6901cb0ef41Sopenharmony_ci                                   Register actual_parameter_count,
6911cb0ef41Sopenharmony_ci                                   InvokeType type);
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_ci  void InvokeFunction(Register function, Register expected_parameter_count,
6941cb0ef41Sopenharmony_ci                      Register actual_parameter_count, InvokeType type);
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ci  // Exception handling
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci  // Push a new stack handler and link into stack handler chain.
6991cb0ef41Sopenharmony_ci  void PushStackHandler();
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci  // Unlink the stack handler on top of the stack from the stack handler chain.
7021cb0ef41Sopenharmony_ci  // Must preserve the result register.
7031cb0ef41Sopenharmony_ci  void PopStackHandler();
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
7061cb0ef41Sopenharmony_ci  // Support functions.
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci  // Compare object type for heap object.  heap_object contains a non-Smi
7091cb0ef41Sopenharmony_ci  // whose object type should be compared with the given type.  This both
7101cb0ef41Sopenharmony_ci  // sets the flags and leaves the object type in the type_reg register.
7111cb0ef41Sopenharmony_ci  // It leaves the map in the map register (unless the type_reg and map register
7121cb0ef41Sopenharmony_ci  // are the same register).  It leaves the heap object in the heap_object
7131cb0ef41Sopenharmony_ci  // register unless the heap_object register is the same register as one of the
7141cb0ef41Sopenharmony_ci  // other registers.
7151cb0ef41Sopenharmony_ci  // Type_reg can be no_reg. In that case a scratch register is used.
7161cb0ef41Sopenharmony_ci  void CompareObjectType(Register heap_object, Register map, Register type_reg,
7171cb0ef41Sopenharmony_ci                         InstanceType type);
7181cb0ef41Sopenharmony_ci
7191cb0ef41Sopenharmony_ci  // Compare instance type in a map.  map contains a valid map object whose
7201cb0ef41Sopenharmony_ci  // object type should be compared with the given type.  This both
7211cb0ef41Sopenharmony_ci  // sets the flags and leaves the object type in the type_reg register.
7221cb0ef41Sopenharmony_ci  void CompareInstanceType(Register map, Register type_reg, InstanceType type);
7231cb0ef41Sopenharmony_ci
7241cb0ef41Sopenharmony_ci  // Compare instance type ranges for a map (lower_limit and higher_limit
7251cb0ef41Sopenharmony_ci  // inclusive).
7261cb0ef41Sopenharmony_ci  //
7271cb0ef41Sopenharmony_ci  // Always use unsigned comparisons: ls for a positive result.
7281cb0ef41Sopenharmony_ci  void CompareInstanceTypeRange(Register map, Register type_reg,
7291cb0ef41Sopenharmony_ci                                InstanceType lower_limit,
7301cb0ef41Sopenharmony_ci                                InstanceType higher_limit);
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ci  // Compare the object in a register to a value from the root list.
7331cb0ef41Sopenharmony_ci  // Acquires a scratch register.
7341cb0ef41Sopenharmony_ci  void CompareRoot(Register obj, RootIndex index);
7351cb0ef41Sopenharmony_ci  void PushRoot(RootIndex index) {
7361cb0ef41Sopenharmony_ci    UseScratchRegisterScope temps(this);
7371cb0ef41Sopenharmony_ci    Register scratch = temps.Acquire();
7381cb0ef41Sopenharmony_ci    LoadRoot(scratch, index);
7391cb0ef41Sopenharmony_ci    Push(scratch);
7401cb0ef41Sopenharmony_ci  }
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_ci  // Compare the object in a register to a value and jump if they are equal.
7431cb0ef41Sopenharmony_ci  void JumpIfRoot(Register with, RootIndex index, Label* if_equal) {
7441cb0ef41Sopenharmony_ci    CompareRoot(with, index);
7451cb0ef41Sopenharmony_ci    b(eq, if_equal);
7461cb0ef41Sopenharmony_ci  }
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ci  // Compare the object in a register to a value and jump if they are not equal.
7491cb0ef41Sopenharmony_ci  void JumpIfNotRoot(Register with, RootIndex index, Label* if_not_equal) {
7501cb0ef41Sopenharmony_ci    CompareRoot(with, index);
7511cb0ef41Sopenharmony_ci    b(ne, if_not_equal);
7521cb0ef41Sopenharmony_ci  }
7531cb0ef41Sopenharmony_ci
7541cb0ef41Sopenharmony_ci  // Checks if value is in range [lower_limit, higher_limit] using a single
7551cb0ef41Sopenharmony_ci  // comparison. Flags C=0 or Z=1 indicate the value is in the range (condition
7561cb0ef41Sopenharmony_ci  // ls).
7571cb0ef41Sopenharmony_ci  void CompareRange(Register value, unsigned lower_limit,
7581cb0ef41Sopenharmony_ci                    unsigned higher_limit);
7591cb0ef41Sopenharmony_ci  void JumpIfIsInRange(Register value, unsigned lower_limit,
7601cb0ef41Sopenharmony_ci                       unsigned higher_limit, Label* on_in_range);
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ci  // It assumes that the arguments are located below the stack pointer.
7631cb0ef41Sopenharmony_ci  // argc is the number of arguments not including the receiver.
7641cb0ef41Sopenharmony_ci  // TODO(victorgomes): Remove this function once we stick with the reversed
7651cb0ef41Sopenharmony_ci  // arguments order.
7661cb0ef41Sopenharmony_ci  MemOperand ReceiverOperand(Register argc) {
7671cb0ef41Sopenharmony_ci    return MemOperand(sp, 0);
7681cb0ef41Sopenharmony_ci  }
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
7711cb0ef41Sopenharmony_ci  // Runtime calls
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci  // Call a runtime routine.
7741cb0ef41Sopenharmony_ci  void CallRuntime(const Runtime::Function* f, int num_arguments,
7751cb0ef41Sopenharmony_ci                   SaveFPRegsMode save_doubles = SaveFPRegsMode::kIgnore);
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci  // Convenience function: Same as above, but takes the fid instead.
7781cb0ef41Sopenharmony_ci  void CallRuntime(Runtime::FunctionId fid,
7791cb0ef41Sopenharmony_ci                   SaveFPRegsMode save_doubles = SaveFPRegsMode::kIgnore) {
7801cb0ef41Sopenharmony_ci    const Runtime::Function* function = Runtime::FunctionForId(fid);
7811cb0ef41Sopenharmony_ci    CallRuntime(function, function->nargs, save_doubles);
7821cb0ef41Sopenharmony_ci  }
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ci  // Convenience function: Same as above, but takes the fid instead.
7851cb0ef41Sopenharmony_ci  void CallRuntime(Runtime::FunctionId fid, int num_arguments,
7861cb0ef41Sopenharmony_ci                   SaveFPRegsMode save_doubles = SaveFPRegsMode::kIgnore) {
7871cb0ef41Sopenharmony_ci    CallRuntime(Runtime::FunctionForId(fid), num_arguments, save_doubles);
7881cb0ef41Sopenharmony_ci  }
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ci  // Convenience function: tail call a runtime routine (jump).
7911cb0ef41Sopenharmony_ci  void TailCallRuntime(Runtime::FunctionId fid);
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ci  // Jump to a runtime routine.
7941cb0ef41Sopenharmony_ci  void JumpToExternalReference(const ExternalReference& builtin,
7951cb0ef41Sopenharmony_ci                               bool builtin_exit_frame = false);
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci  // Generates a trampoline to jump to the off-heap instruction stream.
7981cb0ef41Sopenharmony_ci  void JumpToOffHeapInstructionStream(Address entry);
7991cb0ef41Sopenharmony_ci
8001cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
8011cb0ef41Sopenharmony_ci  // In-place weak references.
8021cb0ef41Sopenharmony_ci  void LoadWeakValue(Register out, Register in, Label* target_if_cleared);
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
8051cb0ef41Sopenharmony_ci  // StatsCounter support
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci  void IncrementCounter(StatsCounter* counter, int value, Register scratch1,
8081cb0ef41Sopenharmony_ci                        Register scratch2) {
8091cb0ef41Sopenharmony_ci    if (!FLAG_native_code_counters) return;
8101cb0ef41Sopenharmony_ci    EmitIncrementCounter(counter, value, scratch1, scratch2);
8111cb0ef41Sopenharmony_ci  }
8121cb0ef41Sopenharmony_ci  void EmitIncrementCounter(StatsCounter* counter, int value, Register scratch1,
8131cb0ef41Sopenharmony_ci                            Register scratch2);
8141cb0ef41Sopenharmony_ci  void DecrementCounter(StatsCounter* counter, int value, Register scratch1,
8151cb0ef41Sopenharmony_ci                        Register scratch2) {
8161cb0ef41Sopenharmony_ci    if (!FLAG_native_code_counters) return;
8171cb0ef41Sopenharmony_ci    EmitDecrementCounter(counter, value, scratch1, scratch2);
8181cb0ef41Sopenharmony_ci  }
8191cb0ef41Sopenharmony_ci  void EmitDecrementCounter(StatsCounter* counter, int value, Register scratch1,
8201cb0ef41Sopenharmony_ci                            Register scratch2);
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
8231cb0ef41Sopenharmony_ci  // Stack limit utilities
8241cb0ef41Sopenharmony_ci  void LoadStackLimit(Register destination, StackLimitKind kind);
8251cb0ef41Sopenharmony_ci  void StackOverflowCheck(Register num_args, Register scratch,
8261cb0ef41Sopenharmony_ci                          Label* stack_overflow);
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  // ---------------------------------------------------------------------------
8291cb0ef41Sopenharmony_ci  // Smi utilities
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci  void SmiTag(Register reg, SBit s = LeaveCC);
8321cb0ef41Sopenharmony_ci  void SmiTag(Register dst, Register src, SBit s = LeaveCC);
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  // Test if the register contains a smi (Z == 0 (eq) if true).
8351cb0ef41Sopenharmony_ci  void SmiTst(Register value);
8361cb0ef41Sopenharmony_ci  // Jump if either of the registers contain a non-smi.
8371cb0ef41Sopenharmony_ci  void JumpIfNotSmi(Register value, Label* not_smi_label);
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci  // Abort execution if argument is a smi, enabled via --debug-code.
8401cb0ef41Sopenharmony_ci  void AssertNotSmi(Register object);
8411cb0ef41Sopenharmony_ci  void AssertSmi(Register object);
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ci  // Abort execution if argument is not a Constructor, enabled via --debug-code.
8441cb0ef41Sopenharmony_ci  void AssertConstructor(Register object);
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_ci  // Abort execution if argument is not a JSFunction, enabled via --debug-code.
8471cb0ef41Sopenharmony_ci  void AssertFunction(Register object);
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci  // Abort execution if argument is not a callable JSFunction, enabled via
8501cb0ef41Sopenharmony_ci  // --debug-code.
8511cb0ef41Sopenharmony_ci  void AssertCallableFunction(Register object);
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  // Abort execution if argument is not a JSBoundFunction,
8541cb0ef41Sopenharmony_ci  // enabled via --debug-code.
8551cb0ef41Sopenharmony_ci  void AssertBoundFunction(Register object);
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci  // Abort execution if argument is not a JSGeneratorObject (or subclass),
8581cb0ef41Sopenharmony_ci  // enabled via --debug-code.
8591cb0ef41Sopenharmony_ci  void AssertGeneratorObject(Register object);
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_ci  // Abort execution if argument is not undefined or an AllocationSite, enabled
8621cb0ef41Sopenharmony_ci  // via --debug-code.
8631cb0ef41Sopenharmony_ci  void AssertUndefinedOrAllocationSite(Register object, Register scratch);
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  template <typename Field>
8661cb0ef41Sopenharmony_ci  void DecodeField(Register dst, Register src) {
8671cb0ef41Sopenharmony_ci    Ubfx(dst, src, Field::kShift, Field::kSize);
8681cb0ef41Sopenharmony_ci  }
8691cb0ef41Sopenharmony_ci
8701cb0ef41Sopenharmony_ci  template <typename Field>
8711cb0ef41Sopenharmony_ci  void DecodeField(Register reg) {
8721cb0ef41Sopenharmony_ci    DecodeField<Field>(reg, reg);
8731cb0ef41Sopenharmony_ci  }
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci private:
8761cb0ef41Sopenharmony_ci  // Helper functions for generating invokes.
8771cb0ef41Sopenharmony_ci  void InvokePrologue(Register expected_parameter_count,
8781cb0ef41Sopenharmony_ci                      Register actual_parameter_count, Label* done,
8791cb0ef41Sopenharmony_ci                      InvokeType type);
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ci  DISALLOW_IMPLICIT_CONSTRUCTORS(MacroAssembler);
8821cb0ef41Sopenharmony_ci};
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci#define ACCESS_MASM(masm) masm->
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci}  // namespace internal
8871cb0ef41Sopenharmony_ci}  // namespace v8
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_ARM_MACRO_ASSEMBLER_ARM_H_
890