11cb0ef41Sopenharmony_ci// Copyright 2017 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 V8_WASM_BASELINE_ARM64_LIFTOFF_ASSEMBLER_ARM64_H_
61cb0ef41Sopenharmony_ci#define V8_WASM_BASELINE_ARM64_LIFTOFF_ASSEMBLER_ARM64_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
91cb0ef41Sopenharmony_ci#include "src/heap/memory-chunk.h"
101cb0ef41Sopenharmony_ci#include "src/wasm/baseline/liftoff-assembler.h"
111cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_cinamespace wasm {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace liftoff {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciinline constexpr Condition ToCondition(LiftoffCondition liftoff_cond) {
201cb0ef41Sopenharmony_ci  switch (liftoff_cond) {
211cb0ef41Sopenharmony_ci    case kEqual:
221cb0ef41Sopenharmony_ci      return eq;
231cb0ef41Sopenharmony_ci    case kUnequal:
241cb0ef41Sopenharmony_ci      return ne;
251cb0ef41Sopenharmony_ci    case kSignedLessThan:
261cb0ef41Sopenharmony_ci      return lt;
271cb0ef41Sopenharmony_ci    case kSignedLessEqual:
281cb0ef41Sopenharmony_ci      return le;
291cb0ef41Sopenharmony_ci    case kSignedGreaterThan:
301cb0ef41Sopenharmony_ci      return gt;
311cb0ef41Sopenharmony_ci    case kSignedGreaterEqual:
321cb0ef41Sopenharmony_ci      return ge;
331cb0ef41Sopenharmony_ci    case kUnsignedLessThan:
341cb0ef41Sopenharmony_ci      return lo;
351cb0ef41Sopenharmony_ci    case kUnsignedLessEqual:
361cb0ef41Sopenharmony_ci      return ls;
371cb0ef41Sopenharmony_ci    case kUnsignedGreaterThan:
381cb0ef41Sopenharmony_ci      return hi;
391cb0ef41Sopenharmony_ci    case kUnsignedGreaterEqual:
401cb0ef41Sopenharmony_ci      return hs;
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci}
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci// Liftoff Frames.
451cb0ef41Sopenharmony_ci//
461cb0ef41Sopenharmony_ci//  slot      Frame
471cb0ef41Sopenharmony_ci//       +--------------------+---------------------------
481cb0ef41Sopenharmony_ci//  n+4  | optional padding slot to keep the stack 16 byte aligned.
491cb0ef41Sopenharmony_ci//  n+3  |   parameter n      |
501cb0ef41Sopenharmony_ci//  ...  |       ...          |
511cb0ef41Sopenharmony_ci//   4   |   parameter 1      | or parameter 2
521cb0ef41Sopenharmony_ci//   3   |   parameter 0      | or parameter 1
531cb0ef41Sopenharmony_ci//   2   |  (result address)  | or parameter 0
541cb0ef41Sopenharmony_ci//  -----+--------------------+---------------------------
551cb0ef41Sopenharmony_ci//   1   | return addr (lr)   |
561cb0ef41Sopenharmony_ci//   0   | previous frame (fp)|
571cb0ef41Sopenharmony_ci//  -----+--------------------+  <-- frame ptr (fp)
581cb0ef41Sopenharmony_ci//  -1   | StackFrame::WASM   |
591cb0ef41Sopenharmony_ci//  -2   |     instance       |
601cb0ef41Sopenharmony_ci//  -3   |     feedback vector|
611cb0ef41Sopenharmony_ci//  -4   |     tiering budget |
621cb0ef41Sopenharmony_ci//  -----+--------------------+---------------------------
631cb0ef41Sopenharmony_ci//  -5   |     slot 0         |   ^
641cb0ef41Sopenharmony_ci//  -6   |     slot 1         |   |
651cb0ef41Sopenharmony_ci//       |                    | Frame slots
661cb0ef41Sopenharmony_ci//       |                    |   |
671cb0ef41Sopenharmony_ci//       |                    |   v
681cb0ef41Sopenharmony_ci//       | optional padding slot to keep the stack 16 byte aligned.
691cb0ef41Sopenharmony_ci//  -----+--------------------+  <-- stack ptr (sp)
701cb0ef41Sopenharmony_ci//
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciconstexpr int kInstanceOffset = 2 * kSystemPointerSize;
731cb0ef41Sopenharmony_ciconstexpr int kFeedbackVectorOffset = 3 * kSystemPointerSize;
741cb0ef41Sopenharmony_ciconstexpr int kTierupBudgetOffset = 4 * kSystemPointerSize;
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ciinline MemOperand GetStackSlot(int offset) { return MemOperand(fp, -offset); }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciinline MemOperand GetInstanceOperand() { return GetStackSlot(kInstanceOffset); }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciinline CPURegister GetRegFromType(const LiftoffRegister& reg, ValueKind kind) {
811cb0ef41Sopenharmony_ci  switch (kind) {
821cb0ef41Sopenharmony_ci    case kI32:
831cb0ef41Sopenharmony_ci      return reg.gp().W();
841cb0ef41Sopenharmony_ci    case kI64:
851cb0ef41Sopenharmony_ci    case kRef:
861cb0ef41Sopenharmony_ci    case kOptRef:
871cb0ef41Sopenharmony_ci    case kRtt:
881cb0ef41Sopenharmony_ci      return reg.gp().X();
891cb0ef41Sopenharmony_ci    case kF32:
901cb0ef41Sopenharmony_ci      return reg.fp().S();
911cb0ef41Sopenharmony_ci    case kF64:
921cb0ef41Sopenharmony_ci      return reg.fp().D();
931cb0ef41Sopenharmony_ci    case kS128:
941cb0ef41Sopenharmony_ci      return reg.fp().Q();
951cb0ef41Sopenharmony_ci    default:
961cb0ef41Sopenharmony_ci      UNREACHABLE();
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci}
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ciinline CPURegList PadRegList(RegList list) {
1011cb0ef41Sopenharmony_ci  if ((list.Count() & 1) != 0) list.set(padreg);
1021cb0ef41Sopenharmony_ci  return CPURegList(kXRegSizeInBits, list);
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ciinline CPURegList PadVRegList(DoubleRegList list) {
1061cb0ef41Sopenharmony_ci  if ((list.Count() & 1) != 0) list.set(fp_scratch);
1071cb0ef41Sopenharmony_ci  return CPURegList(kQRegSizeInBits, list);
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ciinline CPURegister AcquireByType(UseScratchRegisterScope* temps,
1111cb0ef41Sopenharmony_ci                                 ValueKind kind) {
1121cb0ef41Sopenharmony_ci  switch (kind) {
1131cb0ef41Sopenharmony_ci    case kI32:
1141cb0ef41Sopenharmony_ci      return temps->AcquireW();
1151cb0ef41Sopenharmony_ci    case kI64:
1161cb0ef41Sopenharmony_ci    case kRef:
1171cb0ef41Sopenharmony_ci    case kOptRef:
1181cb0ef41Sopenharmony_ci      return temps->AcquireX();
1191cb0ef41Sopenharmony_ci    case kF32:
1201cb0ef41Sopenharmony_ci      return temps->AcquireS();
1211cb0ef41Sopenharmony_ci    case kF64:
1221cb0ef41Sopenharmony_ci      return temps->AcquireD();
1231cb0ef41Sopenharmony_ci    case kS128:
1241cb0ef41Sopenharmony_ci      return temps->AcquireQ();
1251cb0ef41Sopenharmony_ci    default:
1261cb0ef41Sopenharmony_ci      UNREACHABLE();
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_citemplate <typename T>
1311cb0ef41Sopenharmony_ciinline MemOperand GetMemOp(LiftoffAssembler* assm,
1321cb0ef41Sopenharmony_ci                           UseScratchRegisterScope* temps, Register addr,
1331cb0ef41Sopenharmony_ci                           Register offset, T offset_imm,
1341cb0ef41Sopenharmony_ci                           bool i64_offset = false) {
1351cb0ef41Sopenharmony_ci  if (!offset.is_valid()) return MemOperand(addr.X(), offset_imm);
1361cb0ef41Sopenharmony_ci  Register effective_addr = addr.X();
1371cb0ef41Sopenharmony_ci  if (offset_imm) {
1381cb0ef41Sopenharmony_ci    effective_addr = temps->AcquireX();
1391cb0ef41Sopenharmony_ci    assm->Add(effective_addr, addr.X(), offset_imm);
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci  return i64_offset ? MemOperand(effective_addr, offset.X())
1421cb0ef41Sopenharmony_ci                    : MemOperand(effective_addr, offset.W(), UXTW);
1431cb0ef41Sopenharmony_ci}
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci// Compute the effective address (sum of |addr|, |offset| (if given) and
1461cb0ef41Sopenharmony_ci// |offset_imm|) into a temporary register. This is needed for certain load
1471cb0ef41Sopenharmony_ci// instructions that do not support an offset (register or immediate).
1481cb0ef41Sopenharmony_ci// Returns |addr| if both |offset| and |offset_imm| are zero.
1491cb0ef41Sopenharmony_ciinline Register GetEffectiveAddress(LiftoffAssembler* assm,
1501cb0ef41Sopenharmony_ci                                    UseScratchRegisterScope* temps,
1511cb0ef41Sopenharmony_ci                                    Register addr, Register offset,
1521cb0ef41Sopenharmony_ci                                    uintptr_t offset_imm) {
1531cb0ef41Sopenharmony_ci  if (!offset.is_valid() && offset_imm == 0) return addr;
1541cb0ef41Sopenharmony_ci  Register tmp = temps->AcquireX();
1551cb0ef41Sopenharmony_ci  if (offset.is_valid()) {
1561cb0ef41Sopenharmony_ci    // TODO(clemensb): This needs adaption for memory64.
1571cb0ef41Sopenharmony_ci    assm->Add(tmp, addr, Operand(offset, UXTW));
1581cb0ef41Sopenharmony_ci    addr = tmp;
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci  if (offset_imm != 0) assm->Add(tmp, addr, offset_imm);
1611cb0ef41Sopenharmony_ci  return tmp;
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_cienum class ShiftDirection : bool { kLeft, kRight };
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_cienum class ShiftSign : bool { kSigned, kUnsigned };
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_citemplate <ShiftDirection dir, ShiftSign sign = ShiftSign::kSigned>
1691cb0ef41Sopenharmony_ciinline void EmitSimdShift(LiftoffAssembler* assm, VRegister dst, VRegister lhs,
1701cb0ef41Sopenharmony_ci                          Register rhs, VectorFormat format) {
1711cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(dir == ShiftDirection::kLeft, sign == ShiftSign::kSigned);
1721cb0ef41Sopenharmony_ci  DCHECK(dst.IsSameFormat(lhs));
1731cb0ef41Sopenharmony_ci  DCHECK_EQ(dst.LaneCount(), LaneCountFromFormat(format));
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(assm);
1761cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireV(format);
1771cb0ef41Sopenharmony_ci  Register shift = dst.Is2D() ? temps.AcquireX() : temps.AcquireW();
1781cb0ef41Sopenharmony_ci  int mask = LaneSizeInBitsFromFormat(format) - 1;
1791cb0ef41Sopenharmony_ci  assm->And(shift, rhs, mask);
1801cb0ef41Sopenharmony_ci  assm->Dup(tmp, shift);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  if (dir == ShiftDirection::kRight) {
1831cb0ef41Sopenharmony_ci    assm->Neg(tmp, tmp);
1841cb0ef41Sopenharmony_ci  }
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci  if (sign == ShiftSign::kSigned) {
1871cb0ef41Sopenharmony_ci    assm->Sshl(dst, lhs, tmp);
1881cb0ef41Sopenharmony_ci  } else {
1891cb0ef41Sopenharmony_ci    assm->Ushl(dst, lhs, tmp);
1901cb0ef41Sopenharmony_ci  }
1911cb0ef41Sopenharmony_ci}
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_citemplate <VectorFormat format, ShiftSign sign>
1941cb0ef41Sopenharmony_ciinline void EmitSimdShiftRightImmediate(LiftoffAssembler* assm, VRegister dst,
1951cb0ef41Sopenharmony_ci                                        VRegister lhs, int32_t rhs) {
1961cb0ef41Sopenharmony_ci  // Sshr and Ushr does not allow shifts to be 0, so check for that here.
1971cb0ef41Sopenharmony_ci  int mask = LaneSizeInBitsFromFormat(format) - 1;
1981cb0ef41Sopenharmony_ci  int32_t shift = rhs & mask;
1991cb0ef41Sopenharmony_ci  if (!shift) {
2001cb0ef41Sopenharmony_ci    if (dst != lhs) {
2011cb0ef41Sopenharmony_ci      assm->Mov(dst, lhs);
2021cb0ef41Sopenharmony_ci    }
2031cb0ef41Sopenharmony_ci    return;
2041cb0ef41Sopenharmony_ci  }
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  if (sign == ShiftSign::kSigned) {
2071cb0ef41Sopenharmony_ci    assm->Sshr(dst, lhs, rhs & mask);
2081cb0ef41Sopenharmony_ci  } else {
2091cb0ef41Sopenharmony_ci    assm->Ushr(dst, lhs, rhs & mask);
2101cb0ef41Sopenharmony_ci  }
2111cb0ef41Sopenharmony_ci}
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ciinline void EmitAnyTrue(LiftoffAssembler* assm, LiftoffRegister dst,
2141cb0ef41Sopenharmony_ci                        LiftoffRegister src) {
2151cb0ef41Sopenharmony_ci  // AnyTrue does not depend on the number of lanes, so we can use V4S for all.
2161cb0ef41Sopenharmony_ci  UseScratchRegisterScope scope(assm);
2171cb0ef41Sopenharmony_ci  VRegister temp = scope.AcquireV(kFormatS);
2181cb0ef41Sopenharmony_ci  assm->Umaxv(temp, src.fp().V4S());
2191cb0ef41Sopenharmony_ci  assm->Umov(dst.gp().W(), temp, 0);
2201cb0ef41Sopenharmony_ci  assm->Cmp(dst.gp().W(), 0);
2211cb0ef41Sopenharmony_ci  assm->Cset(dst.gp().W(), ne);
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciinline void EmitAllTrue(LiftoffAssembler* assm, LiftoffRegister dst,
2251cb0ef41Sopenharmony_ci                        LiftoffRegister src, VectorFormat format) {
2261cb0ef41Sopenharmony_ci  UseScratchRegisterScope scope(assm);
2271cb0ef41Sopenharmony_ci  VRegister temp = scope.AcquireV(ScalarFormatFromFormat(format));
2281cb0ef41Sopenharmony_ci  assm->Uminv(temp, VRegister::Create(src.fp().code(), format));
2291cb0ef41Sopenharmony_ci  assm->Umov(dst.gp().W(), temp, 0);
2301cb0ef41Sopenharmony_ci  assm->Cmp(dst.gp().W(), 0);
2311cb0ef41Sopenharmony_ci  assm->Cset(dst.gp().W(), ne);
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci}  // namespace liftoff
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciint LiftoffAssembler::PrepareStackFrame() {
2371cb0ef41Sopenharmony_ci  int offset = pc_offset();
2381cb0ef41Sopenharmony_ci  InstructionAccurateScope scope(this, 1);
2391cb0ef41Sopenharmony_ci  // Next we reserve the memory for the whole stack frame. We do not know yet
2401cb0ef41Sopenharmony_ci  // how big the stack frame will be so we just emit a placeholder instruction.
2411cb0ef41Sopenharmony_ci  // PatchPrepareStackFrame will patch this in order to increase the stack
2421cb0ef41Sopenharmony_ci  // appropriately.
2431cb0ef41Sopenharmony_ci  sub(sp, sp, 0);
2441cb0ef41Sopenharmony_ci  return offset;
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_civoid LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
2481cb0ef41Sopenharmony_ci                                       int stack_param_delta) {
2491cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
2501cb0ef41Sopenharmony_ci  temps.Exclude(x16, x17);
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  // This is the previous stack pointer value (before we push the lr and the
2531cb0ef41Sopenharmony_ci  // fp). We need to keep it to autenticate the lr and adjust the new stack
2541cb0ef41Sopenharmony_ci  // pointer afterwards.
2551cb0ef41Sopenharmony_ci  Add(x16, fp, 16);
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci  // Load the fp and lr of the old frame, they will be pushed in the new frame
2581cb0ef41Sopenharmony_ci  // during the actual call.
2591cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
2601cb0ef41Sopenharmony_ci  Ldp(fp, x17, MemOperand(fp));
2611cb0ef41Sopenharmony_ci  Autib1716();
2621cb0ef41Sopenharmony_ci  Mov(lr, x17);
2631cb0ef41Sopenharmony_ci#else
2641cb0ef41Sopenharmony_ci  Ldp(fp, lr, MemOperand(fp));
2651cb0ef41Sopenharmony_ci#endif
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  temps.Include(x17);
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  Register scratch = temps.AcquireX();
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci  // Shift the whole frame upwards, except for fp and lr.
2721cb0ef41Sopenharmony_ci  int slot_count = num_callee_stack_params;
2731cb0ef41Sopenharmony_ci  for (int i = slot_count - 1; i >= 0; --i) {
2741cb0ef41Sopenharmony_ci    ldr(scratch, MemOperand(sp, i * 8));
2751cb0ef41Sopenharmony_ci    str(scratch, MemOperand(x16, (i - stack_param_delta) * 8));
2761cb0ef41Sopenharmony_ci  }
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci  // Set the new stack pointer.
2791cb0ef41Sopenharmony_ci  Sub(sp, x16, stack_param_delta * 8);
2801cb0ef41Sopenharmony_ci}
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_civoid LiftoffAssembler::AlignFrameSize() {
2831cb0ef41Sopenharmony_ci  // The frame_size includes the frame marker. The frame marker has already been
2841cb0ef41Sopenharmony_ci  // pushed on the stack though, so we don't need to allocate memory for it
2851cb0ef41Sopenharmony_ci  // anymore.
2861cb0ef41Sopenharmony_ci  int initial_frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
2871cb0ef41Sopenharmony_ci  int frame_size = initial_frame_size;
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  static_assert(kStackSlotSize == kXRegSize,
2901cb0ef41Sopenharmony_ci                "kStackSlotSize must equal kXRegSize");
2911cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
2921cb0ef41Sopenharmony_ci  // Misalignment will cause a stack alignment fault.
2931cb0ef41Sopenharmony_ci  frame_size = RoundUp(frame_size, kQuadWordSizeInBytes);
2941cb0ef41Sopenharmony_ci  if (!IsImmAddSub(frame_size)) {
2951cb0ef41Sopenharmony_ci    // Round the stack to a page to try to fit a add/sub immediate.
2961cb0ef41Sopenharmony_ci    frame_size = RoundUp(frame_size, 0x1000);
2971cb0ef41Sopenharmony_ci    if (!IsImmAddSub(frame_size)) {
2981cb0ef41Sopenharmony_ci      // Stack greater than 4M! Because this is a quite improbable case, we
2991cb0ef41Sopenharmony_ci      // just fallback to TurboFan.
3001cb0ef41Sopenharmony_ci      bailout(kOtherReason, "Stack too big");
3011cb0ef41Sopenharmony_ci      return;
3021cb0ef41Sopenharmony_ci    }
3031cb0ef41Sopenharmony_ci  }
3041cb0ef41Sopenharmony_ci  if (frame_size > initial_frame_size) {
3051cb0ef41Sopenharmony_ci    // Record the padding, as it is needed for GC offsets later.
3061cb0ef41Sopenharmony_ci    max_used_spill_offset_ += (frame_size - initial_frame_size);
3071cb0ef41Sopenharmony_ci  }
3081cb0ef41Sopenharmony_ci}
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_civoid LiftoffAssembler::PatchPrepareStackFrame(
3111cb0ef41Sopenharmony_ci    int offset, SafepointTableBuilder* safepoint_table_builder) {
3121cb0ef41Sopenharmony_ci  // The frame_size includes the frame marker and the instance slot. Both are
3131cb0ef41Sopenharmony_ci  // pushed as part of frame construction, so we don't need to allocate memory
3141cb0ef41Sopenharmony_ci  // for them anymore.
3151cb0ef41Sopenharmony_ci  int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
3181cb0ef41Sopenharmony_ci  // Misalignment will cause a stack alignment fault.
3191cb0ef41Sopenharmony_ci  DCHECK_EQ(frame_size, RoundUp(frame_size, kQuadWordSizeInBytes));
3201cb0ef41Sopenharmony_ci  DCHECK(IsImmAddSub(frame_size));
3211cb0ef41Sopenharmony_ci
3221cb0ef41Sopenharmony_ci  PatchingAssembler patching_assembler(AssemblerOptions{},
3231cb0ef41Sopenharmony_ci                                       buffer_start_ + offset, 1);
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci  if (V8_LIKELY(frame_size < 4 * KB)) {
3261cb0ef41Sopenharmony_ci    // This is the standard case for small frames: just subtract from SP and be
3271cb0ef41Sopenharmony_ci    // done with it.
3281cb0ef41Sopenharmony_ci    patching_assembler.PatchSubSp(frame_size);
3291cb0ef41Sopenharmony_ci    return;
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  // The frame size is bigger than 4KB, so we might overflow the available stack
3331cb0ef41Sopenharmony_ci  // space if we first allocate the frame and then do the stack check (we will
3341cb0ef41Sopenharmony_ci  // need some remaining stack space for throwing the exception). That's why we
3351cb0ef41Sopenharmony_ci  // check the available stack space before we allocate the frame. To do this we
3361cb0ef41Sopenharmony_ci  // replace the {__ sub(sp, sp, framesize)} with a jump to OOL code that does
3371cb0ef41Sopenharmony_ci  // this "extended stack check".
3381cb0ef41Sopenharmony_ci  //
3391cb0ef41Sopenharmony_ci  // The OOL code can simply be generated here with the normal assembler,
3401cb0ef41Sopenharmony_ci  // because all other code generation, including OOL code, has already finished
3411cb0ef41Sopenharmony_ci  // when {PatchPrepareStackFrame} is called. The function prologue then jumps
3421cb0ef41Sopenharmony_ci  // to the current {pc_offset()} to execute the OOL code for allocating the
3431cb0ef41Sopenharmony_ci  // large frame.
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  // Emit the unconditional branch in the function prologue (from {offset} to
3461cb0ef41Sopenharmony_ci  // {pc_offset()}).
3471cb0ef41Sopenharmony_ci  patching_assembler.b((pc_offset() - offset) >> kInstrSizeLog2);
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  // If the frame is bigger than the stack, we throw the stack overflow
3501cb0ef41Sopenharmony_ci  // exception unconditionally. Thereby we can avoid the integer overflow
3511cb0ef41Sopenharmony_ci  // check in the condition code.
3521cb0ef41Sopenharmony_ci  RecordComment("OOL: stack check for large frame");
3531cb0ef41Sopenharmony_ci  Label continuation;
3541cb0ef41Sopenharmony_ci  if (frame_size < FLAG_stack_size * 1024) {
3551cb0ef41Sopenharmony_ci    UseScratchRegisterScope temps(this);
3561cb0ef41Sopenharmony_ci    Register stack_limit = temps.AcquireX();
3571cb0ef41Sopenharmony_ci    Ldr(stack_limit,
3581cb0ef41Sopenharmony_ci        FieldMemOperand(kWasmInstanceRegister,
3591cb0ef41Sopenharmony_ci                        WasmInstanceObject::kRealStackLimitAddressOffset));
3601cb0ef41Sopenharmony_ci    Ldr(stack_limit, MemOperand(stack_limit));
3611cb0ef41Sopenharmony_ci    Add(stack_limit, stack_limit, Operand(frame_size));
3621cb0ef41Sopenharmony_ci    Cmp(sp, stack_limit);
3631cb0ef41Sopenharmony_ci    B(hs /* higher or same */, &continuation);
3641cb0ef41Sopenharmony_ci  }
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_ci  Call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
3671cb0ef41Sopenharmony_ci  // The call will not return; just define an empty safepoint.
3681cb0ef41Sopenharmony_ci  safepoint_table_builder->DefineSafepoint(this);
3691cb0ef41Sopenharmony_ci  if (FLAG_debug_code) Brk(0);
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  bind(&continuation);
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci  // Now allocate the stack space. Note that this might do more than just
3741cb0ef41Sopenharmony_ci  // decrementing the SP; consult {TurboAssembler::Claim}.
3751cb0ef41Sopenharmony_ci  Claim(frame_size, 1);
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci  // Jump back to the start of the function, from {pc_offset()} to
3781cb0ef41Sopenharmony_ci  // right after the reserved space for the {__ sub(sp, sp, framesize)} (which
3791cb0ef41Sopenharmony_ci  // is a branch now).
3801cb0ef41Sopenharmony_ci  int func_start_offset = offset + kInstrSize;
3811cb0ef41Sopenharmony_ci  b((func_start_offset - pc_offset()) >> kInstrSizeLog2);
3821cb0ef41Sopenharmony_ci}
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_civoid LiftoffAssembler::FinishCode() { ForceConstantPoolEmissionWithoutJump(); }
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_civoid LiftoffAssembler::AbortCompilation() { AbortedCodeGeneration(); }
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci// static
3891cb0ef41Sopenharmony_ciconstexpr int LiftoffAssembler::StaticStackFrameSize() {
3901cb0ef41Sopenharmony_ci  return liftoff::kTierupBudgetOffset;
3911cb0ef41Sopenharmony_ci}
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ciint LiftoffAssembler::SlotSizeForType(ValueKind kind) {
3941cb0ef41Sopenharmony_ci  // TODO(zhin): Unaligned access typically take additional cycles, we should do
3951cb0ef41Sopenharmony_ci  // some performance testing to see how big an effect it will take.
3961cb0ef41Sopenharmony_ci  switch (kind) {
3971cb0ef41Sopenharmony_ci    case kS128:
3981cb0ef41Sopenharmony_ci      return value_kind_size(kind);
3991cb0ef41Sopenharmony_ci    default:
4001cb0ef41Sopenharmony_ci      return kStackSlotSize;
4011cb0ef41Sopenharmony_ci  }
4021cb0ef41Sopenharmony_ci}
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_cibool LiftoffAssembler::NeedsAlignment(ValueKind kind) {
4051cb0ef41Sopenharmony_ci  return kind == kS128 || is_reference(kind);
4061cb0ef41Sopenharmony_ci}
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value,
4091cb0ef41Sopenharmony_ci                                    RelocInfo::Mode rmode) {
4101cb0ef41Sopenharmony_ci  switch (value.type().kind()) {
4111cb0ef41Sopenharmony_ci    case kI32:
4121cb0ef41Sopenharmony_ci      Mov(reg.gp().W(), Immediate(value.to_i32(), rmode));
4131cb0ef41Sopenharmony_ci      break;
4141cb0ef41Sopenharmony_ci    case kI64:
4151cb0ef41Sopenharmony_ci      Mov(reg.gp().X(), Immediate(value.to_i64(), rmode));
4161cb0ef41Sopenharmony_ci      break;
4171cb0ef41Sopenharmony_ci    case kF32:
4181cb0ef41Sopenharmony_ci      Fmov(reg.fp().S(), value.to_f32_boxed().get_scalar());
4191cb0ef41Sopenharmony_ci      break;
4201cb0ef41Sopenharmony_ci    case kF64:
4211cb0ef41Sopenharmony_ci      Fmov(reg.fp().D(), value.to_f64_boxed().get_scalar());
4221cb0ef41Sopenharmony_ci      break;
4231cb0ef41Sopenharmony_ci    default:
4241cb0ef41Sopenharmony_ci      UNREACHABLE();
4251cb0ef41Sopenharmony_ci  }
4261cb0ef41Sopenharmony_ci}
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadInstanceFromFrame(Register dst) {
4291cb0ef41Sopenharmony_ci  Ldr(dst, liftoff::GetInstanceOperand());
4301cb0ef41Sopenharmony_ci}
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadFromInstance(Register dst, Register instance,
4331cb0ef41Sopenharmony_ci                                        int offset, int size) {
4341cb0ef41Sopenharmony_ci  DCHECK_LE(0, offset);
4351cb0ef41Sopenharmony_ci  MemOperand src{instance, offset};
4361cb0ef41Sopenharmony_ci  switch (size) {
4371cb0ef41Sopenharmony_ci    case 1:
4381cb0ef41Sopenharmony_ci      Ldrb(dst.W(), src);
4391cb0ef41Sopenharmony_ci      break;
4401cb0ef41Sopenharmony_ci    case 4:
4411cb0ef41Sopenharmony_ci      Ldr(dst.W(), src);
4421cb0ef41Sopenharmony_ci      break;
4431cb0ef41Sopenharmony_ci    case 8:
4441cb0ef41Sopenharmony_ci      Ldr(dst, src);
4451cb0ef41Sopenharmony_ci      break;
4461cb0ef41Sopenharmony_ci    default:
4471cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
4481cb0ef41Sopenharmony_ci  }
4491cb0ef41Sopenharmony_ci}
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTaggedPointerFromInstance(Register dst,
4521cb0ef41Sopenharmony_ci                                                     Register instance,
4531cb0ef41Sopenharmony_ci                                                     int offset) {
4541cb0ef41Sopenharmony_ci  DCHECK_LE(0, offset);
4551cb0ef41Sopenharmony_ci  LoadTaggedPointerField(dst, MemOperand{instance, offset});
4561cb0ef41Sopenharmony_ci}
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadExternalPointer(Register dst, Register instance,
4591cb0ef41Sopenharmony_ci                                           int offset, ExternalPointerTag tag,
4601cb0ef41Sopenharmony_ci                                           Register isolate_root) {
4611cb0ef41Sopenharmony_ci  LoadExternalPointerField(dst, FieldMemOperand(instance, offset), tag,
4621cb0ef41Sopenharmony_ci                           isolate_root);
4631cb0ef41Sopenharmony_ci}
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_civoid LiftoffAssembler::SpillInstance(Register instance) {
4661cb0ef41Sopenharmony_ci  Str(instance, liftoff::GetInstanceOperand());
4671cb0ef41Sopenharmony_ci}
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_civoid LiftoffAssembler::ResetOSRTarget() {}
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
4721cb0ef41Sopenharmony_ci                                         Register offset_reg,
4731cb0ef41Sopenharmony_ci                                         int32_t offset_imm,
4741cb0ef41Sopenharmony_ci                                         LiftoffRegList pinned) {
4751cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
4761cb0ef41Sopenharmony_ci  MemOperand src_op =
4771cb0ef41Sopenharmony_ci      liftoff::GetMemOp(this, &temps, src_addr, offset_reg, offset_imm);
4781cb0ef41Sopenharmony_ci  LoadTaggedPointerField(dst, src_op);
4791cb0ef41Sopenharmony_ci}
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadFullPointer(Register dst, Register src_addr,
4821cb0ef41Sopenharmony_ci                                       int32_t offset_imm) {
4831cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
4841cb0ef41Sopenharmony_ci  MemOperand src_op =
4851cb0ef41Sopenharmony_ci      liftoff::GetMemOp(this, &temps, src_addr, no_reg, offset_imm);
4861cb0ef41Sopenharmony_ci  Ldr(dst.X(), src_op);
4871cb0ef41Sopenharmony_ci}
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
4901cb0ef41Sopenharmony_ci                                          Register offset_reg,
4911cb0ef41Sopenharmony_ci                                          int32_t offset_imm,
4921cb0ef41Sopenharmony_ci                                          LiftoffRegister src,
4931cb0ef41Sopenharmony_ci                                          LiftoffRegList pinned,
4941cb0ef41Sopenharmony_ci                                          SkipWriteBarrier skip_write_barrier) {
4951cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
4961cb0ef41Sopenharmony_ci  Operand offset_op = offset_reg.is_valid() ? Operand(offset_reg.W(), UXTW)
4971cb0ef41Sopenharmony_ci                                            : Operand(offset_imm);
4981cb0ef41Sopenharmony_ci  // For the write barrier (below), we cannot have both an offset register and
4991cb0ef41Sopenharmony_ci  // an immediate offset. Add them to a 32-bit offset initially, but in a 64-bit
5001cb0ef41Sopenharmony_ci  // register, because that's needed in the MemOperand below.
5011cb0ef41Sopenharmony_ci  if (offset_reg.is_valid() && offset_imm) {
5021cb0ef41Sopenharmony_ci    Register effective_offset = temps.AcquireX();
5031cb0ef41Sopenharmony_ci    Add(effective_offset.W(), offset_reg.W(), offset_imm);
5041cb0ef41Sopenharmony_ci    offset_op = effective_offset;
5051cb0ef41Sopenharmony_ci  }
5061cb0ef41Sopenharmony_ci  StoreTaggedField(src.gp(), MemOperand(dst_addr.X(), offset_op));
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  if (skip_write_barrier || FLAG_disable_write_barriers) return;
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci  // The write barrier.
5111cb0ef41Sopenharmony_ci  Label write_barrier;
5121cb0ef41Sopenharmony_ci  Label exit;
5131cb0ef41Sopenharmony_ci  CheckPageFlag(dst_addr, MemoryChunk::kPointersFromHereAreInterestingMask, eq,
5141cb0ef41Sopenharmony_ci                &write_barrier);
5151cb0ef41Sopenharmony_ci  b(&exit);
5161cb0ef41Sopenharmony_ci  bind(&write_barrier);
5171cb0ef41Sopenharmony_ci  JumpIfSmi(src.gp(), &exit);
5181cb0ef41Sopenharmony_ci  if (COMPRESS_POINTERS_BOOL) {
5191cb0ef41Sopenharmony_ci    DecompressTaggedPointer(src.gp(), src.gp());
5201cb0ef41Sopenharmony_ci  }
5211cb0ef41Sopenharmony_ci  CheckPageFlag(src.gp(), MemoryChunk::kPointersToHereAreInterestingMask, ne,
5221cb0ef41Sopenharmony_ci                &exit);
5231cb0ef41Sopenharmony_ci  CallRecordWriteStubSaveRegisters(
5241cb0ef41Sopenharmony_ci      dst_addr, offset_op, RememberedSetAction::kEmit, SaveFPRegsMode::kSave,
5251cb0ef41Sopenharmony_ci      StubCallMode::kCallWasmRuntimeStub);
5261cb0ef41Sopenharmony_ci  bind(&exit);
5271cb0ef41Sopenharmony_ci}
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_civoid LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
5301cb0ef41Sopenharmony_ci                            Register offset_reg, uintptr_t offset_imm,
5311cb0ef41Sopenharmony_ci                            LoadType type, LiftoffRegList pinned,
5321cb0ef41Sopenharmony_ci                            uint32_t* protected_load_pc, bool is_load_mem,
5331cb0ef41Sopenharmony_ci                            bool i64_offset) {
5341cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
5351cb0ef41Sopenharmony_ci  MemOperand src_op = liftoff::GetMemOp(this, &temps, src_addr, offset_reg,
5361cb0ef41Sopenharmony_ci                                        offset_imm, i64_offset);
5371cb0ef41Sopenharmony_ci  if (protected_load_pc) *protected_load_pc = pc_offset();
5381cb0ef41Sopenharmony_ci  switch (type.value()) {
5391cb0ef41Sopenharmony_ci    case LoadType::kI32Load8U:
5401cb0ef41Sopenharmony_ci    case LoadType::kI64Load8U:
5411cb0ef41Sopenharmony_ci      Ldrb(dst.gp().W(), src_op);
5421cb0ef41Sopenharmony_ci      break;
5431cb0ef41Sopenharmony_ci    case LoadType::kI32Load8S:
5441cb0ef41Sopenharmony_ci      Ldrsb(dst.gp().W(), src_op);
5451cb0ef41Sopenharmony_ci      break;
5461cb0ef41Sopenharmony_ci    case LoadType::kI64Load8S:
5471cb0ef41Sopenharmony_ci      Ldrsb(dst.gp().X(), src_op);
5481cb0ef41Sopenharmony_ci      break;
5491cb0ef41Sopenharmony_ci    case LoadType::kI32Load16U:
5501cb0ef41Sopenharmony_ci    case LoadType::kI64Load16U:
5511cb0ef41Sopenharmony_ci      Ldrh(dst.gp().W(), src_op);
5521cb0ef41Sopenharmony_ci      break;
5531cb0ef41Sopenharmony_ci    case LoadType::kI32Load16S:
5541cb0ef41Sopenharmony_ci      Ldrsh(dst.gp().W(), src_op);
5551cb0ef41Sopenharmony_ci      break;
5561cb0ef41Sopenharmony_ci    case LoadType::kI64Load16S:
5571cb0ef41Sopenharmony_ci      Ldrsh(dst.gp().X(), src_op);
5581cb0ef41Sopenharmony_ci      break;
5591cb0ef41Sopenharmony_ci    case LoadType::kI32Load:
5601cb0ef41Sopenharmony_ci    case LoadType::kI64Load32U:
5611cb0ef41Sopenharmony_ci      Ldr(dst.gp().W(), src_op);
5621cb0ef41Sopenharmony_ci      break;
5631cb0ef41Sopenharmony_ci    case LoadType::kI64Load32S:
5641cb0ef41Sopenharmony_ci      Ldrsw(dst.gp().X(), src_op);
5651cb0ef41Sopenharmony_ci      break;
5661cb0ef41Sopenharmony_ci    case LoadType::kI64Load:
5671cb0ef41Sopenharmony_ci      Ldr(dst.gp().X(), src_op);
5681cb0ef41Sopenharmony_ci      break;
5691cb0ef41Sopenharmony_ci    case LoadType::kF32Load:
5701cb0ef41Sopenharmony_ci      Ldr(dst.fp().S(), src_op);
5711cb0ef41Sopenharmony_ci      break;
5721cb0ef41Sopenharmony_ci    case LoadType::kF64Load:
5731cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
5741cb0ef41Sopenharmony_ci      break;
5751cb0ef41Sopenharmony_ci    case LoadType::kS128Load:
5761cb0ef41Sopenharmony_ci      Ldr(dst.fp().Q(), src_op);
5771cb0ef41Sopenharmony_ci      break;
5781cb0ef41Sopenharmony_ci  }
5791cb0ef41Sopenharmony_ci}
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_civoid LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
5821cb0ef41Sopenharmony_ci                             uintptr_t offset_imm, LiftoffRegister src,
5831cb0ef41Sopenharmony_ci                             StoreType type, LiftoffRegList pinned,
5841cb0ef41Sopenharmony_ci                             uint32_t* protected_store_pc, bool is_store_mem) {
5851cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
5861cb0ef41Sopenharmony_ci  MemOperand dst_op =
5871cb0ef41Sopenharmony_ci      liftoff::GetMemOp(this, &temps, dst_addr, offset_reg, offset_imm);
5881cb0ef41Sopenharmony_ci  if (protected_store_pc) *protected_store_pc = pc_offset();
5891cb0ef41Sopenharmony_ci  switch (type.value()) {
5901cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
5911cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
5921cb0ef41Sopenharmony_ci      Strb(src.gp().W(), dst_op);
5931cb0ef41Sopenharmony_ci      break;
5941cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
5951cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
5961cb0ef41Sopenharmony_ci      Strh(src.gp().W(), dst_op);
5971cb0ef41Sopenharmony_ci      break;
5981cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
5991cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
6001cb0ef41Sopenharmony_ci      Str(src.gp().W(), dst_op);
6011cb0ef41Sopenharmony_ci      break;
6021cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
6031cb0ef41Sopenharmony_ci      Str(src.gp().X(), dst_op);
6041cb0ef41Sopenharmony_ci      break;
6051cb0ef41Sopenharmony_ci    case StoreType::kF32Store:
6061cb0ef41Sopenharmony_ci      Str(src.fp().S(), dst_op);
6071cb0ef41Sopenharmony_ci      break;
6081cb0ef41Sopenharmony_ci    case StoreType::kF64Store:
6091cb0ef41Sopenharmony_ci      Str(src.fp().D(), dst_op);
6101cb0ef41Sopenharmony_ci      break;
6111cb0ef41Sopenharmony_ci    case StoreType::kS128Store:
6121cb0ef41Sopenharmony_ci      Str(src.fp().Q(), dst_op);
6131cb0ef41Sopenharmony_ci      break;
6141cb0ef41Sopenharmony_ci  }
6151cb0ef41Sopenharmony_ci}
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_cinamespace liftoff {
6181cb0ef41Sopenharmony_ci#define __ lasm->
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ciinline Register CalculateActualAddress(LiftoffAssembler* lasm,
6211cb0ef41Sopenharmony_ci                                       Register addr_reg, Register offset_reg,
6221cb0ef41Sopenharmony_ci                                       uintptr_t offset_imm,
6231cb0ef41Sopenharmony_ci                                       Register result_reg) {
6241cb0ef41Sopenharmony_ci  DCHECK_NE(offset_reg, no_reg);
6251cb0ef41Sopenharmony_ci  DCHECK_NE(addr_reg, no_reg);
6261cb0ef41Sopenharmony_ci  __ Add(result_reg, addr_reg, Operand(offset_reg));
6271cb0ef41Sopenharmony_ci  if (offset_imm != 0) {
6281cb0ef41Sopenharmony_ci    __ Add(result_reg, result_reg, Operand(offset_imm));
6291cb0ef41Sopenharmony_ci  }
6301cb0ef41Sopenharmony_ci  return result_reg;
6311cb0ef41Sopenharmony_ci}
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_cienum class Binop { kAdd, kSub, kAnd, kOr, kXor, kExchange };
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ciinline void AtomicBinop(LiftoffAssembler* lasm, Register dst_addr,
6361cb0ef41Sopenharmony_ci                        Register offset_reg, uintptr_t offset_imm,
6371cb0ef41Sopenharmony_ci                        LiftoffRegister value, LiftoffRegister result,
6381cb0ef41Sopenharmony_ci                        StoreType type, Binop op) {
6391cb0ef41Sopenharmony_ci  LiftoffRegList pinned = {dst_addr, offset_reg, value, result};
6401cb0ef41Sopenharmony_ci  Register store_result = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci  // {LiftoffCompiler::AtomicBinop} ensures that {result} is unique.
6431cb0ef41Sopenharmony_ci  DCHECK(result.gp() != value.gp() && result.gp() != dst_addr &&
6441cb0ef41Sopenharmony_ci         result.gp() != offset_reg);
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(lasm);
6471cb0ef41Sopenharmony_ci  Register actual_addr = liftoff::CalculateActualAddress(
6481cb0ef41Sopenharmony_ci      lasm, dst_addr, offset_reg, offset_imm, temps.AcquireX());
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci  // Allocate an additional {temp} register to hold the result that should be
6511cb0ef41Sopenharmony_ci  // stored to memory. Note that {temp} and {store_result} are not allowed to be
6521cb0ef41Sopenharmony_ci  // the same register.
6531cb0ef41Sopenharmony_ci  Register temp = temps.AcquireX();
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ci  Label retry;
6561cb0ef41Sopenharmony_ci  __ Bind(&retry);
6571cb0ef41Sopenharmony_ci  switch (type.value()) {
6581cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
6591cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
6601cb0ef41Sopenharmony_ci      __ ldaxrb(result.gp().W(), actual_addr);
6611cb0ef41Sopenharmony_ci      break;
6621cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
6631cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
6641cb0ef41Sopenharmony_ci      __ ldaxrh(result.gp().W(), actual_addr);
6651cb0ef41Sopenharmony_ci      break;
6661cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
6671cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
6681cb0ef41Sopenharmony_ci      __ ldaxr(result.gp().W(), actual_addr);
6691cb0ef41Sopenharmony_ci      break;
6701cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
6711cb0ef41Sopenharmony_ci      __ ldaxr(result.gp().X(), actual_addr);
6721cb0ef41Sopenharmony_ci      break;
6731cb0ef41Sopenharmony_ci    default:
6741cb0ef41Sopenharmony_ci      UNREACHABLE();
6751cb0ef41Sopenharmony_ci  }
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci  switch (op) {
6781cb0ef41Sopenharmony_ci    case Binop::kAdd:
6791cb0ef41Sopenharmony_ci      __ add(temp, result.gp(), value.gp());
6801cb0ef41Sopenharmony_ci      break;
6811cb0ef41Sopenharmony_ci    case Binop::kSub:
6821cb0ef41Sopenharmony_ci      __ sub(temp, result.gp(), value.gp());
6831cb0ef41Sopenharmony_ci      break;
6841cb0ef41Sopenharmony_ci    case Binop::kAnd:
6851cb0ef41Sopenharmony_ci      __ and_(temp, result.gp(), value.gp());
6861cb0ef41Sopenharmony_ci      break;
6871cb0ef41Sopenharmony_ci    case Binop::kOr:
6881cb0ef41Sopenharmony_ci      __ orr(temp, result.gp(), value.gp());
6891cb0ef41Sopenharmony_ci      break;
6901cb0ef41Sopenharmony_ci    case Binop::kXor:
6911cb0ef41Sopenharmony_ci      __ eor(temp, result.gp(), value.gp());
6921cb0ef41Sopenharmony_ci      break;
6931cb0ef41Sopenharmony_ci    case Binop::kExchange:
6941cb0ef41Sopenharmony_ci      __ mov(temp, value.gp());
6951cb0ef41Sopenharmony_ci      break;
6961cb0ef41Sopenharmony_ci  }
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ci  switch (type.value()) {
6991cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
7001cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
7011cb0ef41Sopenharmony_ci      __ stlxrb(store_result.W(), temp.W(), actual_addr);
7021cb0ef41Sopenharmony_ci      break;
7031cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
7041cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
7051cb0ef41Sopenharmony_ci      __ stlxrh(store_result.W(), temp.W(), actual_addr);
7061cb0ef41Sopenharmony_ci      break;
7071cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
7081cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
7091cb0ef41Sopenharmony_ci      __ stlxr(store_result.W(), temp.W(), actual_addr);
7101cb0ef41Sopenharmony_ci      break;
7111cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
7121cb0ef41Sopenharmony_ci      __ stlxr(store_result.W(), temp.X(), actual_addr);
7131cb0ef41Sopenharmony_ci      break;
7141cb0ef41Sopenharmony_ci    default:
7151cb0ef41Sopenharmony_ci      UNREACHABLE();
7161cb0ef41Sopenharmony_ci  }
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci  __ Cbnz(store_result.W(), &retry);
7191cb0ef41Sopenharmony_ci}
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci#undef __
7221cb0ef41Sopenharmony_ci}  // namespace liftoff
7231cb0ef41Sopenharmony_ci
7241cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicLoad(LiftoffRegister dst, Register src_addr,
7251cb0ef41Sopenharmony_ci                                  Register offset_reg, uintptr_t offset_imm,
7261cb0ef41Sopenharmony_ci                                  LoadType type, LiftoffRegList pinned) {
7271cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
7281cb0ef41Sopenharmony_ci  Register src_reg = liftoff::CalculateActualAddress(
7291cb0ef41Sopenharmony_ci      this, src_addr, offset_reg, offset_imm, temps.AcquireX());
7301cb0ef41Sopenharmony_ci  switch (type.value()) {
7311cb0ef41Sopenharmony_ci    case LoadType::kI32Load8U:
7321cb0ef41Sopenharmony_ci    case LoadType::kI64Load8U:
7331cb0ef41Sopenharmony_ci      Ldarb(dst.gp().W(), src_reg);
7341cb0ef41Sopenharmony_ci      return;
7351cb0ef41Sopenharmony_ci    case LoadType::kI32Load16U:
7361cb0ef41Sopenharmony_ci    case LoadType::kI64Load16U:
7371cb0ef41Sopenharmony_ci      Ldarh(dst.gp().W(), src_reg);
7381cb0ef41Sopenharmony_ci      return;
7391cb0ef41Sopenharmony_ci    case LoadType::kI32Load:
7401cb0ef41Sopenharmony_ci    case LoadType::kI64Load32U:
7411cb0ef41Sopenharmony_ci      Ldar(dst.gp().W(), src_reg);
7421cb0ef41Sopenharmony_ci      return;
7431cb0ef41Sopenharmony_ci    case LoadType::kI64Load:
7441cb0ef41Sopenharmony_ci      Ldar(dst.gp().X(), src_reg);
7451cb0ef41Sopenharmony_ci      return;
7461cb0ef41Sopenharmony_ci    default:
7471cb0ef41Sopenharmony_ci      UNREACHABLE();
7481cb0ef41Sopenharmony_ci  }
7491cb0ef41Sopenharmony_ci}
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
7521cb0ef41Sopenharmony_ci                                   uintptr_t offset_imm, LiftoffRegister src,
7531cb0ef41Sopenharmony_ci                                   StoreType type, LiftoffRegList pinned) {
7541cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
7551cb0ef41Sopenharmony_ci  Register dst_reg = liftoff::CalculateActualAddress(
7561cb0ef41Sopenharmony_ci      this, dst_addr, offset_reg, offset_imm, temps.AcquireX());
7571cb0ef41Sopenharmony_ci  switch (type.value()) {
7581cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
7591cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
7601cb0ef41Sopenharmony_ci      Stlrb(src.gp().W(), dst_reg);
7611cb0ef41Sopenharmony_ci      return;
7621cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
7631cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
7641cb0ef41Sopenharmony_ci      Stlrh(src.gp().W(), dst_reg);
7651cb0ef41Sopenharmony_ci      return;
7661cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
7671cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
7681cb0ef41Sopenharmony_ci      Stlr(src.gp().W(), dst_reg);
7691cb0ef41Sopenharmony_ci      return;
7701cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
7711cb0ef41Sopenharmony_ci      Stlr(src.gp().X(), dst_reg);
7721cb0ef41Sopenharmony_ci      return;
7731cb0ef41Sopenharmony_ci    default:
7741cb0ef41Sopenharmony_ci      UNREACHABLE();
7751cb0ef41Sopenharmony_ci  }
7761cb0ef41Sopenharmony_ci}
7771cb0ef41Sopenharmony_ci
7781cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
7791cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
7801cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
7811cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
7821cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kAdd);
7831cb0ef41Sopenharmony_ci}
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
7861cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
7871cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
7881cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
7891cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kSub);
7901cb0ef41Sopenharmony_ci}
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
7931cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
7941cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
7951cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
7961cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kAnd);
7971cb0ef41Sopenharmony_ci}
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
8001cb0ef41Sopenharmony_ci                                uintptr_t offset_imm, LiftoffRegister value,
8011cb0ef41Sopenharmony_ci                                LiftoffRegister result, StoreType type) {
8021cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
8031cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kOr);
8041cb0ef41Sopenharmony_ci}
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
8071cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
8081cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
8091cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
8101cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kXor);
8111cb0ef41Sopenharmony_ci}
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
8141cb0ef41Sopenharmony_ci                                      uintptr_t offset_imm,
8151cb0ef41Sopenharmony_ci                                      LiftoffRegister value,
8161cb0ef41Sopenharmony_ci                                      LiftoffRegister result, StoreType type) {
8171cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, dst_addr, offset_reg, offset_imm, value, result,
8181cb0ef41Sopenharmony_ci                       type, liftoff::Binop::kExchange);
8191cb0ef41Sopenharmony_ci}
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicCompareExchange(
8221cb0ef41Sopenharmony_ci    Register dst_addr, Register offset_reg, uintptr_t offset_imm,
8231cb0ef41Sopenharmony_ci    LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result,
8241cb0ef41Sopenharmony_ci    StoreType type) {
8251cb0ef41Sopenharmony_ci  LiftoffRegList pinned = {dst_addr, offset_reg, expected, new_value};
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci  Register result_reg = result.gp();
8281cb0ef41Sopenharmony_ci  if (pinned.has(result)) {
8291cb0ef41Sopenharmony_ci    result_reg = GetUnusedRegister(kGpReg, pinned).gp();
8301cb0ef41Sopenharmony_ci  }
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  Register actual_addr = liftoff::CalculateActualAddress(
8351cb0ef41Sopenharmony_ci      this, dst_addr, offset_reg, offset_imm, temps.AcquireX());
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci  Register store_result = temps.AcquireW();
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci  Label retry;
8401cb0ef41Sopenharmony_ci  Label done;
8411cb0ef41Sopenharmony_ci  Bind(&retry);
8421cb0ef41Sopenharmony_ci  switch (type.value()) {
8431cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
8441cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
8451cb0ef41Sopenharmony_ci      ldaxrb(result_reg.W(), actual_addr);
8461cb0ef41Sopenharmony_ci      Cmp(result.gp().W(), Operand(expected.gp().W(), UXTB));
8471cb0ef41Sopenharmony_ci      B(ne, &done);
8481cb0ef41Sopenharmony_ci      stlxrb(store_result.W(), new_value.gp().W(), actual_addr);
8491cb0ef41Sopenharmony_ci      break;
8501cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
8511cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
8521cb0ef41Sopenharmony_ci      ldaxrh(result_reg.W(), actual_addr);
8531cb0ef41Sopenharmony_ci      Cmp(result.gp().W(), Operand(expected.gp().W(), UXTH));
8541cb0ef41Sopenharmony_ci      B(ne, &done);
8551cb0ef41Sopenharmony_ci      stlxrh(store_result.W(), new_value.gp().W(), actual_addr);
8561cb0ef41Sopenharmony_ci      break;
8571cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
8581cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
8591cb0ef41Sopenharmony_ci      ldaxr(result_reg.W(), actual_addr);
8601cb0ef41Sopenharmony_ci      Cmp(result.gp().W(), Operand(expected.gp().W(), UXTW));
8611cb0ef41Sopenharmony_ci      B(ne, &done);
8621cb0ef41Sopenharmony_ci      stlxr(store_result.W(), new_value.gp().W(), actual_addr);
8631cb0ef41Sopenharmony_ci      break;
8641cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
8651cb0ef41Sopenharmony_ci      ldaxr(result_reg.X(), actual_addr);
8661cb0ef41Sopenharmony_ci      Cmp(result.gp().X(), Operand(expected.gp().X(), UXTX));
8671cb0ef41Sopenharmony_ci      B(ne, &done);
8681cb0ef41Sopenharmony_ci      stlxr(store_result.W(), new_value.gp().X(), actual_addr);
8691cb0ef41Sopenharmony_ci      break;
8701cb0ef41Sopenharmony_ci    default:
8711cb0ef41Sopenharmony_ci      UNREACHABLE();
8721cb0ef41Sopenharmony_ci  }
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_ci  Cbnz(store_result.W(), &retry);
8751cb0ef41Sopenharmony_ci  Bind(&done);
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci  if (result_reg != result.gp()) {
8781cb0ef41Sopenharmony_ci    mov(result.gp(), result_reg);
8791cb0ef41Sopenharmony_ci  }
8801cb0ef41Sopenharmony_ci}
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicFence() { Dmb(InnerShareable, BarrierAll); }
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
8851cb0ef41Sopenharmony_ci                                           uint32_t caller_slot_idx,
8861cb0ef41Sopenharmony_ci                                           ValueKind kind) {
8871cb0ef41Sopenharmony_ci  int32_t offset = (caller_slot_idx + 1) * LiftoffAssembler::kStackSlotSize;
8881cb0ef41Sopenharmony_ci  Ldr(liftoff::GetRegFromType(dst, kind), MemOperand(fp, offset));
8891cb0ef41Sopenharmony_ci}
8901cb0ef41Sopenharmony_ci
8911cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreCallerFrameSlot(LiftoffRegister src,
8921cb0ef41Sopenharmony_ci                                            uint32_t caller_slot_idx,
8931cb0ef41Sopenharmony_ci                                            ValueKind kind) {
8941cb0ef41Sopenharmony_ci  int32_t offset = (caller_slot_idx + 1) * LiftoffAssembler::kStackSlotSize;
8951cb0ef41Sopenharmony_ci  Str(liftoff::GetRegFromType(src, kind), MemOperand(fp, offset));
8961cb0ef41Sopenharmony_ci}
8971cb0ef41Sopenharmony_ci
8981cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadReturnStackSlot(LiftoffRegister dst, int offset,
8991cb0ef41Sopenharmony_ci                                           ValueKind kind) {
9001cb0ef41Sopenharmony_ci  Ldr(liftoff::GetRegFromType(dst, kind), MemOperand(sp, offset));
9011cb0ef41Sopenharmony_ci}
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_civoid LiftoffAssembler::MoveStackValue(uint32_t dst_offset, uint32_t src_offset,
9041cb0ef41Sopenharmony_ci                                      ValueKind kind) {
9051cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
9061cb0ef41Sopenharmony_ci  CPURegister scratch = liftoff::AcquireByType(&temps, kind);
9071cb0ef41Sopenharmony_ci  Ldr(scratch, liftoff::GetStackSlot(src_offset));
9081cb0ef41Sopenharmony_ci  Str(scratch, liftoff::GetStackSlot(dst_offset));
9091cb0ef41Sopenharmony_ci}
9101cb0ef41Sopenharmony_ci
9111cb0ef41Sopenharmony_civoid LiftoffAssembler::Move(Register dst, Register src, ValueKind kind) {
9121cb0ef41Sopenharmony_ci  if (kind == kI32) {
9131cb0ef41Sopenharmony_ci    Mov(dst.W(), src.W());
9141cb0ef41Sopenharmony_ci  } else {
9151cb0ef41Sopenharmony_ci    DCHECK(kI64 == kind || is_reference(kind));
9161cb0ef41Sopenharmony_ci    Mov(dst.X(), src.X());
9171cb0ef41Sopenharmony_ci  }
9181cb0ef41Sopenharmony_ci}
9191cb0ef41Sopenharmony_ci
9201cb0ef41Sopenharmony_civoid LiftoffAssembler::Move(DoubleRegister dst, DoubleRegister src,
9211cb0ef41Sopenharmony_ci                            ValueKind kind) {
9221cb0ef41Sopenharmony_ci  if (kind == kF32) {
9231cb0ef41Sopenharmony_ci    Fmov(dst.S(), src.S());
9241cb0ef41Sopenharmony_ci  } else if (kind == kF64) {
9251cb0ef41Sopenharmony_ci    Fmov(dst.D(), src.D());
9261cb0ef41Sopenharmony_ci  } else {
9271cb0ef41Sopenharmony_ci    DCHECK_EQ(kS128, kind);
9281cb0ef41Sopenharmony_ci    Mov(dst.Q(), src.Q());
9291cb0ef41Sopenharmony_ci  }
9301cb0ef41Sopenharmony_ci}
9311cb0ef41Sopenharmony_ci
9321cb0ef41Sopenharmony_civoid LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
9331cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(offset);
9341cb0ef41Sopenharmony_ci  MemOperand dst = liftoff::GetStackSlot(offset);
9351cb0ef41Sopenharmony_ci  Str(liftoff::GetRegFromType(reg, kind), dst);
9361cb0ef41Sopenharmony_ci}
9371cb0ef41Sopenharmony_ci
9381cb0ef41Sopenharmony_civoid LiftoffAssembler::Spill(int offset, WasmValue value) {
9391cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(offset);
9401cb0ef41Sopenharmony_ci  MemOperand dst = liftoff::GetStackSlot(offset);
9411cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
9421cb0ef41Sopenharmony_ci  CPURegister src = CPURegister::no_reg();
9431cb0ef41Sopenharmony_ci  switch (value.type().kind()) {
9441cb0ef41Sopenharmony_ci    case kI32:
9451cb0ef41Sopenharmony_ci      if (value.to_i32() == 0) {
9461cb0ef41Sopenharmony_ci        src = wzr;
9471cb0ef41Sopenharmony_ci      } else {
9481cb0ef41Sopenharmony_ci        src = temps.AcquireW();
9491cb0ef41Sopenharmony_ci        Mov(src.W(), value.to_i32());
9501cb0ef41Sopenharmony_ci      }
9511cb0ef41Sopenharmony_ci      break;
9521cb0ef41Sopenharmony_ci    case kI64:
9531cb0ef41Sopenharmony_ci      if (value.to_i64() == 0) {
9541cb0ef41Sopenharmony_ci        src = xzr;
9551cb0ef41Sopenharmony_ci      } else {
9561cb0ef41Sopenharmony_ci        src = temps.AcquireX();
9571cb0ef41Sopenharmony_ci        Mov(src.X(), value.to_i64());
9581cb0ef41Sopenharmony_ci      }
9591cb0ef41Sopenharmony_ci      break;
9601cb0ef41Sopenharmony_ci    default:
9611cb0ef41Sopenharmony_ci      // We do not track f32 and f64 constants, hence they are unreachable.
9621cb0ef41Sopenharmony_ci      UNREACHABLE();
9631cb0ef41Sopenharmony_ci  }
9641cb0ef41Sopenharmony_ci  Str(src, dst);
9651cb0ef41Sopenharmony_ci}
9661cb0ef41Sopenharmony_ci
9671cb0ef41Sopenharmony_civoid LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
9681cb0ef41Sopenharmony_ci  MemOperand src = liftoff::GetStackSlot(offset);
9691cb0ef41Sopenharmony_ci  Ldr(liftoff::GetRegFromType(reg, kind), src);
9701cb0ef41Sopenharmony_ci}
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_civoid LiftoffAssembler::FillI64Half(Register, int offset, RegPairHalf) {
9731cb0ef41Sopenharmony_ci  UNREACHABLE();
9741cb0ef41Sopenharmony_ci}
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_civoid LiftoffAssembler::FillStackSlotsWithZero(int start, int size) {
9771cb0ef41Sopenharmony_ci  // Zero 'size' bytes *below* start, byte at offset 'start' is untouched.
9781cb0ef41Sopenharmony_ci  DCHECK_LE(0, start);
9791cb0ef41Sopenharmony_ci  DCHECK_LT(0, size);
9801cb0ef41Sopenharmony_ci  DCHECK_EQ(0, size % 4);
9811cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(start + size);
9821cb0ef41Sopenharmony_ci
9831cb0ef41Sopenharmony_ci  int max_stp_offset = -start - size;
9841cb0ef41Sopenharmony_ci  // We check IsImmLSUnscaled(-start-12) because str only allows for unscaled
9851cb0ef41Sopenharmony_ci  // 9-bit immediate offset [-256,256]. If start is large enough, which can
9861cb0ef41Sopenharmony_ci  // happen when a function has many params (>=32 i64), str cannot be encoded
9871cb0ef41Sopenharmony_ci  // properly. We can use Str, which will generate more instructions, so
9881cb0ef41Sopenharmony_ci  // fallback to the general case below.
9891cb0ef41Sopenharmony_ci  if (size <= 12 * kStackSlotSize &&
9901cb0ef41Sopenharmony_ci      IsImmLSPair(max_stp_offset, kXRegSizeLog2) &&
9911cb0ef41Sopenharmony_ci      IsImmLSUnscaled(-start - 12)) {
9921cb0ef41Sopenharmony_ci    // Special straight-line code for up to 12 slots. Generates one
9931cb0ef41Sopenharmony_ci    // instruction per two slots (<= 7 instructions total).
9941cb0ef41Sopenharmony_ci    STATIC_ASSERT(kStackSlotSize == kSystemPointerSize);
9951cb0ef41Sopenharmony_ci    uint32_t remainder = size;
9961cb0ef41Sopenharmony_ci    for (; remainder >= 2 * kStackSlotSize; remainder -= 2 * kStackSlotSize) {
9971cb0ef41Sopenharmony_ci      stp(xzr, xzr, liftoff::GetStackSlot(start + remainder));
9981cb0ef41Sopenharmony_ci    }
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ci    DCHECK_GE(12, remainder);
10011cb0ef41Sopenharmony_ci    switch (remainder) {
10021cb0ef41Sopenharmony_ci      case 12:
10031cb0ef41Sopenharmony_ci        str(xzr, liftoff::GetStackSlot(start + remainder));
10041cb0ef41Sopenharmony_ci        str(wzr, liftoff::GetStackSlot(start + remainder - 8));
10051cb0ef41Sopenharmony_ci        break;
10061cb0ef41Sopenharmony_ci      case 8:
10071cb0ef41Sopenharmony_ci        str(xzr, liftoff::GetStackSlot(start + remainder));
10081cb0ef41Sopenharmony_ci        break;
10091cb0ef41Sopenharmony_ci      case 4:
10101cb0ef41Sopenharmony_ci        str(wzr, liftoff::GetStackSlot(start + remainder));
10111cb0ef41Sopenharmony_ci        break;
10121cb0ef41Sopenharmony_ci      case 0:
10131cb0ef41Sopenharmony_ci        break;
10141cb0ef41Sopenharmony_ci      default:
10151cb0ef41Sopenharmony_ci        UNREACHABLE();
10161cb0ef41Sopenharmony_ci    }
10171cb0ef41Sopenharmony_ci  } else {
10181cb0ef41Sopenharmony_ci    // General case for bigger counts (5-8 instructions).
10191cb0ef41Sopenharmony_ci    UseScratchRegisterScope temps(this);
10201cb0ef41Sopenharmony_ci    Register address_reg = temps.AcquireX();
10211cb0ef41Sopenharmony_ci    // This {Sub} might use another temp register if the offset is too large.
10221cb0ef41Sopenharmony_ci    Sub(address_reg, fp, start + size);
10231cb0ef41Sopenharmony_ci    Register count_reg = temps.AcquireX();
10241cb0ef41Sopenharmony_ci    Mov(count_reg, size / 4);
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci    Label loop;
10271cb0ef41Sopenharmony_ci    bind(&loop);
10281cb0ef41Sopenharmony_ci    sub(count_reg, count_reg, 1);
10291cb0ef41Sopenharmony_ci    str(wzr, MemOperand(address_reg, kSystemPointerSize / 2, PostIndex));
10301cb0ef41Sopenharmony_ci    cbnz(count_reg, &loop);
10311cb0ef41Sopenharmony_ci  }
10321cb0ef41Sopenharmony_ci}
10331cb0ef41Sopenharmony_ci
10341cb0ef41Sopenharmony_ci#define I32_BINOP(name, instruction)                             \
10351cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(Register dst, Register lhs, \
10361cb0ef41Sopenharmony_ci                                     Register rhs) {             \
10371cb0ef41Sopenharmony_ci    instruction(dst.W(), lhs.W(), rhs.W());                      \
10381cb0ef41Sopenharmony_ci  }
10391cb0ef41Sopenharmony_ci#define I32_BINOP_I(name, instruction)                              \
10401cb0ef41Sopenharmony_ci  I32_BINOP(name, instruction)                                      \
10411cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name##i(Register dst, Register lhs, \
10421cb0ef41Sopenharmony_ci                                        int32_t imm) {              \
10431cb0ef41Sopenharmony_ci    instruction(dst.W(), lhs.W(), Immediate(imm));                  \
10441cb0ef41Sopenharmony_ci  }
10451cb0ef41Sopenharmony_ci#define I64_BINOP(name, instruction)                                           \
10461cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister lhs, \
10471cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {                    \
10481cb0ef41Sopenharmony_ci    instruction(dst.gp().X(), lhs.gp().X(), rhs.gp().X());                     \
10491cb0ef41Sopenharmony_ci  }
10501cb0ef41Sopenharmony_ci#define I64_BINOP_I(name, instruction)                                      \
10511cb0ef41Sopenharmony_ci  I64_BINOP(name, instruction)                                              \
10521cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name##i(LiftoffRegister dst,                \
10531cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs, int32_t imm) { \
10541cb0ef41Sopenharmony_ci    instruction(dst.gp().X(), lhs.gp().X(), imm);                           \
10551cb0ef41Sopenharmony_ci  }
10561cb0ef41Sopenharmony_ci#define FP32_BINOP(name, instruction)                                        \
10571cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
10581cb0ef41Sopenharmony_ci                                     DoubleRegister rhs) {                   \
10591cb0ef41Sopenharmony_ci    instruction(dst.S(), lhs.S(), rhs.S());                                  \
10601cb0ef41Sopenharmony_ci  }
10611cb0ef41Sopenharmony_ci#define FP32_UNOP(name, instruction)                                           \
10621cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
10631cb0ef41Sopenharmony_ci    instruction(dst.S(), src.S());                                             \
10641cb0ef41Sopenharmony_ci  }
10651cb0ef41Sopenharmony_ci#define FP32_UNOP_RETURN_TRUE(name, instruction)                               \
10661cb0ef41Sopenharmony_ci  bool LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
10671cb0ef41Sopenharmony_ci    instruction(dst.S(), src.S());                                             \
10681cb0ef41Sopenharmony_ci    return true;                                                               \
10691cb0ef41Sopenharmony_ci  }
10701cb0ef41Sopenharmony_ci#define FP64_BINOP(name, instruction)                                        \
10711cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
10721cb0ef41Sopenharmony_ci                                     DoubleRegister rhs) {                   \
10731cb0ef41Sopenharmony_ci    instruction(dst.D(), lhs.D(), rhs.D());                                  \
10741cb0ef41Sopenharmony_ci  }
10751cb0ef41Sopenharmony_ci#define FP64_UNOP(name, instruction)                                           \
10761cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
10771cb0ef41Sopenharmony_ci    instruction(dst.D(), src.D());                                             \
10781cb0ef41Sopenharmony_ci  }
10791cb0ef41Sopenharmony_ci#define FP64_UNOP_RETURN_TRUE(name, instruction)                               \
10801cb0ef41Sopenharmony_ci  bool LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
10811cb0ef41Sopenharmony_ci    instruction(dst.D(), src.D());                                             \
10821cb0ef41Sopenharmony_ci    return true;                                                               \
10831cb0ef41Sopenharmony_ci  }
10841cb0ef41Sopenharmony_ci#define I32_SHIFTOP(name, instruction)                              \
10851cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(Register dst, Register src,    \
10861cb0ef41Sopenharmony_ci                                     Register amount) {             \
10871cb0ef41Sopenharmony_ci    instruction(dst.W(), src.W(), amount.W());                      \
10881cb0ef41Sopenharmony_ci  }                                                                 \
10891cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name##i(Register dst, Register src, \
10901cb0ef41Sopenharmony_ci                                        int32_t amount) {           \
10911cb0ef41Sopenharmony_ci    instruction(dst.W(), src.W(), amount & 31);                     \
10921cb0ef41Sopenharmony_ci  }
10931cb0ef41Sopenharmony_ci#define I64_SHIFTOP(name, instruction)                                         \
10941cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
10951cb0ef41Sopenharmony_ci                                     Register amount) {                        \
10961cb0ef41Sopenharmony_ci    instruction(dst.gp().X(), src.gp().X(), amount.X());                       \
10971cb0ef41Sopenharmony_ci  }                                                                            \
10981cb0ef41Sopenharmony_ci  void LiftoffAssembler::emit_##name##i(LiftoffRegister dst,                   \
10991cb0ef41Sopenharmony_ci                                        LiftoffRegister src, int32_t amount) { \
11001cb0ef41Sopenharmony_ci    instruction(dst.gp().X(), src.gp().X(), amount & 63);                      \
11011cb0ef41Sopenharmony_ci  }
11021cb0ef41Sopenharmony_ci
11031cb0ef41Sopenharmony_ciI32_BINOP_I(i32_add, Add)
11041cb0ef41Sopenharmony_ciI32_BINOP_I(i32_sub, Sub)
11051cb0ef41Sopenharmony_ciI32_BINOP(i32_mul, Mul)
11061cb0ef41Sopenharmony_ciI32_BINOP_I(i32_and, And)
11071cb0ef41Sopenharmony_ciI32_BINOP_I(i32_or, Orr)
11081cb0ef41Sopenharmony_ciI32_BINOP_I(i32_xor, Eor)
11091cb0ef41Sopenharmony_ciI32_SHIFTOP(i32_shl, Lsl)
11101cb0ef41Sopenharmony_ciI32_SHIFTOP(i32_sar, Asr)
11111cb0ef41Sopenharmony_ciI32_SHIFTOP(i32_shr, Lsr)
11121cb0ef41Sopenharmony_ciI64_BINOP(i64_add, Add)
11131cb0ef41Sopenharmony_ciI64_BINOP(i64_sub, Sub)
11141cb0ef41Sopenharmony_ciI64_BINOP(i64_mul, Mul)
11151cb0ef41Sopenharmony_ciI64_BINOP_I(i64_and, And)
11161cb0ef41Sopenharmony_ciI64_BINOP_I(i64_or, Orr)
11171cb0ef41Sopenharmony_ciI64_BINOP_I(i64_xor, Eor)
11181cb0ef41Sopenharmony_ciI64_SHIFTOP(i64_shl, Lsl)
11191cb0ef41Sopenharmony_ciI64_SHIFTOP(i64_sar, Asr)
11201cb0ef41Sopenharmony_ciI64_SHIFTOP(i64_shr, Lsr)
11211cb0ef41Sopenharmony_ciFP32_BINOP(f32_add, Fadd)
11221cb0ef41Sopenharmony_ciFP32_BINOP(f32_sub, Fsub)
11231cb0ef41Sopenharmony_ciFP32_BINOP(f32_mul, Fmul)
11241cb0ef41Sopenharmony_ciFP32_BINOP(f32_div, Fdiv)
11251cb0ef41Sopenharmony_ciFP32_BINOP(f32_min, Fmin)
11261cb0ef41Sopenharmony_ciFP32_BINOP(f32_max, Fmax)
11271cb0ef41Sopenharmony_ciFP32_UNOP(f32_abs, Fabs)
11281cb0ef41Sopenharmony_ciFP32_UNOP(f32_neg, Fneg)
11291cb0ef41Sopenharmony_ciFP32_UNOP_RETURN_TRUE(f32_ceil, Frintp)
11301cb0ef41Sopenharmony_ciFP32_UNOP_RETURN_TRUE(f32_floor, Frintm)
11311cb0ef41Sopenharmony_ciFP32_UNOP_RETURN_TRUE(f32_trunc, Frintz)
11321cb0ef41Sopenharmony_ciFP32_UNOP_RETURN_TRUE(f32_nearest_int, Frintn)
11331cb0ef41Sopenharmony_ciFP32_UNOP(f32_sqrt, Fsqrt)
11341cb0ef41Sopenharmony_ciFP64_BINOP(f64_add, Fadd)
11351cb0ef41Sopenharmony_ciFP64_BINOP(f64_sub, Fsub)
11361cb0ef41Sopenharmony_ciFP64_BINOP(f64_mul, Fmul)
11371cb0ef41Sopenharmony_ciFP64_BINOP(f64_div, Fdiv)
11381cb0ef41Sopenharmony_ciFP64_BINOP(f64_min, Fmin)
11391cb0ef41Sopenharmony_ciFP64_BINOP(f64_max, Fmax)
11401cb0ef41Sopenharmony_ciFP64_UNOP(f64_abs, Fabs)
11411cb0ef41Sopenharmony_ciFP64_UNOP(f64_neg, Fneg)
11421cb0ef41Sopenharmony_ciFP64_UNOP_RETURN_TRUE(f64_ceil, Frintp)
11431cb0ef41Sopenharmony_ciFP64_UNOP_RETURN_TRUE(f64_floor, Frintm)
11441cb0ef41Sopenharmony_ciFP64_UNOP_RETURN_TRUE(f64_trunc, Frintz)
11451cb0ef41Sopenharmony_ciFP64_UNOP_RETURN_TRUE(f64_nearest_int, Frintn)
11461cb0ef41Sopenharmony_ciFP64_UNOP(f64_sqrt, Fsqrt)
11471cb0ef41Sopenharmony_ci
11481cb0ef41Sopenharmony_ci#undef I32_BINOP
11491cb0ef41Sopenharmony_ci#undef I64_BINOP
11501cb0ef41Sopenharmony_ci#undef FP32_BINOP
11511cb0ef41Sopenharmony_ci#undef FP32_UNOP
11521cb0ef41Sopenharmony_ci#undef FP64_BINOP
11531cb0ef41Sopenharmony_ci#undef FP64_UNOP
11541cb0ef41Sopenharmony_ci#undef FP64_UNOP_RETURN_TRUE
11551cb0ef41Sopenharmony_ci#undef I32_SHIFTOP
11561cb0ef41Sopenharmony_ci#undef I64_SHIFTOP
11571cb0ef41Sopenharmony_ci
11581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_addi(LiftoffRegister dst, LiftoffRegister lhs,
11591cb0ef41Sopenharmony_ci                                     int64_t imm) {
11601cb0ef41Sopenharmony_ci  Add(dst.gp().X(), lhs.gp().X(), imm);
11611cb0ef41Sopenharmony_ci}
11621cb0ef41Sopenharmony_ci
11631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
11641cb0ef41Sopenharmony_ci  Clz(dst.W(), src.W());
11651cb0ef41Sopenharmony_ci}
11661cb0ef41Sopenharmony_ci
11671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
11681cb0ef41Sopenharmony_ci  Rbit(dst.W(), src.W());
11691cb0ef41Sopenharmony_ci  Clz(dst.W(), dst.W());
11701cb0ef41Sopenharmony_ci}
11711cb0ef41Sopenharmony_ci
11721cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i32_popcnt(Register dst, Register src) {
11731cb0ef41Sopenharmony_ci  PopcntHelper(dst.W(), src.W());
11741cb0ef41Sopenharmony_ci  return true;
11751cb0ef41Sopenharmony_ci}
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_clz(LiftoffRegister dst, LiftoffRegister src) {
11781cb0ef41Sopenharmony_ci  Clz(dst.gp().X(), src.gp().X());
11791cb0ef41Sopenharmony_ci}
11801cb0ef41Sopenharmony_ci
11811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) {
11821cb0ef41Sopenharmony_ci  Rbit(dst.gp().X(), src.gp().X());
11831cb0ef41Sopenharmony_ci  Clz(dst.gp().X(), dst.gp().X());
11841cb0ef41Sopenharmony_ci}
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst,
11871cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
11881cb0ef41Sopenharmony_ci  PopcntHelper(dst.gp().X(), src.gp().X());
11891cb0ef41Sopenharmony_ci  return true;
11901cb0ef41Sopenharmony_ci}
11911cb0ef41Sopenharmony_ci
11921cb0ef41Sopenharmony_civoid LiftoffAssembler::IncrementSmi(LiftoffRegister dst, int offset) {
11931cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
11941cb0ef41Sopenharmony_ci  if (COMPRESS_POINTERS_BOOL) {
11951cb0ef41Sopenharmony_ci    DCHECK(SmiValuesAre31Bits());
11961cb0ef41Sopenharmony_ci    Register scratch = temps.AcquireW();
11971cb0ef41Sopenharmony_ci    Ldr(scratch, MemOperand(dst.gp(), offset));
11981cb0ef41Sopenharmony_ci    Add(scratch, scratch, Operand(Smi::FromInt(1)));
11991cb0ef41Sopenharmony_ci    Str(scratch, MemOperand(dst.gp(), offset));
12001cb0ef41Sopenharmony_ci  } else {
12011cb0ef41Sopenharmony_ci    Register scratch = temps.AcquireX();
12021cb0ef41Sopenharmony_ci    SmiUntag(scratch, MemOperand(dst.gp(), offset));
12031cb0ef41Sopenharmony_ci    Add(scratch, scratch, Operand(1));
12041cb0ef41Sopenharmony_ci    SmiTag(scratch);
12051cb0ef41Sopenharmony_ci    Str(scratch, MemOperand(dst.gp(), offset));
12061cb0ef41Sopenharmony_ci  }
12071cb0ef41Sopenharmony_ci}
12081cb0ef41Sopenharmony_ci
12091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_divs(Register dst, Register lhs, Register rhs,
12101cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero,
12111cb0ef41Sopenharmony_ci                                     Label* trap_div_unrepresentable) {
12121cb0ef41Sopenharmony_ci  Register dst_w = dst.W();
12131cb0ef41Sopenharmony_ci  Register lhs_w = lhs.W();
12141cb0ef41Sopenharmony_ci  Register rhs_w = rhs.W();
12151cb0ef41Sopenharmony_ci  bool can_use_dst = !dst_w.Aliases(lhs_w) && !dst_w.Aliases(rhs_w);
12161cb0ef41Sopenharmony_ci  if (can_use_dst) {
12171cb0ef41Sopenharmony_ci    // Do div early.
12181cb0ef41Sopenharmony_ci    Sdiv(dst_w, lhs_w, rhs_w);
12191cb0ef41Sopenharmony_ci  }
12201cb0ef41Sopenharmony_ci  // Check for division by zero.
12211cb0ef41Sopenharmony_ci  Cbz(rhs_w, trap_div_by_zero);
12221cb0ef41Sopenharmony_ci  // Check for kMinInt / -1. This is unrepresentable.
12231cb0ef41Sopenharmony_ci  Cmp(rhs_w, -1);
12241cb0ef41Sopenharmony_ci  Ccmp(lhs_w, 1, NoFlag, eq);
12251cb0ef41Sopenharmony_ci  B(trap_div_unrepresentable, vs);
12261cb0ef41Sopenharmony_ci  if (!can_use_dst) {
12271cb0ef41Sopenharmony_ci    // Do div.
12281cb0ef41Sopenharmony_ci    Sdiv(dst_w, lhs_w, rhs_w);
12291cb0ef41Sopenharmony_ci  }
12301cb0ef41Sopenharmony_ci}
12311cb0ef41Sopenharmony_ci
12321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_divu(Register dst, Register lhs, Register rhs,
12331cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
12341cb0ef41Sopenharmony_ci  // Check for division by zero.
12351cb0ef41Sopenharmony_ci  Cbz(rhs.W(), trap_div_by_zero);
12361cb0ef41Sopenharmony_ci  // Do div.
12371cb0ef41Sopenharmony_ci  Udiv(dst.W(), lhs.W(), rhs.W());
12381cb0ef41Sopenharmony_ci}
12391cb0ef41Sopenharmony_ci
12401cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_rems(Register dst, Register lhs, Register rhs,
12411cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
12421cb0ef41Sopenharmony_ci  Register dst_w = dst.W();
12431cb0ef41Sopenharmony_ci  Register lhs_w = lhs.W();
12441cb0ef41Sopenharmony_ci  Register rhs_w = rhs.W();
12451cb0ef41Sopenharmony_ci  // Do early div.
12461cb0ef41Sopenharmony_ci  // No need to check kMinInt / -1 because the result is kMinInt and then
12471cb0ef41Sopenharmony_ci  // kMinInt * -1 -> kMinInt. In this case, the Msub result is therefore 0.
12481cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
12491cb0ef41Sopenharmony_ci  Register scratch = temps.AcquireW();
12501cb0ef41Sopenharmony_ci  Sdiv(scratch, lhs_w, rhs_w);
12511cb0ef41Sopenharmony_ci  // Check for division by zero.
12521cb0ef41Sopenharmony_ci  Cbz(rhs_w, trap_div_by_zero);
12531cb0ef41Sopenharmony_ci  // Compute remainder.
12541cb0ef41Sopenharmony_ci  Msub(dst_w, scratch, rhs_w, lhs_w);
12551cb0ef41Sopenharmony_ci}
12561cb0ef41Sopenharmony_ci
12571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
12581cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
12591cb0ef41Sopenharmony_ci  Register dst_w = dst.W();
12601cb0ef41Sopenharmony_ci  Register lhs_w = lhs.W();
12611cb0ef41Sopenharmony_ci  Register rhs_w = rhs.W();
12621cb0ef41Sopenharmony_ci  // Do early div.
12631cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
12641cb0ef41Sopenharmony_ci  Register scratch = temps.AcquireW();
12651cb0ef41Sopenharmony_ci  Udiv(scratch, lhs_w, rhs_w);
12661cb0ef41Sopenharmony_ci  // Check for division by zero.
12671cb0ef41Sopenharmony_ci  Cbz(rhs_w, trap_div_by_zero);
12681cb0ef41Sopenharmony_ci  // Compute remainder.
12691cb0ef41Sopenharmony_ci  Msub(dst_w, scratch, rhs_w, lhs_w);
12701cb0ef41Sopenharmony_ci}
12711cb0ef41Sopenharmony_ci
12721cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_divs(LiftoffRegister dst, LiftoffRegister lhs,
12731cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
12741cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero,
12751cb0ef41Sopenharmony_ci                                     Label* trap_div_unrepresentable) {
12761cb0ef41Sopenharmony_ci  Register dst_x = dst.gp().X();
12771cb0ef41Sopenharmony_ci  Register lhs_x = lhs.gp().X();
12781cb0ef41Sopenharmony_ci  Register rhs_x = rhs.gp().X();
12791cb0ef41Sopenharmony_ci  bool can_use_dst = !dst_x.Aliases(lhs_x) && !dst_x.Aliases(rhs_x);
12801cb0ef41Sopenharmony_ci  if (can_use_dst) {
12811cb0ef41Sopenharmony_ci    // Do div early.
12821cb0ef41Sopenharmony_ci    Sdiv(dst_x, lhs_x, rhs_x);
12831cb0ef41Sopenharmony_ci  }
12841cb0ef41Sopenharmony_ci  // Check for division by zero.
12851cb0ef41Sopenharmony_ci  Cbz(rhs_x, trap_div_by_zero);
12861cb0ef41Sopenharmony_ci  // Check for kMinInt / -1. This is unrepresentable.
12871cb0ef41Sopenharmony_ci  Cmp(rhs_x, -1);
12881cb0ef41Sopenharmony_ci  Ccmp(lhs_x, 1, NoFlag, eq);
12891cb0ef41Sopenharmony_ci  B(trap_div_unrepresentable, vs);
12901cb0ef41Sopenharmony_ci  if (!can_use_dst) {
12911cb0ef41Sopenharmony_ci    // Do div.
12921cb0ef41Sopenharmony_ci    Sdiv(dst_x, lhs_x, rhs_x);
12931cb0ef41Sopenharmony_ci  }
12941cb0ef41Sopenharmony_ci  return true;
12951cb0ef41Sopenharmony_ci}
12961cb0ef41Sopenharmony_ci
12971cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_divu(LiftoffRegister dst, LiftoffRegister lhs,
12981cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
12991cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13001cb0ef41Sopenharmony_ci  // Check for division by zero.
13011cb0ef41Sopenharmony_ci  Cbz(rhs.gp().X(), trap_div_by_zero);
13021cb0ef41Sopenharmony_ci  // Do div.
13031cb0ef41Sopenharmony_ci  Udiv(dst.gp().X(), lhs.gp().X(), rhs.gp().X());
13041cb0ef41Sopenharmony_ci  return true;
13051cb0ef41Sopenharmony_ci}
13061cb0ef41Sopenharmony_ci
13071cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_rems(LiftoffRegister dst, LiftoffRegister lhs,
13081cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13091cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13101cb0ef41Sopenharmony_ci  Register dst_x = dst.gp().X();
13111cb0ef41Sopenharmony_ci  Register lhs_x = lhs.gp().X();
13121cb0ef41Sopenharmony_ci  Register rhs_x = rhs.gp().X();
13131cb0ef41Sopenharmony_ci  // Do early div.
13141cb0ef41Sopenharmony_ci  // No need to check kMinInt / -1 because the result is kMinInt and then
13151cb0ef41Sopenharmony_ci  // kMinInt * -1 -> kMinInt. In this case, the Msub result is therefore 0.
13161cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
13171cb0ef41Sopenharmony_ci  Register scratch = temps.AcquireX();
13181cb0ef41Sopenharmony_ci  Sdiv(scratch, lhs_x, rhs_x);
13191cb0ef41Sopenharmony_ci  // Check for division by zero.
13201cb0ef41Sopenharmony_ci  Cbz(rhs_x, trap_div_by_zero);
13211cb0ef41Sopenharmony_ci  // Compute remainder.
13221cb0ef41Sopenharmony_ci  Msub(dst_x, scratch, rhs_x, lhs_x);
13231cb0ef41Sopenharmony_ci  return true;
13241cb0ef41Sopenharmony_ci}
13251cb0ef41Sopenharmony_ci
13261cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
13271cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13281cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13291cb0ef41Sopenharmony_ci  Register dst_x = dst.gp().X();
13301cb0ef41Sopenharmony_ci  Register lhs_x = lhs.gp().X();
13311cb0ef41Sopenharmony_ci  Register rhs_x = rhs.gp().X();
13321cb0ef41Sopenharmony_ci  // Do early div.
13331cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
13341cb0ef41Sopenharmony_ci  Register scratch = temps.AcquireX();
13351cb0ef41Sopenharmony_ci  Udiv(scratch, lhs_x, rhs_x);
13361cb0ef41Sopenharmony_ci  // Check for division by zero.
13371cb0ef41Sopenharmony_ci  Cbz(rhs_x, trap_div_by_zero);
13381cb0ef41Sopenharmony_ci  // Compute remainder.
13391cb0ef41Sopenharmony_ci  Msub(dst_x, scratch, rhs_x, lhs_x);
13401cb0ef41Sopenharmony_ci  return true;
13411cb0ef41Sopenharmony_ci}
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_u32_to_uintptr(Register dst, Register src) {
13441cb0ef41Sopenharmony_ci  Uxtw(dst, src);
13451cb0ef41Sopenharmony_ci}
13461cb0ef41Sopenharmony_ci
13471cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_copysign(DoubleRegister dst, DoubleRegister lhs,
13481cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
13491cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
13501cb0ef41Sopenharmony_ci  DoubleRegister scratch = temps.AcquireD();
13511cb0ef41Sopenharmony_ci  Ushr(scratch.V2S(), rhs.V2S(), 31);
13521cb0ef41Sopenharmony_ci  if (dst != lhs) {
13531cb0ef41Sopenharmony_ci    Fmov(dst.S(), lhs.S());
13541cb0ef41Sopenharmony_ci  }
13551cb0ef41Sopenharmony_ci  Sli(dst.V2S(), scratch.V2S(), 31);
13561cb0ef41Sopenharmony_ci}
13571cb0ef41Sopenharmony_ci
13581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_copysign(DoubleRegister dst, DoubleRegister lhs,
13591cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
13601cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
13611cb0ef41Sopenharmony_ci  DoubleRegister scratch = temps.AcquireD();
13621cb0ef41Sopenharmony_ci  Ushr(scratch.V1D(), rhs.V1D(), 63);
13631cb0ef41Sopenharmony_ci  if (dst != lhs) {
13641cb0ef41Sopenharmony_ci    Fmov(dst.D(), lhs.D());
13651cb0ef41Sopenharmony_ci  }
13661cb0ef41Sopenharmony_ci  Sli(dst.V1D(), scratch.V1D(), 63);
13671cb0ef41Sopenharmony_ci}
13681cb0ef41Sopenharmony_ci
13691cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode,
13701cb0ef41Sopenharmony_ci                                            LiftoffRegister dst,
13711cb0ef41Sopenharmony_ci                                            LiftoffRegister src, Label* trap) {
13721cb0ef41Sopenharmony_ci  switch (opcode) {
13731cb0ef41Sopenharmony_ci    case kExprI32ConvertI64:
13741cb0ef41Sopenharmony_ci      Mov(dst.gp().W(), src.gp().W());
13751cb0ef41Sopenharmony_ci      return true;
13761cb0ef41Sopenharmony_ci    case kExprI32SConvertF32:
13771cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().W(), src.fp().S());  // f32 -> i32 round to zero.
13781cb0ef41Sopenharmony_ci      // Check underflow and NaN.
13791cb0ef41Sopenharmony_ci      Fcmp(src.fp().S(), static_cast<float>(INT32_MIN));
13801cb0ef41Sopenharmony_ci      // Check overflow.
13811cb0ef41Sopenharmony_ci      Ccmp(dst.gp().W(), -1, VFlag, ge);
13821cb0ef41Sopenharmony_ci      B(trap, vs);
13831cb0ef41Sopenharmony_ci      return true;
13841cb0ef41Sopenharmony_ci    case kExprI32UConvertF32:
13851cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().W(), src.fp().S());  // f32 -> i32 round to zero.
13861cb0ef41Sopenharmony_ci      // Check underflow and NaN.
13871cb0ef41Sopenharmony_ci      Fcmp(src.fp().S(), -1.0);
13881cb0ef41Sopenharmony_ci      // Check overflow.
13891cb0ef41Sopenharmony_ci      Ccmp(dst.gp().W(), -1, ZFlag, gt);
13901cb0ef41Sopenharmony_ci      B(trap, eq);
13911cb0ef41Sopenharmony_ci      return true;
13921cb0ef41Sopenharmony_ci    case kExprI32SConvertF64: {
13931cb0ef41Sopenharmony_ci      // INT32_MIN and INT32_MAX are valid results, we cannot test the result
13941cb0ef41Sopenharmony_ci      // to detect the overflows. We could have done two immediate floating
13951cb0ef41Sopenharmony_ci      // point comparisons but it would have generated two conditional branches.
13961cb0ef41Sopenharmony_ci      UseScratchRegisterScope temps(this);
13971cb0ef41Sopenharmony_ci      VRegister fp_ref = temps.AcquireD();
13981cb0ef41Sopenharmony_ci      VRegister fp_cmp = temps.AcquireD();
13991cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().W(), src.fp().D());  // f64 -> i32 round to zero.
14001cb0ef41Sopenharmony_ci      Frintz(fp_ref, src.fp().D());        // f64 -> f64 round to zero.
14011cb0ef41Sopenharmony_ci      Scvtf(fp_cmp, dst.gp().W());         // i32 -> f64.
14021cb0ef41Sopenharmony_ci      // If comparison fails, we have an overflow or a NaN.
14031cb0ef41Sopenharmony_ci      Fcmp(fp_cmp, fp_ref);
14041cb0ef41Sopenharmony_ci      B(trap, ne);
14051cb0ef41Sopenharmony_ci      return true;
14061cb0ef41Sopenharmony_ci    }
14071cb0ef41Sopenharmony_ci    case kExprI32UConvertF64: {
14081cb0ef41Sopenharmony_ci      // INT32_MAX is a valid result, we cannot test the result to detect the
14091cb0ef41Sopenharmony_ci      // overflows. We could have done two immediate floating point comparisons
14101cb0ef41Sopenharmony_ci      // but it would have generated two conditional branches.
14111cb0ef41Sopenharmony_ci      UseScratchRegisterScope temps(this);
14121cb0ef41Sopenharmony_ci      VRegister fp_ref = temps.AcquireD();
14131cb0ef41Sopenharmony_ci      VRegister fp_cmp = temps.AcquireD();
14141cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().W(), src.fp().D());  // f64 -> i32 round to zero.
14151cb0ef41Sopenharmony_ci      Frintz(fp_ref, src.fp().D());        // f64 -> f64 round to zero.
14161cb0ef41Sopenharmony_ci      Ucvtf(fp_cmp, dst.gp().W());         // i32 -> f64.
14171cb0ef41Sopenharmony_ci      // If comparison fails, we have an overflow or a NaN.
14181cb0ef41Sopenharmony_ci      Fcmp(fp_cmp, fp_ref);
14191cb0ef41Sopenharmony_ci      B(trap, ne);
14201cb0ef41Sopenharmony_ci      return true;
14211cb0ef41Sopenharmony_ci    }
14221cb0ef41Sopenharmony_ci    case kExprI32SConvertSatF32:
14231cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().W(), src.fp().S());
14241cb0ef41Sopenharmony_ci      return true;
14251cb0ef41Sopenharmony_ci    case kExprI32UConvertSatF32:
14261cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().W(), src.fp().S());
14271cb0ef41Sopenharmony_ci      return true;
14281cb0ef41Sopenharmony_ci    case kExprI32SConvertSatF64:
14291cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().W(), src.fp().D());
14301cb0ef41Sopenharmony_ci      return true;
14311cb0ef41Sopenharmony_ci    case kExprI32UConvertSatF64:
14321cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().W(), src.fp().D());
14331cb0ef41Sopenharmony_ci      return true;
14341cb0ef41Sopenharmony_ci    case kExprI64SConvertSatF32:
14351cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().X(), src.fp().S());
14361cb0ef41Sopenharmony_ci      return true;
14371cb0ef41Sopenharmony_ci    case kExprI64UConvertSatF32:
14381cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().X(), src.fp().S());
14391cb0ef41Sopenharmony_ci      return true;
14401cb0ef41Sopenharmony_ci    case kExprI64SConvertSatF64:
14411cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().X(), src.fp().D());
14421cb0ef41Sopenharmony_ci      return true;
14431cb0ef41Sopenharmony_ci    case kExprI64UConvertSatF64:
14441cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().X(), src.fp().D());
14451cb0ef41Sopenharmony_ci      return true;
14461cb0ef41Sopenharmony_ci    case kExprI32ReinterpretF32:
14471cb0ef41Sopenharmony_ci      Fmov(dst.gp().W(), src.fp().S());
14481cb0ef41Sopenharmony_ci      return true;
14491cb0ef41Sopenharmony_ci    case kExprI64SConvertI32:
14501cb0ef41Sopenharmony_ci      Sxtw(dst.gp().X(), src.gp().W());
14511cb0ef41Sopenharmony_ci      return true;
14521cb0ef41Sopenharmony_ci    case kExprI64SConvertF32:
14531cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().X(), src.fp().S());  // f32 -> i64 round to zero.
14541cb0ef41Sopenharmony_ci      // Check underflow and NaN.
14551cb0ef41Sopenharmony_ci      Fcmp(src.fp().S(), static_cast<float>(INT64_MIN));
14561cb0ef41Sopenharmony_ci      // Check overflow.
14571cb0ef41Sopenharmony_ci      Ccmp(dst.gp().X(), -1, VFlag, ge);
14581cb0ef41Sopenharmony_ci      B(trap, vs);
14591cb0ef41Sopenharmony_ci      return true;
14601cb0ef41Sopenharmony_ci    case kExprI64UConvertF32:
14611cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().X(), src.fp().S());  // f32 -> i64 round to zero.
14621cb0ef41Sopenharmony_ci      // Check underflow and NaN.
14631cb0ef41Sopenharmony_ci      Fcmp(src.fp().S(), -1.0);
14641cb0ef41Sopenharmony_ci      // Check overflow.
14651cb0ef41Sopenharmony_ci      Ccmp(dst.gp().X(), -1, ZFlag, gt);
14661cb0ef41Sopenharmony_ci      B(trap, eq);
14671cb0ef41Sopenharmony_ci      return true;
14681cb0ef41Sopenharmony_ci    case kExprI64SConvertF64:
14691cb0ef41Sopenharmony_ci      Fcvtzs(dst.gp().X(), src.fp().D());  // f64 -> i64 round to zero.
14701cb0ef41Sopenharmony_ci      // Check underflow and NaN.
14711cb0ef41Sopenharmony_ci      Fcmp(src.fp().D(), static_cast<float>(INT64_MIN));
14721cb0ef41Sopenharmony_ci      // Check overflow.
14731cb0ef41Sopenharmony_ci      Ccmp(dst.gp().X(), -1, VFlag, ge);
14741cb0ef41Sopenharmony_ci      B(trap, vs);
14751cb0ef41Sopenharmony_ci      return true;
14761cb0ef41Sopenharmony_ci    case kExprI64UConvertF64:
14771cb0ef41Sopenharmony_ci      Fcvtzu(dst.gp().X(), src.fp().D());  // f64 -> i64 round to zero.
14781cb0ef41Sopenharmony_ci      // Check underflow and NaN.
14791cb0ef41Sopenharmony_ci      Fcmp(src.fp().D(), -1.0);
14801cb0ef41Sopenharmony_ci      // Check overflow.
14811cb0ef41Sopenharmony_ci      Ccmp(dst.gp().X(), -1, ZFlag, gt);
14821cb0ef41Sopenharmony_ci      B(trap, eq);
14831cb0ef41Sopenharmony_ci      return true;
14841cb0ef41Sopenharmony_ci    case kExprI64UConvertI32:
14851cb0ef41Sopenharmony_ci      Mov(dst.gp().W(), src.gp().W());
14861cb0ef41Sopenharmony_ci      return true;
14871cb0ef41Sopenharmony_ci    case kExprI64ReinterpretF64:
14881cb0ef41Sopenharmony_ci      Fmov(dst.gp().X(), src.fp().D());
14891cb0ef41Sopenharmony_ci      return true;
14901cb0ef41Sopenharmony_ci    case kExprF32SConvertI32:
14911cb0ef41Sopenharmony_ci      Scvtf(dst.fp().S(), src.gp().W());
14921cb0ef41Sopenharmony_ci      return true;
14931cb0ef41Sopenharmony_ci    case kExprF32UConvertI32:
14941cb0ef41Sopenharmony_ci      Ucvtf(dst.fp().S(), src.gp().W());
14951cb0ef41Sopenharmony_ci      return true;
14961cb0ef41Sopenharmony_ci    case kExprF32SConvertI64:
14971cb0ef41Sopenharmony_ci      Scvtf(dst.fp().S(), src.gp().X());
14981cb0ef41Sopenharmony_ci      return true;
14991cb0ef41Sopenharmony_ci    case kExprF32UConvertI64:
15001cb0ef41Sopenharmony_ci      Ucvtf(dst.fp().S(), src.gp().X());
15011cb0ef41Sopenharmony_ci      return true;
15021cb0ef41Sopenharmony_ci    case kExprF32ConvertF64:
15031cb0ef41Sopenharmony_ci      Fcvt(dst.fp().S(), src.fp().D());
15041cb0ef41Sopenharmony_ci      return true;
15051cb0ef41Sopenharmony_ci    case kExprF32ReinterpretI32:
15061cb0ef41Sopenharmony_ci      Fmov(dst.fp().S(), src.gp().W());
15071cb0ef41Sopenharmony_ci      return true;
15081cb0ef41Sopenharmony_ci    case kExprF64SConvertI32:
15091cb0ef41Sopenharmony_ci      Scvtf(dst.fp().D(), src.gp().W());
15101cb0ef41Sopenharmony_ci      return true;
15111cb0ef41Sopenharmony_ci    case kExprF64UConvertI32:
15121cb0ef41Sopenharmony_ci      Ucvtf(dst.fp().D(), src.gp().W());
15131cb0ef41Sopenharmony_ci      return true;
15141cb0ef41Sopenharmony_ci    case kExprF64SConvertI64:
15151cb0ef41Sopenharmony_ci      Scvtf(dst.fp().D(), src.gp().X());
15161cb0ef41Sopenharmony_ci      return true;
15171cb0ef41Sopenharmony_ci    case kExprF64UConvertI64:
15181cb0ef41Sopenharmony_ci      Ucvtf(dst.fp().D(), src.gp().X());
15191cb0ef41Sopenharmony_ci      return true;
15201cb0ef41Sopenharmony_ci    case kExprF64ConvertF32:
15211cb0ef41Sopenharmony_ci      Fcvt(dst.fp().D(), src.fp().S());
15221cb0ef41Sopenharmony_ci      return true;
15231cb0ef41Sopenharmony_ci    case kExprF64ReinterpretI64:
15241cb0ef41Sopenharmony_ci      Fmov(dst.fp().D(), src.gp().X());
15251cb0ef41Sopenharmony_ci      return true;
15261cb0ef41Sopenharmony_ci    default:
15271cb0ef41Sopenharmony_ci      UNREACHABLE();
15281cb0ef41Sopenharmony_ci  }
15291cb0ef41Sopenharmony_ci}
15301cb0ef41Sopenharmony_ci
15311cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_signextend_i8(Register dst, Register src) {
15321cb0ef41Sopenharmony_ci  sxtb(dst.W(), src.W());
15331cb0ef41Sopenharmony_ci}
15341cb0ef41Sopenharmony_ci
15351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_signextend_i16(Register dst, Register src) {
15361cb0ef41Sopenharmony_ci  sxth(dst.W(), src.W());
15371cb0ef41Sopenharmony_ci}
15381cb0ef41Sopenharmony_ci
15391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i8(LiftoffRegister dst,
15401cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
15411cb0ef41Sopenharmony_ci  sxtb(dst.gp(), src.gp());
15421cb0ef41Sopenharmony_ci}
15431cb0ef41Sopenharmony_ci
15441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i16(LiftoffRegister dst,
15451cb0ef41Sopenharmony_ci                                               LiftoffRegister src) {
15461cb0ef41Sopenharmony_ci  sxth(dst.gp(), src.gp());
15471cb0ef41Sopenharmony_ci}
15481cb0ef41Sopenharmony_ci
15491cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i32(LiftoffRegister dst,
15501cb0ef41Sopenharmony_ci                                               LiftoffRegister src) {
15511cb0ef41Sopenharmony_ci  sxtw(dst.gp(), src.gp());
15521cb0ef41Sopenharmony_ci}
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_jump(Label* label) { B(label); }
15551cb0ef41Sopenharmony_ci
15561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_jump(Register target) { Br(target); }
15571cb0ef41Sopenharmony_ci
15581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
15591cb0ef41Sopenharmony_ci                                      Label* label, ValueKind kind,
15601cb0ef41Sopenharmony_ci                                      Register lhs, Register rhs) {
15611cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
15621cb0ef41Sopenharmony_ci  switch (kind) {
15631cb0ef41Sopenharmony_ci    case kI32:
15641cb0ef41Sopenharmony_ci      if (rhs.is_valid()) {
15651cb0ef41Sopenharmony_ci        Cmp(lhs.W(), rhs.W());
15661cb0ef41Sopenharmony_ci      } else {
15671cb0ef41Sopenharmony_ci        Cmp(lhs.W(), wzr);
15681cb0ef41Sopenharmony_ci      }
15691cb0ef41Sopenharmony_ci      break;
15701cb0ef41Sopenharmony_ci    case kRef:
15711cb0ef41Sopenharmony_ci    case kOptRef:
15721cb0ef41Sopenharmony_ci    case kRtt:
15731cb0ef41Sopenharmony_ci      DCHECK(rhs.is_valid());
15741cb0ef41Sopenharmony_ci      DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
15751cb0ef41Sopenharmony_ci      V8_FALLTHROUGH;
15761cb0ef41Sopenharmony_ci    case kI64:
15771cb0ef41Sopenharmony_ci      if (rhs.is_valid()) {
15781cb0ef41Sopenharmony_ci        Cmp(lhs.X(), rhs.X());
15791cb0ef41Sopenharmony_ci      } else {
15801cb0ef41Sopenharmony_ci        Cmp(lhs.X(), xzr);
15811cb0ef41Sopenharmony_ci      }
15821cb0ef41Sopenharmony_ci      break;
15831cb0ef41Sopenharmony_ci    default:
15841cb0ef41Sopenharmony_ci      UNREACHABLE();
15851cb0ef41Sopenharmony_ci  }
15861cb0ef41Sopenharmony_ci  B(label, cond);
15871cb0ef41Sopenharmony_ci}
15881cb0ef41Sopenharmony_ci
15891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_cond_jumpi(LiftoffCondition liftoff_cond,
15901cb0ef41Sopenharmony_ci                                           Label* label, Register lhs,
15911cb0ef41Sopenharmony_ci                                           int32_t imm) {
15921cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
15931cb0ef41Sopenharmony_ci  Cmp(lhs.W(), Operand(imm));
15941cb0ef41Sopenharmony_ci  B(label, cond);
15951cb0ef41Sopenharmony_ci}
15961cb0ef41Sopenharmony_ci
15971cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_subi_jump_negative(Register value,
15981cb0ef41Sopenharmony_ci                                                   int subtrahend,
15991cb0ef41Sopenharmony_ci                                                   Label* result_negative) {
16001cb0ef41Sopenharmony_ci  Subs(value.W(), value.W(), Immediate(subtrahend));
16011cb0ef41Sopenharmony_ci  B(result_negative, mi);
16021cb0ef41Sopenharmony_ci}
16031cb0ef41Sopenharmony_ci
16041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
16051cb0ef41Sopenharmony_ci  Cmp(src.W(), wzr);
16061cb0ef41Sopenharmony_ci  Cset(dst.W(), eq);
16071cb0ef41Sopenharmony_ci}
16081cb0ef41Sopenharmony_ci
16091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_set_cond(LiftoffCondition liftoff_cond,
16101cb0ef41Sopenharmony_ci                                         Register dst, Register lhs,
16111cb0ef41Sopenharmony_ci                                         Register rhs) {
16121cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
16131cb0ef41Sopenharmony_ci  Cmp(lhs.W(), rhs.W());
16141cb0ef41Sopenharmony_ci  Cset(dst.W(), cond);
16151cb0ef41Sopenharmony_ci}
16161cb0ef41Sopenharmony_ci
16171cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
16181cb0ef41Sopenharmony_ci  Cmp(src.gp().X(), xzr);
16191cb0ef41Sopenharmony_ci  Cset(dst.W(), eq);
16201cb0ef41Sopenharmony_ci}
16211cb0ef41Sopenharmony_ci
16221cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_set_cond(LiftoffCondition liftoff_cond,
16231cb0ef41Sopenharmony_ci                                         Register dst, LiftoffRegister lhs,
16241cb0ef41Sopenharmony_ci                                         LiftoffRegister rhs) {
16251cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
16261cb0ef41Sopenharmony_ci  Cmp(lhs.gp().X(), rhs.gp().X());
16271cb0ef41Sopenharmony_ci  Cset(dst.W(), cond);
16281cb0ef41Sopenharmony_ci}
16291cb0ef41Sopenharmony_ci
16301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_set_cond(LiftoffCondition liftoff_cond,
16311cb0ef41Sopenharmony_ci                                         Register dst, DoubleRegister lhs,
16321cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
16331cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
16341cb0ef41Sopenharmony_ci  Fcmp(lhs.S(), rhs.S());
16351cb0ef41Sopenharmony_ci  Cset(dst.W(), cond);
16361cb0ef41Sopenharmony_ci  if (cond != ne) {
16371cb0ef41Sopenharmony_ci    // If V flag set, at least one of the arguments was a Nan -> false.
16381cb0ef41Sopenharmony_ci    Csel(dst.W(), wzr, dst.W(), vs);
16391cb0ef41Sopenharmony_ci  }
16401cb0ef41Sopenharmony_ci}
16411cb0ef41Sopenharmony_ci
16421cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_set_cond(LiftoffCondition liftoff_cond,
16431cb0ef41Sopenharmony_ci                                         Register dst, DoubleRegister lhs,
16441cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
16451cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
16461cb0ef41Sopenharmony_ci  Fcmp(lhs.D(), rhs.D());
16471cb0ef41Sopenharmony_ci  Cset(dst.W(), cond);
16481cb0ef41Sopenharmony_ci  if (cond != ne) {
16491cb0ef41Sopenharmony_ci    // If V flag set, at least one of the arguments was a Nan -> false.
16501cb0ef41Sopenharmony_ci    Csel(dst.W(), wzr, dst.W(), vs);
16511cb0ef41Sopenharmony_ci  }
16521cb0ef41Sopenharmony_ci}
16531cb0ef41Sopenharmony_ci
16541cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_select(LiftoffRegister dst, Register condition,
16551cb0ef41Sopenharmony_ci                                   LiftoffRegister true_value,
16561cb0ef41Sopenharmony_ci                                   LiftoffRegister false_value,
16571cb0ef41Sopenharmony_ci                                   ValueKind kind) {
16581cb0ef41Sopenharmony_ci  return false;
16591cb0ef41Sopenharmony_ci}
16601cb0ef41Sopenharmony_ci
16611cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_smi_check(Register obj, Label* target,
16621cb0ef41Sopenharmony_ci                                      SmiCheckMode mode) {
16631cb0ef41Sopenharmony_ci  Label* smi_label = mode == kJumpOnSmi ? target : nullptr;
16641cb0ef41Sopenharmony_ci  Label* not_smi_label = mode == kJumpOnNotSmi ? target : nullptr;
16651cb0ef41Sopenharmony_ci  JumpIfSmi(obj, smi_label, not_smi_label);
16661cb0ef41Sopenharmony_ci}
16671cb0ef41Sopenharmony_ci
16681cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTransform(LiftoffRegister dst, Register src_addr,
16691cb0ef41Sopenharmony_ci                                     Register offset_reg, uintptr_t offset_imm,
16701cb0ef41Sopenharmony_ci                                     LoadType type,
16711cb0ef41Sopenharmony_ci                                     LoadTransformationKind transform,
16721cb0ef41Sopenharmony_ci                                     uint32_t* protected_load_pc) {
16731cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
16741cb0ef41Sopenharmony_ci  MemOperand src_op =
16751cb0ef41Sopenharmony_ci      transform == LoadTransformationKind::kSplat
16761cb0ef41Sopenharmony_ci          ? MemOperand{liftoff::GetEffectiveAddress(this, &temps, src_addr,
16771cb0ef41Sopenharmony_ci                                                    offset_reg, offset_imm)}
16781cb0ef41Sopenharmony_ci          : liftoff::GetMemOp(this, &temps, src_addr, offset_reg, offset_imm);
16791cb0ef41Sopenharmony_ci  *protected_load_pc = pc_offset();
16801cb0ef41Sopenharmony_ci  MachineType memtype = type.mem_type();
16811cb0ef41Sopenharmony_ci
16821cb0ef41Sopenharmony_ci  if (transform == LoadTransformationKind::kExtend) {
16831cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int8()) {
16841cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
16851cb0ef41Sopenharmony_ci      Sxtl(dst.fp().V8H(), dst.fp().V8B());
16861cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint8()) {
16871cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
16881cb0ef41Sopenharmony_ci      Uxtl(dst.fp().V8H(), dst.fp().V8B());
16891cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int16()) {
16901cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
16911cb0ef41Sopenharmony_ci      Sxtl(dst.fp().V4S(), dst.fp().V4H());
16921cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint16()) {
16931cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
16941cb0ef41Sopenharmony_ci      Uxtl(dst.fp().V4S(), dst.fp().V4H());
16951cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int32()) {
16961cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
16971cb0ef41Sopenharmony_ci      Sxtl(dst.fp().V2D(), dst.fp().V2S());
16981cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint32()) {
16991cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
17001cb0ef41Sopenharmony_ci      Uxtl(dst.fp().V2D(), dst.fp().V2S());
17011cb0ef41Sopenharmony_ci    }
17021cb0ef41Sopenharmony_ci  } else if (transform == LoadTransformationKind::kZeroExtend) {
17031cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int32()) {
17041cb0ef41Sopenharmony_ci      Ldr(dst.fp().S(), src_op);
17051cb0ef41Sopenharmony_ci    } else {
17061cb0ef41Sopenharmony_ci      DCHECK_EQ(MachineType::Int64(), memtype);
17071cb0ef41Sopenharmony_ci      Ldr(dst.fp().D(), src_op);
17081cb0ef41Sopenharmony_ci    }
17091cb0ef41Sopenharmony_ci  } else {
17101cb0ef41Sopenharmony_ci    DCHECK_EQ(LoadTransformationKind::kSplat, transform);
17111cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int8()) {
17121cb0ef41Sopenharmony_ci      ld1r(dst.fp().V16B(), src_op);
17131cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int16()) {
17141cb0ef41Sopenharmony_ci      ld1r(dst.fp().V8H(), src_op);
17151cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int32()) {
17161cb0ef41Sopenharmony_ci      ld1r(dst.fp().V4S(), src_op);
17171cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int64()) {
17181cb0ef41Sopenharmony_ci      ld1r(dst.fp().V2D(), src_op);
17191cb0ef41Sopenharmony_ci    }
17201cb0ef41Sopenharmony_ci  }
17211cb0ef41Sopenharmony_ci}
17221cb0ef41Sopenharmony_ci
17231cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
17241cb0ef41Sopenharmony_ci                                Register addr, Register offset_reg,
17251cb0ef41Sopenharmony_ci                                uintptr_t offset_imm, LoadType type,
17261cb0ef41Sopenharmony_ci                                uint8_t laneidx, uint32_t* protected_load_pc) {
17271cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
17281cb0ef41Sopenharmony_ci  MemOperand src_op{
17291cb0ef41Sopenharmony_ci      liftoff::GetEffectiveAddress(this, &temps, addr, offset_reg, offset_imm)};
17301cb0ef41Sopenharmony_ci
17311cb0ef41Sopenharmony_ci  MachineType mem_type = type.mem_type();
17321cb0ef41Sopenharmony_ci  if (dst != src) {
17331cb0ef41Sopenharmony_ci    Mov(dst.fp().Q(), src.fp().Q());
17341cb0ef41Sopenharmony_ci  }
17351cb0ef41Sopenharmony_ci
17361cb0ef41Sopenharmony_ci  *protected_load_pc = pc_offset();
17371cb0ef41Sopenharmony_ci  if (mem_type == MachineType::Int8()) {
17381cb0ef41Sopenharmony_ci    ld1(dst.fp().B(), laneidx, src_op);
17391cb0ef41Sopenharmony_ci  } else if (mem_type == MachineType::Int16()) {
17401cb0ef41Sopenharmony_ci    ld1(dst.fp().H(), laneidx, src_op);
17411cb0ef41Sopenharmony_ci  } else if (mem_type == MachineType::Int32()) {
17421cb0ef41Sopenharmony_ci    ld1(dst.fp().S(), laneidx, src_op);
17431cb0ef41Sopenharmony_ci  } else if (mem_type == MachineType::Int64()) {
17441cb0ef41Sopenharmony_ci    ld1(dst.fp().D(), laneidx, src_op);
17451cb0ef41Sopenharmony_ci  } else {
17461cb0ef41Sopenharmony_ci    UNREACHABLE();
17471cb0ef41Sopenharmony_ci  }
17481cb0ef41Sopenharmony_ci}
17491cb0ef41Sopenharmony_ci
17501cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreLane(Register dst, Register offset,
17511cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister src,
17521cb0ef41Sopenharmony_ci                                 StoreType type, uint8_t lane,
17531cb0ef41Sopenharmony_ci                                 uint32_t* protected_store_pc) {
17541cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
17551cb0ef41Sopenharmony_ci  MemOperand dst_op{
17561cb0ef41Sopenharmony_ci      liftoff::GetEffectiveAddress(this, &temps, dst, offset, offset_imm)};
17571cb0ef41Sopenharmony_ci  if (protected_store_pc) *protected_store_pc = pc_offset();
17581cb0ef41Sopenharmony_ci
17591cb0ef41Sopenharmony_ci  MachineRepresentation rep = type.mem_rep();
17601cb0ef41Sopenharmony_ci  if (rep == MachineRepresentation::kWord8) {
17611cb0ef41Sopenharmony_ci    st1(src.fp().B(), lane, dst_op);
17621cb0ef41Sopenharmony_ci  } else if (rep == MachineRepresentation::kWord16) {
17631cb0ef41Sopenharmony_ci    st1(src.fp().H(), lane, dst_op);
17641cb0ef41Sopenharmony_ci  } else if (rep == MachineRepresentation::kWord32) {
17651cb0ef41Sopenharmony_ci    st1(src.fp().S(), lane, dst_op);
17661cb0ef41Sopenharmony_ci  } else {
17671cb0ef41Sopenharmony_ci    DCHECK_EQ(MachineRepresentation::kWord64, rep);
17681cb0ef41Sopenharmony_ci    st1(src.fp().D(), lane, dst_op);
17691cb0ef41Sopenharmony_ci  }
17701cb0ef41Sopenharmony_ci}
17711cb0ef41Sopenharmony_ci
17721cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_swizzle(LiftoffRegister dst,
17731cb0ef41Sopenharmony_ci                                          LiftoffRegister lhs,
17741cb0ef41Sopenharmony_ci                                          LiftoffRegister rhs) {
17751cb0ef41Sopenharmony_ci  Tbl(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
17761cb0ef41Sopenharmony_ci}
17771cb0ef41Sopenharmony_ci
17781cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_splat(LiftoffRegister dst,
17791cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
17801cb0ef41Sopenharmony_ci  Dup(dst.fp().V2D(), src.fp().D(), 0);
17811cb0ef41Sopenharmony_ci}
17821cb0ef41Sopenharmony_ci
17831cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_extract_lane(LiftoffRegister dst,
17841cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
17851cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
17861cb0ef41Sopenharmony_ci  Mov(dst.fp().D(), lhs.fp().V2D(), imm_lane_idx);
17871cb0ef41Sopenharmony_ci}
17881cb0ef41Sopenharmony_ci
17891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_replace_lane(LiftoffRegister dst,
17901cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
17911cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
17921cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
17931cb0ef41Sopenharmony_ci  if (dst != src1) {
17941cb0ef41Sopenharmony_ci    Mov(dst.fp().V2D(), src1.fp().V2D());
17951cb0ef41Sopenharmony_ci  }
17961cb0ef41Sopenharmony_ci  Mov(dst.fp().V2D(), imm_lane_idx, src2.fp().V2D(), 0);
17971cb0ef41Sopenharmony_ci}
17981cb0ef41Sopenharmony_ci
17991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_abs(LiftoffRegister dst,
18001cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
18011cb0ef41Sopenharmony_ci  Fabs(dst.fp().V2D(), src.fp().V2D());
18021cb0ef41Sopenharmony_ci}
18031cb0ef41Sopenharmony_ci
18041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_neg(LiftoffRegister dst,
18051cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
18061cb0ef41Sopenharmony_ci  Fneg(dst.fp().V2D(), src.fp().V2D());
18071cb0ef41Sopenharmony_ci}
18081cb0ef41Sopenharmony_ci
18091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_sqrt(LiftoffRegister dst,
18101cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
18111cb0ef41Sopenharmony_ci  Fsqrt(dst.fp().V2D(), src.fp().V2D());
18121cb0ef41Sopenharmony_ci}
18131cb0ef41Sopenharmony_ci
18141cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_ceil(LiftoffRegister dst,
18151cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
18161cb0ef41Sopenharmony_ci  Frintp(dst.fp().V2D(), src.fp().V2D());
18171cb0ef41Sopenharmony_ci  return true;
18181cb0ef41Sopenharmony_ci}
18191cb0ef41Sopenharmony_ci
18201cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_floor(LiftoffRegister dst,
18211cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
18221cb0ef41Sopenharmony_ci  Frintm(dst.fp().V2D(), src.fp().V2D());
18231cb0ef41Sopenharmony_ci  return true;
18241cb0ef41Sopenharmony_ci}
18251cb0ef41Sopenharmony_ci
18261cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_trunc(LiftoffRegister dst,
18271cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
18281cb0ef41Sopenharmony_ci  Frintz(dst.fp().V2D(), src.fp().V2D());
18291cb0ef41Sopenharmony_ci  return true;
18301cb0ef41Sopenharmony_ci}
18311cb0ef41Sopenharmony_ci
18321cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_nearest_int(LiftoffRegister dst,
18331cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
18341cb0ef41Sopenharmony_ci  Frintn(dst.fp().V2D(), src.fp().V2D());
18351cb0ef41Sopenharmony_ci  return true;
18361cb0ef41Sopenharmony_ci}
18371cb0ef41Sopenharmony_ci
18381cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
18391cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18401cb0ef41Sopenharmony_ci  Fadd(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18411cb0ef41Sopenharmony_ci}
18421cb0ef41Sopenharmony_ci
18431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
18441cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18451cb0ef41Sopenharmony_ci  Fsub(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18461cb0ef41Sopenharmony_ci}
18471cb0ef41Sopenharmony_ci
18481cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
18491cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18501cb0ef41Sopenharmony_ci  Fmul(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18511cb0ef41Sopenharmony_ci}
18521cb0ef41Sopenharmony_ci
18531cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_div(LiftoffRegister dst, LiftoffRegister lhs,
18541cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18551cb0ef41Sopenharmony_ci  Fdiv(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18561cb0ef41Sopenharmony_ci}
18571cb0ef41Sopenharmony_ci
18581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_min(LiftoffRegister dst, LiftoffRegister lhs,
18591cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18601cb0ef41Sopenharmony_ci  Fmin(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18611cb0ef41Sopenharmony_ci}
18621cb0ef41Sopenharmony_ci
18631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_max(LiftoffRegister dst, LiftoffRegister lhs,
18641cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
18651cb0ef41Sopenharmony_ci  Fmax(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18661cb0ef41Sopenharmony_ci}
18671cb0ef41Sopenharmony_ci
18681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_pmin(LiftoffRegister dst, LiftoffRegister lhs,
18691cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
18701cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
18711cb0ef41Sopenharmony_ci
18721cb0ef41Sopenharmony_ci  VRegister tmp = dst.fp();
18731cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
18741cb0ef41Sopenharmony_ci    tmp = temps.AcquireV(kFormat2D);
18751cb0ef41Sopenharmony_ci  }
18761cb0ef41Sopenharmony_ci
18771cb0ef41Sopenharmony_ci  Fcmgt(tmp.V2D(), lhs.fp().V2D(), rhs.fp().V2D());
18781cb0ef41Sopenharmony_ci  Bsl(tmp.V16B(), rhs.fp().V16B(), lhs.fp().V16B());
18791cb0ef41Sopenharmony_ci
18801cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
18811cb0ef41Sopenharmony_ci    Mov(dst.fp().V2D(), tmp);
18821cb0ef41Sopenharmony_ci  }
18831cb0ef41Sopenharmony_ci}
18841cb0ef41Sopenharmony_ci
18851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_pmax(LiftoffRegister dst, LiftoffRegister lhs,
18861cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
18871cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
18881cb0ef41Sopenharmony_ci
18891cb0ef41Sopenharmony_ci  VRegister tmp = dst.fp();
18901cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
18911cb0ef41Sopenharmony_ci    tmp = temps.AcquireV(kFormat2D);
18921cb0ef41Sopenharmony_ci  }
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_ci  Fcmgt(tmp.V2D(), rhs.fp().V2D(), lhs.fp().V2D());
18951cb0ef41Sopenharmony_ci  Bsl(tmp.V16B(), rhs.fp().V16B(), lhs.fp().V16B());
18961cb0ef41Sopenharmony_ci
18971cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
18981cb0ef41Sopenharmony_ci    Mov(dst.fp().V2D(), tmp);
18991cb0ef41Sopenharmony_ci  }
19001cb0ef41Sopenharmony_ci}
19011cb0ef41Sopenharmony_ci
19021cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_convert_low_i32x4_s(LiftoffRegister dst,
19031cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
19041cb0ef41Sopenharmony_ci  Sxtl(dst.fp().V2D(), src.fp().V2S());
19051cb0ef41Sopenharmony_ci  Scvtf(dst.fp().V2D(), dst.fp().V2D());
19061cb0ef41Sopenharmony_ci}
19071cb0ef41Sopenharmony_ci
19081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_convert_low_i32x4_u(LiftoffRegister dst,
19091cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
19101cb0ef41Sopenharmony_ci  Uxtl(dst.fp().V2D(), src.fp().V2S());
19111cb0ef41Sopenharmony_ci  Ucvtf(dst.fp().V2D(), dst.fp().V2D());
19121cb0ef41Sopenharmony_ci}
19131cb0ef41Sopenharmony_ci
19141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_promote_low_f32x4(LiftoffRegister dst,
19151cb0ef41Sopenharmony_ci                                                    LiftoffRegister src) {
19161cb0ef41Sopenharmony_ci  Fcvtl(dst.fp().V2D(), src.fp().V2S());
19171cb0ef41Sopenharmony_ci}
19181cb0ef41Sopenharmony_ci
19191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_splat(LiftoffRegister dst,
19201cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
19211cb0ef41Sopenharmony_ci  Dup(dst.fp().V4S(), src.fp().S(), 0);
19221cb0ef41Sopenharmony_ci}
19231cb0ef41Sopenharmony_ci
19241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_extract_lane(LiftoffRegister dst,
19251cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
19261cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
19271cb0ef41Sopenharmony_ci  Mov(dst.fp().S(), lhs.fp().V4S(), imm_lane_idx);
19281cb0ef41Sopenharmony_ci}
19291cb0ef41Sopenharmony_ci
19301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_replace_lane(LiftoffRegister dst,
19311cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
19321cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
19331cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
19341cb0ef41Sopenharmony_ci  if (dst != src1) {
19351cb0ef41Sopenharmony_ci    Mov(dst.fp().V4S(), src1.fp().V4S());
19361cb0ef41Sopenharmony_ci  }
19371cb0ef41Sopenharmony_ci  Mov(dst.fp().V4S(), imm_lane_idx, src2.fp().V4S(), 0);
19381cb0ef41Sopenharmony_ci}
19391cb0ef41Sopenharmony_ci
19401cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_abs(LiftoffRegister dst,
19411cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
19421cb0ef41Sopenharmony_ci  Fabs(dst.fp().V4S(), src.fp().V4S());
19431cb0ef41Sopenharmony_ci}
19441cb0ef41Sopenharmony_ci
19451cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_neg(LiftoffRegister dst,
19461cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
19471cb0ef41Sopenharmony_ci  Fneg(dst.fp().V4S(), src.fp().V4S());
19481cb0ef41Sopenharmony_ci}
19491cb0ef41Sopenharmony_ci
19501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sqrt(LiftoffRegister dst,
19511cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
19521cb0ef41Sopenharmony_ci  Fsqrt(dst.fp().V4S(), src.fp().V4S());
19531cb0ef41Sopenharmony_ci}
19541cb0ef41Sopenharmony_ci
19551cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_ceil(LiftoffRegister dst,
19561cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
19571cb0ef41Sopenharmony_ci  Frintp(dst.fp().V4S(), src.fp().V4S());
19581cb0ef41Sopenharmony_ci  return true;
19591cb0ef41Sopenharmony_ci}
19601cb0ef41Sopenharmony_ci
19611cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_floor(LiftoffRegister dst,
19621cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
19631cb0ef41Sopenharmony_ci  Frintm(dst.fp().V4S(), src.fp().V4S());
19641cb0ef41Sopenharmony_ci  return true;
19651cb0ef41Sopenharmony_ci}
19661cb0ef41Sopenharmony_ci
19671cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_trunc(LiftoffRegister dst,
19681cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
19691cb0ef41Sopenharmony_ci  Frintz(dst.fp().V4S(), src.fp().V4S());
19701cb0ef41Sopenharmony_ci  return true;
19711cb0ef41Sopenharmony_ci}
19721cb0ef41Sopenharmony_ci
19731cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_nearest_int(LiftoffRegister dst,
19741cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
19751cb0ef41Sopenharmony_ci  Frintn(dst.fp().V4S(), src.fp().V4S());
19761cb0ef41Sopenharmony_ci  return true;
19771cb0ef41Sopenharmony_ci}
19781cb0ef41Sopenharmony_ci
19791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
19801cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
19811cb0ef41Sopenharmony_ci  Fadd(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
19821cb0ef41Sopenharmony_ci}
19831cb0ef41Sopenharmony_ci
19841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sub(LiftoffRegister dst, LiftoffRegister lhs,
19851cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
19861cb0ef41Sopenharmony_ci  Fsub(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
19871cb0ef41Sopenharmony_ci}
19881cb0ef41Sopenharmony_ci
19891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_mul(LiftoffRegister dst, LiftoffRegister lhs,
19901cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
19911cb0ef41Sopenharmony_ci  Fmul(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
19921cb0ef41Sopenharmony_ci}
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_div(LiftoffRegister dst, LiftoffRegister lhs,
19951cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
19961cb0ef41Sopenharmony_ci  Fdiv(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
19971cb0ef41Sopenharmony_ci}
19981cb0ef41Sopenharmony_ci
19991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_min(LiftoffRegister dst, LiftoffRegister lhs,
20001cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
20011cb0ef41Sopenharmony_ci  Fmin(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
20021cb0ef41Sopenharmony_ci}
20031cb0ef41Sopenharmony_ci
20041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_max(LiftoffRegister dst, LiftoffRegister lhs,
20051cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
20061cb0ef41Sopenharmony_ci  Fmax(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
20071cb0ef41Sopenharmony_ci}
20081cb0ef41Sopenharmony_ci
20091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_pmin(LiftoffRegister dst, LiftoffRegister lhs,
20101cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
20111cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
20121cb0ef41Sopenharmony_ci
20131cb0ef41Sopenharmony_ci  VRegister tmp = dst.fp();
20141cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
20151cb0ef41Sopenharmony_ci    tmp = temps.AcquireV(kFormat4S);
20161cb0ef41Sopenharmony_ci  }
20171cb0ef41Sopenharmony_ci
20181cb0ef41Sopenharmony_ci  Fcmgt(tmp.V4S(), lhs.fp().V4S(), rhs.fp().V4S());
20191cb0ef41Sopenharmony_ci  Bsl(tmp.V16B(), rhs.fp().V16B(), lhs.fp().V16B());
20201cb0ef41Sopenharmony_ci
20211cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
20221cb0ef41Sopenharmony_ci    Mov(dst.fp().V4S(), tmp);
20231cb0ef41Sopenharmony_ci  }
20241cb0ef41Sopenharmony_ci}
20251cb0ef41Sopenharmony_ci
20261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_pmax(LiftoffRegister dst, LiftoffRegister lhs,
20271cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
20281cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
20291cb0ef41Sopenharmony_ci
20301cb0ef41Sopenharmony_ci  VRegister tmp = dst.fp();
20311cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
20321cb0ef41Sopenharmony_ci    tmp = temps.AcquireV(kFormat4S);
20331cb0ef41Sopenharmony_ci  }
20341cb0ef41Sopenharmony_ci
20351cb0ef41Sopenharmony_ci  Fcmgt(tmp.V4S(), rhs.fp().V4S(), lhs.fp().V4S());
20361cb0ef41Sopenharmony_ci  Bsl(tmp.V16B(), rhs.fp().V16B(), lhs.fp().V16B());
20371cb0ef41Sopenharmony_ci
20381cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
20391cb0ef41Sopenharmony_ci    Mov(dst.fp().V4S(), tmp);
20401cb0ef41Sopenharmony_ci  }
20411cb0ef41Sopenharmony_ci}
20421cb0ef41Sopenharmony_ci
20431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_splat(LiftoffRegister dst,
20441cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
20451cb0ef41Sopenharmony_ci  Dup(dst.fp().V2D(), src.gp().X());
20461cb0ef41Sopenharmony_ci}
20471cb0ef41Sopenharmony_ci
20481cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extract_lane(LiftoffRegister dst,
20491cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
20501cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
20511cb0ef41Sopenharmony_ci  Mov(dst.gp().X(), lhs.fp().V2D(), imm_lane_idx);
20521cb0ef41Sopenharmony_ci}
20531cb0ef41Sopenharmony_ci
20541cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_replace_lane(LiftoffRegister dst,
20551cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
20561cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
20571cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
20581cb0ef41Sopenharmony_ci  if (dst != src1) {
20591cb0ef41Sopenharmony_ci    Mov(dst.fp().V2D(), src1.fp().V2D());
20601cb0ef41Sopenharmony_ci  }
20611cb0ef41Sopenharmony_ci  Mov(dst.fp().V2D(), imm_lane_idx, src2.gp().X());
20621cb0ef41Sopenharmony_ci}
20631cb0ef41Sopenharmony_ci
20641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst,
20651cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
20661cb0ef41Sopenharmony_ci  Neg(dst.fp().V2D(), src.fp().V2D());
20671cb0ef41Sopenharmony_ci}
20681cb0ef41Sopenharmony_ci
20691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_alltrue(LiftoffRegister dst,
20701cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
20711cb0ef41Sopenharmony_ci  I64x2AllTrue(dst.gp(), src.fp());
20721cb0ef41Sopenharmony_ci}
20731cb0ef41Sopenharmony_ci
20741cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shl(LiftoffRegister dst, LiftoffRegister lhs,
20751cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
20761cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kLeft>(
20771cb0ef41Sopenharmony_ci      this, dst.fp().V2D(), lhs.fp().V2D(), rhs.gp(), kFormat2D);
20781cb0ef41Sopenharmony_ci}
20791cb0ef41Sopenharmony_ci
20801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
20811cb0ef41Sopenharmony_ci                                       int32_t rhs) {
20821cb0ef41Sopenharmony_ci  Shl(dst.fp().V2D(), lhs.fp().V2D(), rhs & 63);
20831cb0ef41Sopenharmony_ci}
20841cb0ef41Sopenharmony_ci
20851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
20861cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
20871cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
20881cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
20891cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kSigned>(
20901cb0ef41Sopenharmony_ci      this, dst.fp().V2D(), lhs.fp().V2D(), rhs.gp(), kFormat2D);
20911cb0ef41Sopenharmony_ci}
20921cb0ef41Sopenharmony_ci
20931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
20941cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
20951cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat2D, liftoff::ShiftSign::kSigned>(
20961cb0ef41Sopenharmony_ci      this, dst.fp().V2D(), lhs.fp().V2D(), rhs);
20971cb0ef41Sopenharmony_ci}
20981cb0ef41Sopenharmony_ci
20991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
21001cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
21011cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
21021cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
21031cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kUnsigned>(
21041cb0ef41Sopenharmony_ci      this, dst.fp().V2D(), lhs.fp().V2D(), rhs.gp(), kFormat2D);
21051cb0ef41Sopenharmony_ci}
21061cb0ef41Sopenharmony_ci
21071cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
21081cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
21091cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat2D,
21101cb0ef41Sopenharmony_ci                                       liftoff::ShiftSign::kUnsigned>(
21111cb0ef41Sopenharmony_ci      this, dst.fp().V2D(), lhs.fp().V2D(), rhs);
21121cb0ef41Sopenharmony_ci}
21131cb0ef41Sopenharmony_ci
21141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
21151cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
21161cb0ef41Sopenharmony_ci  Add(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
21171cb0ef41Sopenharmony_ci}
21181cb0ef41Sopenharmony_ci
21191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
21201cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
21211cb0ef41Sopenharmony_ci  Sub(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
21221cb0ef41Sopenharmony_ci}
21231cb0ef41Sopenharmony_ci
21241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
21251cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
21261cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
21271cb0ef41Sopenharmony_ci  VRegister tmp1 = temps.AcquireV(kFormat2D);
21281cb0ef41Sopenharmony_ci  VRegister tmp2 = temps.AcquireV(kFormat2D);
21291cb0ef41Sopenharmony_ci
21301cb0ef41Sopenharmony_ci  // Algorithm copied from code-generator-arm64.cc with minor modifications:
21311cb0ef41Sopenharmony_ci  // - 2 (max number of scratch registers in Liftoff) temporaries instead of 3
21321cb0ef41Sopenharmony_ci  // - 1 more Umull instruction to calculate | cg | ae |,
21331cb0ef41Sopenharmony_ci  // - so, we can no longer use Umlal in the last step, and use Add instead.
21341cb0ef41Sopenharmony_ci  // Refer to comments there for details.
21351cb0ef41Sopenharmony_ci  Xtn(tmp1.V2S(), lhs.fp().V2D());
21361cb0ef41Sopenharmony_ci  Xtn(tmp2.V2S(), rhs.fp().V2D());
21371cb0ef41Sopenharmony_ci  Umull(tmp1.V2D(), tmp1.V2S(), tmp2.V2S());
21381cb0ef41Sopenharmony_ci  Rev64(tmp2.V4S(), rhs.fp().V4S());
21391cb0ef41Sopenharmony_ci  Mul(tmp2.V4S(), tmp2.V4S(), lhs.fp().V4S());
21401cb0ef41Sopenharmony_ci  Addp(tmp2.V4S(), tmp2.V4S(), tmp2.V4S());
21411cb0ef41Sopenharmony_ci  Shll(dst.fp().V2D(), tmp2.V2S(), 32);
21421cb0ef41Sopenharmony_ci  Add(dst.fp().V2D(), dst.fp().V2D(), tmp1.V2D());
21431cb0ef41Sopenharmony_ci}
21441cb0ef41Sopenharmony_ci
21451cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_low_i32x4_s(LiftoffRegister dst,
21461cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
21471cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
21481cb0ef41Sopenharmony_ci  Smull(dst.fp().V2D(), src1.fp().V2S(), src2.fp().V2S());
21491cb0ef41Sopenharmony_ci}
21501cb0ef41Sopenharmony_ci
21511cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_low_i32x4_u(LiftoffRegister dst,
21521cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
21531cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
21541cb0ef41Sopenharmony_ci  Umull(dst.fp().V2D(), src1.fp().V2S(), src2.fp().V2S());
21551cb0ef41Sopenharmony_ci}
21561cb0ef41Sopenharmony_ci
21571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_high_i32x4_s(LiftoffRegister dst,
21581cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
21591cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
21601cb0ef41Sopenharmony_ci  Smull2(dst.fp().V2D(), src1.fp().V4S(), src2.fp().V4S());
21611cb0ef41Sopenharmony_ci}
21621cb0ef41Sopenharmony_ci
21631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_high_i32x4_u(LiftoffRegister dst,
21641cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
21651cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
21661cb0ef41Sopenharmony_ci  Umull2(dst.fp().V2D(), src1.fp().V4S(), src2.fp().V4S());
21671cb0ef41Sopenharmony_ci}
21681cb0ef41Sopenharmony_ci
21691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_bitmask(LiftoffRegister dst,
21701cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
21711cb0ef41Sopenharmony_ci  I64x2BitMask(dst.gp(), src.fp());
21721cb0ef41Sopenharmony_ci}
21731cb0ef41Sopenharmony_ci
21741cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sconvert_i32x4_low(LiftoffRegister dst,
21751cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
21761cb0ef41Sopenharmony_ci  Sxtl(dst.fp().V2D(), src.fp().V2S());
21771cb0ef41Sopenharmony_ci}
21781cb0ef41Sopenharmony_ci
21791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sconvert_i32x4_high(LiftoffRegister dst,
21801cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
21811cb0ef41Sopenharmony_ci  Sxtl2(dst.fp().V2D(), src.fp().V4S());
21821cb0ef41Sopenharmony_ci}
21831cb0ef41Sopenharmony_ci
21841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_uconvert_i32x4_low(LiftoffRegister dst,
21851cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
21861cb0ef41Sopenharmony_ci  Uxtl(dst.fp().V2D(), src.fp().V2S());
21871cb0ef41Sopenharmony_ci}
21881cb0ef41Sopenharmony_ci
21891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_uconvert_i32x4_high(LiftoffRegister dst,
21901cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
21911cb0ef41Sopenharmony_ci  Uxtl2(dst.fp().V2D(), src.fp().V4S());
21921cb0ef41Sopenharmony_ci}
21931cb0ef41Sopenharmony_ci
21941cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_splat(LiftoffRegister dst,
21951cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
21961cb0ef41Sopenharmony_ci  Dup(dst.fp().V4S(), src.gp().W());
21971cb0ef41Sopenharmony_ci}
21981cb0ef41Sopenharmony_ci
21991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extract_lane(LiftoffRegister dst,
22001cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
22011cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
22021cb0ef41Sopenharmony_ci  Mov(dst.gp().W(), lhs.fp().V4S(), imm_lane_idx);
22031cb0ef41Sopenharmony_ci}
22041cb0ef41Sopenharmony_ci
22051cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_replace_lane(LiftoffRegister dst,
22061cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
22071cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
22081cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
22091cb0ef41Sopenharmony_ci  if (dst != src1) {
22101cb0ef41Sopenharmony_ci    Mov(dst.fp().V4S(), src1.fp().V4S());
22111cb0ef41Sopenharmony_ci  }
22121cb0ef41Sopenharmony_ci  Mov(dst.fp().V4S(), imm_lane_idx, src2.gp().W());
22131cb0ef41Sopenharmony_ci}
22141cb0ef41Sopenharmony_ci
22151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst,
22161cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
22171cb0ef41Sopenharmony_ci  Neg(dst.fp().V4S(), src.fp().V4S());
22181cb0ef41Sopenharmony_ci}
22191cb0ef41Sopenharmony_ci
22201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_alltrue(LiftoffRegister dst,
22211cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
22221cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue(this, dst, src, kFormat4S);
22231cb0ef41Sopenharmony_ci}
22241cb0ef41Sopenharmony_ci
22251cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_bitmask(LiftoffRegister dst,
22261cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
22271cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
22281cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireQ();
22291cb0ef41Sopenharmony_ci  VRegister mask = temps.AcquireQ();
22301cb0ef41Sopenharmony_ci
22311cb0ef41Sopenharmony_ci  Sshr(tmp.V4S(), src.fp().V4S(), 31);
22321cb0ef41Sopenharmony_ci  // Set i-th bit of each lane i. When AND with tmp, the lanes that
22331cb0ef41Sopenharmony_ci  // are signed will have i-th bit set, unsigned will be 0.
22341cb0ef41Sopenharmony_ci  Movi(mask.V2D(), 0x0000'0008'0000'0004, 0x0000'0002'0000'0001);
22351cb0ef41Sopenharmony_ci  And(tmp.V16B(), mask.V16B(), tmp.V16B());
22361cb0ef41Sopenharmony_ci  Addv(tmp.S(), tmp.V4S());
22371cb0ef41Sopenharmony_ci  Mov(dst.gp().W(), tmp.V4S(), 0);
22381cb0ef41Sopenharmony_ci}
22391cb0ef41Sopenharmony_ci
22401cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shl(LiftoffRegister dst, LiftoffRegister lhs,
22411cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
22421cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kLeft>(
22431cb0ef41Sopenharmony_ci      this, dst.fp().V4S(), lhs.fp().V4S(), rhs.gp(), kFormat4S);
22441cb0ef41Sopenharmony_ci}
22451cb0ef41Sopenharmony_ci
22461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shli(LiftoffRegister dst, LiftoffRegister lhs,
22471cb0ef41Sopenharmony_ci                                       int32_t rhs) {
22481cb0ef41Sopenharmony_ci  Shl(dst.fp().V4S(), lhs.fp().V4S(), rhs & 31);
22491cb0ef41Sopenharmony_ci}
22501cb0ef41Sopenharmony_ci
22511cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shr_s(LiftoffRegister dst,
22521cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
22531cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
22541cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
22551cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kSigned>(
22561cb0ef41Sopenharmony_ci      this, dst.fp().V4S(), lhs.fp().V4S(), rhs.gp(), kFormat4S);
22571cb0ef41Sopenharmony_ci}
22581cb0ef41Sopenharmony_ci
22591cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shri_s(LiftoffRegister dst,
22601cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
22611cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat4S, liftoff::ShiftSign::kSigned>(
22621cb0ef41Sopenharmony_ci      this, dst.fp().V4S(), lhs.fp().V4S(), rhs);
22631cb0ef41Sopenharmony_ci}
22641cb0ef41Sopenharmony_ci
22651cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shr_u(LiftoffRegister dst,
22661cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
22671cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
22681cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
22691cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kUnsigned>(
22701cb0ef41Sopenharmony_ci      this, dst.fp().V4S(), lhs.fp().V4S(), rhs.gp(), kFormat4S);
22711cb0ef41Sopenharmony_ci}
22721cb0ef41Sopenharmony_ci
22731cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shri_u(LiftoffRegister dst,
22741cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
22751cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat4S,
22761cb0ef41Sopenharmony_ci                                       liftoff::ShiftSign::kUnsigned>(
22771cb0ef41Sopenharmony_ci      this, dst.fp().V4S(), lhs.fp().V4S(), rhs);
22781cb0ef41Sopenharmony_ci}
22791cb0ef41Sopenharmony_ci
22801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
22811cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
22821cb0ef41Sopenharmony_ci  Add(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
22831cb0ef41Sopenharmony_ci}
22841cb0ef41Sopenharmony_ci
22851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sub(LiftoffRegister dst, LiftoffRegister lhs,
22861cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
22871cb0ef41Sopenharmony_ci  Sub(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
22881cb0ef41Sopenharmony_ci}
22891cb0ef41Sopenharmony_ci
22901cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_mul(LiftoffRegister dst, LiftoffRegister lhs,
22911cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
22921cb0ef41Sopenharmony_ci  Mul(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
22931cb0ef41Sopenharmony_ci}
22941cb0ef41Sopenharmony_ci
22951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_min_s(LiftoffRegister dst,
22961cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
22971cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
22981cb0ef41Sopenharmony_ci  Smin(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
22991cb0ef41Sopenharmony_ci}
23001cb0ef41Sopenharmony_ci
23011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_min_u(LiftoffRegister dst,
23021cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
23031cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
23041cb0ef41Sopenharmony_ci  Umin(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
23051cb0ef41Sopenharmony_ci}
23061cb0ef41Sopenharmony_ci
23071cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_max_s(LiftoffRegister dst,
23081cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
23091cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
23101cb0ef41Sopenharmony_ci  Smax(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
23111cb0ef41Sopenharmony_ci}
23121cb0ef41Sopenharmony_ci
23131cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_max_u(LiftoffRegister dst,
23141cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
23151cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
23161cb0ef41Sopenharmony_ci  Umax(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
23171cb0ef41Sopenharmony_ci}
23181cb0ef41Sopenharmony_ci
23191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_dot_i16x8_s(LiftoffRegister dst,
23201cb0ef41Sopenharmony_ci                                              LiftoffRegister lhs,
23211cb0ef41Sopenharmony_ci                                              LiftoffRegister rhs) {
23221cb0ef41Sopenharmony_ci  UseScratchRegisterScope scope(this);
23231cb0ef41Sopenharmony_ci  VRegister tmp1 = scope.AcquireV(kFormat4S);
23241cb0ef41Sopenharmony_ci  VRegister tmp2 = scope.AcquireV(kFormat4S);
23251cb0ef41Sopenharmony_ci  Smull(tmp1, lhs.fp().V4H(), rhs.fp().V4H());
23261cb0ef41Sopenharmony_ci  Smull2(tmp2, lhs.fp().V8H(), rhs.fp().V8H());
23271cb0ef41Sopenharmony_ci  Addp(dst.fp().V4S(), tmp1, tmp2);
23281cb0ef41Sopenharmony_ci}
23291cb0ef41Sopenharmony_ci
23301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extadd_pairwise_i16x8_s(LiftoffRegister dst,
23311cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
23321cb0ef41Sopenharmony_ci  Saddlp(dst.fp().V4S(), src.fp().V8H());
23331cb0ef41Sopenharmony_ci}
23341cb0ef41Sopenharmony_ci
23351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extadd_pairwise_i16x8_u(LiftoffRegister dst,
23361cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
23371cb0ef41Sopenharmony_ci  Uaddlp(dst.fp().V4S(), src.fp().V8H());
23381cb0ef41Sopenharmony_ci}
23391cb0ef41Sopenharmony_ci
23401cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_low_i16x8_s(LiftoffRegister dst,
23411cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
23421cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
23431cb0ef41Sopenharmony_ci  Smull(dst.fp().V4S(), src1.fp().V4H(), src2.fp().V4H());
23441cb0ef41Sopenharmony_ci}
23451cb0ef41Sopenharmony_ci
23461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_low_i16x8_u(LiftoffRegister dst,
23471cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
23481cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
23491cb0ef41Sopenharmony_ci  Umull(dst.fp().V4S(), src1.fp().V4H(), src2.fp().V4H());
23501cb0ef41Sopenharmony_ci}
23511cb0ef41Sopenharmony_ci
23521cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_high_i16x8_s(LiftoffRegister dst,
23531cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
23541cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
23551cb0ef41Sopenharmony_ci  Smull2(dst.fp().V4S(), src1.fp().V8H(), src2.fp().V8H());
23561cb0ef41Sopenharmony_ci}
23571cb0ef41Sopenharmony_ci
23581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_high_i16x8_u(LiftoffRegister dst,
23591cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
23601cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
23611cb0ef41Sopenharmony_ci  Umull2(dst.fp().V4S(), src1.fp().V8H(), src2.fp().V8H());
23621cb0ef41Sopenharmony_ci}
23631cb0ef41Sopenharmony_ci
23641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_splat(LiftoffRegister dst,
23651cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
23661cb0ef41Sopenharmony_ci  Dup(dst.fp().V8H(), src.gp().W());
23671cb0ef41Sopenharmony_ci}
23681cb0ef41Sopenharmony_ci
23691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extract_lane_u(LiftoffRegister dst,
23701cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
23711cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
23721cb0ef41Sopenharmony_ci  Umov(dst.gp().W(), lhs.fp().V8H(), imm_lane_idx);
23731cb0ef41Sopenharmony_ci}
23741cb0ef41Sopenharmony_ci
23751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extract_lane_s(LiftoffRegister dst,
23761cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
23771cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
23781cb0ef41Sopenharmony_ci  Smov(dst.gp().W(), lhs.fp().V8H(), imm_lane_idx);
23791cb0ef41Sopenharmony_ci}
23801cb0ef41Sopenharmony_ci
23811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_replace_lane(LiftoffRegister dst,
23821cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
23831cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
23841cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
23851cb0ef41Sopenharmony_ci  if (dst != src1) {
23861cb0ef41Sopenharmony_ci    Mov(dst.fp().V8H(), src1.fp().V8H());
23871cb0ef41Sopenharmony_ci  }
23881cb0ef41Sopenharmony_ci  Mov(dst.fp().V8H(), imm_lane_idx, src2.gp().W());
23891cb0ef41Sopenharmony_ci}
23901cb0ef41Sopenharmony_ci
23911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_neg(LiftoffRegister dst,
23921cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
23931cb0ef41Sopenharmony_ci  Neg(dst.fp().V8H(), src.fp().V8H());
23941cb0ef41Sopenharmony_ci}
23951cb0ef41Sopenharmony_ci
23961cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_alltrue(LiftoffRegister dst,
23971cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
23981cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue(this, dst, src, kFormat8H);
23991cb0ef41Sopenharmony_ci}
24001cb0ef41Sopenharmony_ci
24011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_bitmask(LiftoffRegister dst,
24021cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
24031cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
24041cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireQ();
24051cb0ef41Sopenharmony_ci  VRegister mask = temps.AcquireQ();
24061cb0ef41Sopenharmony_ci
24071cb0ef41Sopenharmony_ci  Sshr(tmp.V8H(), src.fp().V8H(), 15);
24081cb0ef41Sopenharmony_ci  // Set i-th bit of each lane i. When AND with tmp, the lanes that
24091cb0ef41Sopenharmony_ci  // are signed will have i-th bit set, unsigned will be 0.
24101cb0ef41Sopenharmony_ci  Movi(mask.V2D(), 0x0080'0040'0020'0010, 0x0008'0004'0002'0001);
24111cb0ef41Sopenharmony_ci  And(tmp.V16B(), mask.V16B(), tmp.V16B());
24121cb0ef41Sopenharmony_ci  Addv(tmp.H(), tmp.V8H());
24131cb0ef41Sopenharmony_ci  Mov(dst.gp().W(), tmp.V8H(), 0);
24141cb0ef41Sopenharmony_ci}
24151cb0ef41Sopenharmony_ci
24161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shl(LiftoffRegister dst, LiftoffRegister lhs,
24171cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
24181cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kLeft>(
24191cb0ef41Sopenharmony_ci      this, dst.fp().V8H(), lhs.fp().V8H(), rhs.gp(), kFormat8H);
24201cb0ef41Sopenharmony_ci}
24211cb0ef41Sopenharmony_ci
24221cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shli(LiftoffRegister dst, LiftoffRegister lhs,
24231cb0ef41Sopenharmony_ci                                       int32_t rhs) {
24241cb0ef41Sopenharmony_ci  Shl(dst.fp().V8H(), lhs.fp().V8H(), rhs & 15);
24251cb0ef41Sopenharmony_ci}
24261cb0ef41Sopenharmony_ci
24271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shr_s(LiftoffRegister dst,
24281cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
24291cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
24301cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
24311cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kSigned>(
24321cb0ef41Sopenharmony_ci      this, dst.fp().V8H(), lhs.fp().V8H(), rhs.gp(), kFormat8H);
24331cb0ef41Sopenharmony_ci}
24341cb0ef41Sopenharmony_ci
24351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shri_s(LiftoffRegister dst,
24361cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
24371cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat8H, liftoff::ShiftSign::kSigned>(
24381cb0ef41Sopenharmony_ci      this, dst.fp().V8H(), lhs.fp().V8H(), rhs);
24391cb0ef41Sopenharmony_ci}
24401cb0ef41Sopenharmony_ci
24411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shr_u(LiftoffRegister dst,
24421cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
24431cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
24441cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
24451cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kUnsigned>(
24461cb0ef41Sopenharmony_ci      this, dst.fp().V8H(), lhs.fp().V8H(), rhs.gp(), kFormat8H);
24471cb0ef41Sopenharmony_ci}
24481cb0ef41Sopenharmony_ci
24491cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shri_u(LiftoffRegister dst,
24501cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
24511cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat8H,
24521cb0ef41Sopenharmony_ci                                       liftoff::ShiftSign::kUnsigned>(
24531cb0ef41Sopenharmony_ci      this, dst.fp().V8H(), lhs.fp().V8H(), rhs);
24541cb0ef41Sopenharmony_ci}
24551cb0ef41Sopenharmony_ci
24561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add(LiftoffRegister dst, LiftoffRegister lhs,
24571cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
24581cb0ef41Sopenharmony_ci  Add(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24591cb0ef41Sopenharmony_ci}
24601cb0ef41Sopenharmony_ci
24611cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add_sat_s(LiftoffRegister dst,
24621cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
24631cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
24641cb0ef41Sopenharmony_ci  Sqadd(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24651cb0ef41Sopenharmony_ci}
24661cb0ef41Sopenharmony_ci
24671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub(LiftoffRegister dst, LiftoffRegister lhs,
24681cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
24691cb0ef41Sopenharmony_ci  Sub(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24701cb0ef41Sopenharmony_ci}
24711cb0ef41Sopenharmony_ci
24721cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub_sat_s(LiftoffRegister dst,
24731cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
24741cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
24751cb0ef41Sopenharmony_ci  Sqsub(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24761cb0ef41Sopenharmony_ci}
24771cb0ef41Sopenharmony_ci
24781cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub_sat_u(LiftoffRegister dst,
24791cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
24801cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
24811cb0ef41Sopenharmony_ci  Uqsub(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24821cb0ef41Sopenharmony_ci}
24831cb0ef41Sopenharmony_ci
24841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_mul(LiftoffRegister dst, LiftoffRegister lhs,
24851cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
24861cb0ef41Sopenharmony_ci  Mul(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24871cb0ef41Sopenharmony_ci}
24881cb0ef41Sopenharmony_ci
24891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add_sat_u(LiftoffRegister dst,
24901cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
24911cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
24921cb0ef41Sopenharmony_ci  Uqadd(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24931cb0ef41Sopenharmony_ci}
24941cb0ef41Sopenharmony_ci
24951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_min_s(LiftoffRegister dst,
24961cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
24971cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
24981cb0ef41Sopenharmony_ci  Smin(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
24991cb0ef41Sopenharmony_ci}
25001cb0ef41Sopenharmony_ci
25011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_min_u(LiftoffRegister dst,
25021cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
25031cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
25041cb0ef41Sopenharmony_ci  Umin(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
25051cb0ef41Sopenharmony_ci}
25061cb0ef41Sopenharmony_ci
25071cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_max_s(LiftoffRegister dst,
25081cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
25091cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
25101cb0ef41Sopenharmony_ci  Smax(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
25111cb0ef41Sopenharmony_ci}
25121cb0ef41Sopenharmony_ci
25131cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_max_u(LiftoffRegister dst,
25141cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
25151cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
25161cb0ef41Sopenharmony_ci  Umax(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
25171cb0ef41Sopenharmony_ci}
25181cb0ef41Sopenharmony_ci
25191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shuffle(LiftoffRegister dst,
25201cb0ef41Sopenharmony_ci                                          LiftoffRegister lhs,
25211cb0ef41Sopenharmony_ci                                          LiftoffRegister rhs,
25221cb0ef41Sopenharmony_ci                                          const uint8_t shuffle[16],
25231cb0ef41Sopenharmony_ci                                          bool is_swizzle) {
25241cb0ef41Sopenharmony_ci  VRegister src1 = lhs.fp();
25251cb0ef41Sopenharmony_ci  VRegister src2 = rhs.fp();
25261cb0ef41Sopenharmony_ci  VRegister temp = dst.fp();
25271cb0ef41Sopenharmony_ci  if (dst == lhs || dst == rhs) {
25281cb0ef41Sopenharmony_ci    // dst overlaps with lhs or rhs, so we need a temporary.
25291cb0ef41Sopenharmony_ci    temp = GetUnusedRegister(kFpReg, LiftoffRegList{lhs, rhs}).fp();
25301cb0ef41Sopenharmony_ci  }
25311cb0ef41Sopenharmony_ci
25321cb0ef41Sopenharmony_ci  UseScratchRegisterScope scope(this);
25331cb0ef41Sopenharmony_ci
25341cb0ef41Sopenharmony_ci  if (src1 != src2 && !AreConsecutive(src1, src2)) {
25351cb0ef41Sopenharmony_ci    // Tbl needs consecutive registers, which our scratch registers are.
25361cb0ef41Sopenharmony_ci    src1 = scope.AcquireV(kFormat16B);
25371cb0ef41Sopenharmony_ci    src2 = scope.AcquireV(kFormat16B);
25381cb0ef41Sopenharmony_ci    DCHECK(AreConsecutive(src1, src2));
25391cb0ef41Sopenharmony_ci    Mov(src1.Q(), lhs.fp().Q());
25401cb0ef41Sopenharmony_ci    Mov(src2.Q(), rhs.fp().Q());
25411cb0ef41Sopenharmony_ci  }
25421cb0ef41Sopenharmony_ci
25431cb0ef41Sopenharmony_ci  int64_t imms[2] = {0, 0};
25441cb0ef41Sopenharmony_ci  for (int i = 7; i >= 0; i--) {
25451cb0ef41Sopenharmony_ci    imms[0] = (imms[0] << 8) | (shuffle[i]);
25461cb0ef41Sopenharmony_ci    imms[1] = (imms[1] << 8) | (shuffle[i + 8]);
25471cb0ef41Sopenharmony_ci  }
25481cb0ef41Sopenharmony_ci  DCHECK_EQ(0, (imms[0] | imms[1]) &
25491cb0ef41Sopenharmony_ci                   (lhs == rhs ? 0xF0F0F0F0F0F0F0F0 : 0xE0E0E0E0E0E0E0E0));
25501cb0ef41Sopenharmony_ci
25511cb0ef41Sopenharmony_ci  Movi(temp.V16B(), imms[1], imms[0]);
25521cb0ef41Sopenharmony_ci
25531cb0ef41Sopenharmony_ci  if (src1 == src2) {
25541cb0ef41Sopenharmony_ci    Tbl(dst.fp().V16B(), src1.V16B(), temp.V16B());
25551cb0ef41Sopenharmony_ci  } else {
25561cb0ef41Sopenharmony_ci    Tbl(dst.fp().V16B(), src1.V16B(), src2.V16B(), temp.V16B());
25571cb0ef41Sopenharmony_ci  }
25581cb0ef41Sopenharmony_ci}
25591cb0ef41Sopenharmony_ci
25601cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_popcnt(LiftoffRegister dst,
25611cb0ef41Sopenharmony_ci                                         LiftoffRegister src) {
25621cb0ef41Sopenharmony_ci  Cnt(dst.fp().V16B(), src.fp().V16B());
25631cb0ef41Sopenharmony_ci}
25641cb0ef41Sopenharmony_ci
25651cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_splat(LiftoffRegister dst,
25661cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25671cb0ef41Sopenharmony_ci  Dup(dst.fp().V16B(), src.gp().W());
25681cb0ef41Sopenharmony_ci}
25691cb0ef41Sopenharmony_ci
25701cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_extract_lane_u(LiftoffRegister dst,
25711cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
25721cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
25731cb0ef41Sopenharmony_ci  Umov(dst.gp().W(), lhs.fp().V16B(), imm_lane_idx);
25741cb0ef41Sopenharmony_ci}
25751cb0ef41Sopenharmony_ci
25761cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_extract_lane_s(LiftoffRegister dst,
25771cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
25781cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
25791cb0ef41Sopenharmony_ci  Smov(dst.gp().W(), lhs.fp().V16B(), imm_lane_idx);
25801cb0ef41Sopenharmony_ci}
25811cb0ef41Sopenharmony_ci
25821cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_replace_lane(LiftoffRegister dst,
25831cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
25841cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
25851cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
25861cb0ef41Sopenharmony_ci  if (dst != src1) {
25871cb0ef41Sopenharmony_ci    Mov(dst.fp().V16B(), src1.fp().V16B());
25881cb0ef41Sopenharmony_ci  }
25891cb0ef41Sopenharmony_ci  Mov(dst.fp().V16B(), imm_lane_idx, src2.gp().W());
25901cb0ef41Sopenharmony_ci}
25911cb0ef41Sopenharmony_ci
25921cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_neg(LiftoffRegister dst,
25931cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
25941cb0ef41Sopenharmony_ci  Neg(dst.fp().V16B(), src.fp().V16B());
25951cb0ef41Sopenharmony_ci}
25961cb0ef41Sopenharmony_ci
25971cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_v128_anytrue(LiftoffRegister dst,
25981cb0ef41Sopenharmony_ci                                         LiftoffRegister src) {
25991cb0ef41Sopenharmony_ci  liftoff::EmitAnyTrue(this, dst, src);
26001cb0ef41Sopenharmony_ci}
26011cb0ef41Sopenharmony_ci
26021cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_alltrue(LiftoffRegister dst,
26031cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
26041cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue(this, dst, src, kFormat16B);
26051cb0ef41Sopenharmony_ci}
26061cb0ef41Sopenharmony_ci
26071cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_bitmask(LiftoffRegister dst,
26081cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
26091cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
26101cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireQ();
26111cb0ef41Sopenharmony_ci  VRegister mask = temps.AcquireQ();
26121cb0ef41Sopenharmony_ci
26131cb0ef41Sopenharmony_ci  // Set i-th bit of each lane i. When AND with tmp, the lanes that
26141cb0ef41Sopenharmony_ci  // are signed will have i-th bit set, unsigned will be 0.
26151cb0ef41Sopenharmony_ci  Sshr(tmp.V16B(), src.fp().V16B(), 7);
26161cb0ef41Sopenharmony_ci  Movi(mask.V2D(), 0x8040'2010'0804'0201);
26171cb0ef41Sopenharmony_ci  And(tmp.V16B(), mask.V16B(), tmp.V16B());
26181cb0ef41Sopenharmony_ci  Ext(mask.V16B(), tmp.V16B(), tmp.V16B(), 8);
26191cb0ef41Sopenharmony_ci  Zip1(tmp.V16B(), tmp.V16B(), mask.V16B());
26201cb0ef41Sopenharmony_ci  Addv(tmp.H(), tmp.V8H());
26211cb0ef41Sopenharmony_ci  Mov(dst.gp().W(), tmp.V8H(), 0);
26221cb0ef41Sopenharmony_ci}
26231cb0ef41Sopenharmony_ci
26241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shl(LiftoffRegister dst, LiftoffRegister lhs,
26251cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
26261cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kLeft>(
26271cb0ef41Sopenharmony_ci      this, dst.fp().V16B(), lhs.fp().V16B(), rhs.gp(), kFormat16B);
26281cb0ef41Sopenharmony_ci}
26291cb0ef41Sopenharmony_ci
26301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shli(LiftoffRegister dst, LiftoffRegister lhs,
26311cb0ef41Sopenharmony_ci                                       int32_t rhs) {
26321cb0ef41Sopenharmony_ci  Shl(dst.fp().V16B(), lhs.fp().V16B(), rhs & 7);
26331cb0ef41Sopenharmony_ci}
26341cb0ef41Sopenharmony_ci
26351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shr_s(LiftoffRegister dst,
26361cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
26371cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
26381cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
26391cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kSigned>(
26401cb0ef41Sopenharmony_ci      this, dst.fp().V16B(), lhs.fp().V16B(), rhs.gp(), kFormat16B);
26411cb0ef41Sopenharmony_ci}
26421cb0ef41Sopenharmony_ci
26431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shri_s(LiftoffRegister dst,
26441cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
26451cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat16B, liftoff::ShiftSign::kSigned>(
26461cb0ef41Sopenharmony_ci      this, dst.fp().V16B(), lhs.fp().V16B(), rhs);
26471cb0ef41Sopenharmony_ci}
26481cb0ef41Sopenharmony_ci
26491cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shr_u(LiftoffRegister dst,
26501cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
26511cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
26521cb0ef41Sopenharmony_ci  liftoff::EmitSimdShift<liftoff::ShiftDirection::kRight,
26531cb0ef41Sopenharmony_ci                         liftoff::ShiftSign::kUnsigned>(
26541cb0ef41Sopenharmony_ci      this, dst.fp().V16B(), lhs.fp().V16B(), rhs.gp(), kFormat16B);
26551cb0ef41Sopenharmony_ci}
26561cb0ef41Sopenharmony_ci
26571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shri_u(LiftoffRegister dst,
26581cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
26591cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftRightImmediate<kFormat16B,
26601cb0ef41Sopenharmony_ci                                       liftoff::ShiftSign::kUnsigned>(
26611cb0ef41Sopenharmony_ci      this, dst.fp().V16B(), lhs.fp().V16B(), rhs);
26621cb0ef41Sopenharmony_ci}
26631cb0ef41Sopenharmony_ci
26641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add(LiftoffRegister dst, LiftoffRegister lhs,
26651cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
26661cb0ef41Sopenharmony_ci  Add(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26671cb0ef41Sopenharmony_ci}
26681cb0ef41Sopenharmony_ci
26691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add_sat_s(LiftoffRegister dst,
26701cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
26711cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
26721cb0ef41Sopenharmony_ci  Sqadd(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26731cb0ef41Sopenharmony_ci}
26741cb0ef41Sopenharmony_ci
26751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub(LiftoffRegister dst, LiftoffRegister lhs,
26761cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
26771cb0ef41Sopenharmony_ci  Sub(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26781cb0ef41Sopenharmony_ci}
26791cb0ef41Sopenharmony_ci
26801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub_sat_s(LiftoffRegister dst,
26811cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
26821cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
26831cb0ef41Sopenharmony_ci  Sqsub(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26841cb0ef41Sopenharmony_ci}
26851cb0ef41Sopenharmony_ci
26861cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub_sat_u(LiftoffRegister dst,
26871cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
26881cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
26891cb0ef41Sopenharmony_ci  Uqsub(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26901cb0ef41Sopenharmony_ci}
26911cb0ef41Sopenharmony_ci
26921cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add_sat_u(LiftoffRegister dst,
26931cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
26941cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
26951cb0ef41Sopenharmony_ci  Uqadd(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
26961cb0ef41Sopenharmony_ci}
26971cb0ef41Sopenharmony_ci
26981cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_min_s(LiftoffRegister dst,
26991cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
27001cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
27011cb0ef41Sopenharmony_ci  Smin(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27021cb0ef41Sopenharmony_ci}
27031cb0ef41Sopenharmony_ci
27041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_min_u(LiftoffRegister dst,
27051cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
27061cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
27071cb0ef41Sopenharmony_ci  Umin(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27081cb0ef41Sopenharmony_ci}
27091cb0ef41Sopenharmony_ci
27101cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_max_s(LiftoffRegister dst,
27111cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
27121cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
27131cb0ef41Sopenharmony_ci  Smax(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27141cb0ef41Sopenharmony_ci}
27151cb0ef41Sopenharmony_ci
27161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_max_u(LiftoffRegister dst,
27171cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
27181cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
27191cb0ef41Sopenharmony_ci  Umax(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27201cb0ef41Sopenharmony_ci}
27211cb0ef41Sopenharmony_ci
27221cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_eq(LiftoffRegister dst, LiftoffRegister lhs,
27231cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27241cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27251cb0ef41Sopenharmony_ci}
27261cb0ef41Sopenharmony_ci
27271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ne(LiftoffRegister dst, LiftoffRegister lhs,
27281cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27291cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27301cb0ef41Sopenharmony_ci  Mvn(dst.fp().V16B(), dst.fp().V16B());
27311cb0ef41Sopenharmony_ci}
27321cb0ef41Sopenharmony_ci
27331cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
27341cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27351cb0ef41Sopenharmony_ci  Cmgt(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27361cb0ef41Sopenharmony_ci}
27371cb0ef41Sopenharmony_ci
27381cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
27391cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27401cb0ef41Sopenharmony_ci  Cmhi(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27411cb0ef41Sopenharmony_ci}
27421cb0ef41Sopenharmony_ci
27431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
27441cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27451cb0ef41Sopenharmony_ci  Cmge(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27461cb0ef41Sopenharmony_ci}
27471cb0ef41Sopenharmony_ci
27481cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
27491cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27501cb0ef41Sopenharmony_ci  Cmhs(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
27511cb0ef41Sopenharmony_ci}
27521cb0ef41Sopenharmony_ci
27531cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_eq(LiftoffRegister dst, LiftoffRegister lhs,
27541cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27551cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27561cb0ef41Sopenharmony_ci}
27571cb0ef41Sopenharmony_ci
27581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ne(LiftoffRegister dst, LiftoffRegister lhs,
27591cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27601cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27611cb0ef41Sopenharmony_ci  Mvn(dst.fp().V8H(), dst.fp().V8H());
27621cb0ef41Sopenharmony_ci}
27631cb0ef41Sopenharmony_ci
27641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
27651cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27661cb0ef41Sopenharmony_ci  Cmgt(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27671cb0ef41Sopenharmony_ci}
27681cb0ef41Sopenharmony_ci
27691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
27701cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27711cb0ef41Sopenharmony_ci  Cmhi(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27721cb0ef41Sopenharmony_ci}
27731cb0ef41Sopenharmony_ci
27741cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
27751cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27761cb0ef41Sopenharmony_ci  Cmge(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27771cb0ef41Sopenharmony_ci}
27781cb0ef41Sopenharmony_ci
27791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
27801cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27811cb0ef41Sopenharmony_ci  Cmhs(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
27821cb0ef41Sopenharmony_ci}
27831cb0ef41Sopenharmony_ci
27841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_eq(LiftoffRegister dst, LiftoffRegister lhs,
27851cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27861cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
27871cb0ef41Sopenharmony_ci}
27881cb0ef41Sopenharmony_ci
27891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ne(LiftoffRegister dst, LiftoffRegister lhs,
27901cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27911cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
27921cb0ef41Sopenharmony_ci  Mvn(dst.fp().V4S(), dst.fp().V4S());
27931cb0ef41Sopenharmony_ci}
27941cb0ef41Sopenharmony_ci
27951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
27961cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27971cb0ef41Sopenharmony_ci  Cmgt(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
27981cb0ef41Sopenharmony_ci}
27991cb0ef41Sopenharmony_ci
28001cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
28011cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
28021cb0ef41Sopenharmony_ci  Cmhi(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
28031cb0ef41Sopenharmony_ci}
28041cb0ef41Sopenharmony_ci
28051cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
28061cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
28071cb0ef41Sopenharmony_ci  Cmge(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
28081cb0ef41Sopenharmony_ci}
28091cb0ef41Sopenharmony_ci
28101cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
28111cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
28121cb0ef41Sopenharmony_ci  Cmhs(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
28131cb0ef41Sopenharmony_ci}
28141cb0ef41Sopenharmony_ci
28151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_eq(LiftoffRegister dst, LiftoffRegister lhs,
28161cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28171cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28181cb0ef41Sopenharmony_ci}
28191cb0ef41Sopenharmony_ci
28201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_ne(LiftoffRegister dst, LiftoffRegister lhs,
28211cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28221cb0ef41Sopenharmony_ci  Cmeq(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28231cb0ef41Sopenharmony_ci  Mvn(dst.fp().V2D(), dst.fp().V2D());
28241cb0ef41Sopenharmony_ci}
28251cb0ef41Sopenharmony_ci
28261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
28271cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
28281cb0ef41Sopenharmony_ci  Cmgt(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28291cb0ef41Sopenharmony_ci}
28301cb0ef41Sopenharmony_ci
28311cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
28321cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
28331cb0ef41Sopenharmony_ci  Cmge(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28341cb0ef41Sopenharmony_ci}
28351cb0ef41Sopenharmony_ci
28361cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_eq(LiftoffRegister dst, LiftoffRegister lhs,
28371cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28381cb0ef41Sopenharmony_ci  Fcmeq(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
28391cb0ef41Sopenharmony_ci}
28401cb0ef41Sopenharmony_ci
28411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_ne(LiftoffRegister dst, LiftoffRegister lhs,
28421cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28431cb0ef41Sopenharmony_ci  Fcmeq(dst.fp().V4S(), lhs.fp().V4S(), rhs.fp().V4S());
28441cb0ef41Sopenharmony_ci  Mvn(dst.fp().V4S(), dst.fp().V4S());
28451cb0ef41Sopenharmony_ci}
28461cb0ef41Sopenharmony_ci
28471cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_lt(LiftoffRegister dst, LiftoffRegister lhs,
28481cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28491cb0ef41Sopenharmony_ci  Fcmgt(dst.fp().V4S(), rhs.fp().V4S(), lhs.fp().V4S());
28501cb0ef41Sopenharmony_ci}
28511cb0ef41Sopenharmony_ci
28521cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_le(LiftoffRegister dst, LiftoffRegister lhs,
28531cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28541cb0ef41Sopenharmony_ci  Fcmge(dst.fp().V4S(), rhs.fp().V4S(), lhs.fp().V4S());
28551cb0ef41Sopenharmony_ci}
28561cb0ef41Sopenharmony_ci
28571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_eq(LiftoffRegister dst, LiftoffRegister lhs,
28581cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28591cb0ef41Sopenharmony_ci  Fcmeq(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28601cb0ef41Sopenharmony_ci}
28611cb0ef41Sopenharmony_ci
28621cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_ne(LiftoffRegister dst, LiftoffRegister lhs,
28631cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28641cb0ef41Sopenharmony_ci  Fcmeq(dst.fp().V2D(), lhs.fp().V2D(), rhs.fp().V2D());
28651cb0ef41Sopenharmony_ci  Mvn(dst.fp().V2D(), dst.fp().V2D());
28661cb0ef41Sopenharmony_ci}
28671cb0ef41Sopenharmony_ci
28681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_lt(LiftoffRegister dst, LiftoffRegister lhs,
28691cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28701cb0ef41Sopenharmony_ci  Fcmgt(dst.fp().V2D(), rhs.fp().V2D(), lhs.fp().V2D());
28711cb0ef41Sopenharmony_ci}
28721cb0ef41Sopenharmony_ci
28731cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_le(LiftoffRegister dst, LiftoffRegister lhs,
28741cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28751cb0ef41Sopenharmony_ci  Fcmge(dst.fp().V2D(), rhs.fp().V2D(), lhs.fp().V2D());
28761cb0ef41Sopenharmony_ci}
28771cb0ef41Sopenharmony_ci
28781cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_const(LiftoffRegister dst,
28791cb0ef41Sopenharmony_ci                                       const uint8_t imms[16]) {
28801cb0ef41Sopenharmony_ci  uint64_t vals[2];
28811cb0ef41Sopenharmony_ci  memcpy(vals, imms, sizeof(vals));
28821cb0ef41Sopenharmony_ci  Movi(dst.fp().V16B(), vals[1], vals[0]);
28831cb0ef41Sopenharmony_ci}
28841cb0ef41Sopenharmony_ci
28851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_not(LiftoffRegister dst, LiftoffRegister src) {
28861cb0ef41Sopenharmony_ci  Mvn(dst.fp().V16B(), src.fp().V16B());
28871cb0ef41Sopenharmony_ci}
28881cb0ef41Sopenharmony_ci
28891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_and(LiftoffRegister dst, LiftoffRegister lhs,
28901cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28911cb0ef41Sopenharmony_ci  And(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
28921cb0ef41Sopenharmony_ci}
28931cb0ef41Sopenharmony_ci
28941cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_or(LiftoffRegister dst, LiftoffRegister lhs,
28951cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
28961cb0ef41Sopenharmony_ci  Orr(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
28971cb0ef41Sopenharmony_ci}
28981cb0ef41Sopenharmony_ci
28991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_xor(LiftoffRegister dst, LiftoffRegister lhs,
29001cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
29011cb0ef41Sopenharmony_ci  Eor(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
29021cb0ef41Sopenharmony_ci}
29031cb0ef41Sopenharmony_ci
29041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_select(LiftoffRegister dst,
29051cb0ef41Sopenharmony_ci                                        LiftoffRegister src1,
29061cb0ef41Sopenharmony_ci                                        LiftoffRegister src2,
29071cb0ef41Sopenharmony_ci                                        LiftoffRegister mask) {
29081cb0ef41Sopenharmony_ci  if (dst != mask) {
29091cb0ef41Sopenharmony_ci    Mov(dst.fp().V16B(), mask.fp().V16B());
29101cb0ef41Sopenharmony_ci  }
29111cb0ef41Sopenharmony_ci  Bsl(dst.fp().V16B(), src1.fp().V16B(), src2.fp().V16B());
29121cb0ef41Sopenharmony_ci}
29131cb0ef41Sopenharmony_ci
29141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_f32x4(LiftoffRegister dst,
29151cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
29161cb0ef41Sopenharmony_ci  Fcvtzs(dst.fp().V4S(), src.fp().V4S());
29171cb0ef41Sopenharmony_ci}
29181cb0ef41Sopenharmony_ci
29191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_f32x4(LiftoffRegister dst,
29201cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
29211cb0ef41Sopenharmony_ci  Fcvtzu(dst.fp().V4S(), src.fp().V4S());
29221cb0ef41Sopenharmony_ci}
29231cb0ef41Sopenharmony_ci
29241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sconvert_i32x4(LiftoffRegister dst,
29251cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
29261cb0ef41Sopenharmony_ci  Scvtf(dst.fp().V4S(), src.fp().V4S());
29271cb0ef41Sopenharmony_ci}
29281cb0ef41Sopenharmony_ci
29291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_uconvert_i32x4(LiftoffRegister dst,
29301cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
29311cb0ef41Sopenharmony_ci  Ucvtf(dst.fp().V4S(), src.fp().V4S());
29321cb0ef41Sopenharmony_ci}
29331cb0ef41Sopenharmony_ci
29341cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_demote_f64x2_zero(LiftoffRegister dst,
29351cb0ef41Sopenharmony_ci                                                    LiftoffRegister src) {
29361cb0ef41Sopenharmony_ci  Fcvtn(dst.fp().V2S(), src.fp().V2D());
29371cb0ef41Sopenharmony_ci}
29381cb0ef41Sopenharmony_ci
29391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sconvert_i16x8(LiftoffRegister dst,
29401cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
29411cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
29421cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
29431cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireV(kFormat8H);
29441cb0ef41Sopenharmony_ci  VRegister right = rhs.fp().V8H();
29451cb0ef41Sopenharmony_ci  if (dst == rhs) {
29461cb0ef41Sopenharmony_ci    Mov(tmp, right);
29471cb0ef41Sopenharmony_ci    right = tmp;
29481cb0ef41Sopenharmony_ci  }
29491cb0ef41Sopenharmony_ci  Sqxtn(dst.fp().V8B(), lhs.fp().V8H());
29501cb0ef41Sopenharmony_ci  Sqxtn2(dst.fp().V16B(), right);
29511cb0ef41Sopenharmony_ci}
29521cb0ef41Sopenharmony_ci
29531cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_uconvert_i16x8(LiftoffRegister dst,
29541cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
29551cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
29561cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
29571cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireV(kFormat8H);
29581cb0ef41Sopenharmony_ci  VRegister right = rhs.fp().V8H();
29591cb0ef41Sopenharmony_ci  if (dst == rhs) {
29601cb0ef41Sopenharmony_ci    Mov(tmp, right);
29611cb0ef41Sopenharmony_ci    right = tmp;
29621cb0ef41Sopenharmony_ci  }
29631cb0ef41Sopenharmony_ci  Sqxtun(dst.fp().V8B(), lhs.fp().V8H());
29641cb0ef41Sopenharmony_ci  Sqxtun2(dst.fp().V16B(), right);
29651cb0ef41Sopenharmony_ci}
29661cb0ef41Sopenharmony_ci
29671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i32x4(LiftoffRegister dst,
29681cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
29691cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
29701cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
29711cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireV(kFormat4S);
29721cb0ef41Sopenharmony_ci  VRegister right = rhs.fp().V4S();
29731cb0ef41Sopenharmony_ci  if (dst == rhs) {
29741cb0ef41Sopenharmony_ci    Mov(tmp, right);
29751cb0ef41Sopenharmony_ci    right = tmp;
29761cb0ef41Sopenharmony_ci  }
29771cb0ef41Sopenharmony_ci  Sqxtn(dst.fp().V4H(), lhs.fp().V4S());
29781cb0ef41Sopenharmony_ci  Sqxtn2(dst.fp().V8H(), right);
29791cb0ef41Sopenharmony_ci}
29801cb0ef41Sopenharmony_ci
29811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i32x4(LiftoffRegister dst,
29821cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
29831cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
29841cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
29851cb0ef41Sopenharmony_ci  VRegister tmp = temps.AcquireV(kFormat4S);
29861cb0ef41Sopenharmony_ci  VRegister right = rhs.fp().V4S();
29871cb0ef41Sopenharmony_ci  if (dst == rhs) {
29881cb0ef41Sopenharmony_ci    Mov(tmp, right);
29891cb0ef41Sopenharmony_ci    right = tmp;
29901cb0ef41Sopenharmony_ci  }
29911cb0ef41Sopenharmony_ci  Sqxtun(dst.fp().V4H(), lhs.fp().V4S());
29921cb0ef41Sopenharmony_ci  Sqxtun2(dst.fp().V8H(), right);
29931cb0ef41Sopenharmony_ci}
29941cb0ef41Sopenharmony_ci
29951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i8x16_low(LiftoffRegister dst,
29961cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
29971cb0ef41Sopenharmony_ci  Sxtl(dst.fp().V8H(), src.fp().V8B());
29981cb0ef41Sopenharmony_ci}
29991cb0ef41Sopenharmony_ci
30001cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i8x16_high(LiftoffRegister dst,
30011cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
30021cb0ef41Sopenharmony_ci  Sxtl2(dst.fp().V8H(), src.fp().V16B());
30031cb0ef41Sopenharmony_ci}
30041cb0ef41Sopenharmony_ci
30051cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i8x16_low(LiftoffRegister dst,
30061cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
30071cb0ef41Sopenharmony_ci  Uxtl(dst.fp().V8H(), src.fp().V8B());
30081cb0ef41Sopenharmony_ci}
30091cb0ef41Sopenharmony_ci
30101cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i8x16_high(LiftoffRegister dst,
30111cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
30121cb0ef41Sopenharmony_ci  Uxtl2(dst.fp().V8H(), src.fp().V16B());
30131cb0ef41Sopenharmony_ci}
30141cb0ef41Sopenharmony_ci
30151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_i16x8_low(LiftoffRegister dst,
30161cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
30171cb0ef41Sopenharmony_ci  Sxtl(dst.fp().V4S(), src.fp().V4H());
30181cb0ef41Sopenharmony_ci}
30191cb0ef41Sopenharmony_ci
30201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_i16x8_high(LiftoffRegister dst,
30211cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
30221cb0ef41Sopenharmony_ci  Sxtl2(dst.fp().V4S(), src.fp().V8H());
30231cb0ef41Sopenharmony_ci}
30241cb0ef41Sopenharmony_ci
30251cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_i16x8_low(LiftoffRegister dst,
30261cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
30271cb0ef41Sopenharmony_ci  Uxtl(dst.fp().V4S(), src.fp().V4H());
30281cb0ef41Sopenharmony_ci}
30291cb0ef41Sopenharmony_ci
30301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_i16x8_high(LiftoffRegister dst,
30311cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
30321cb0ef41Sopenharmony_ci  Uxtl2(dst.fp().V4S(), src.fp().V8H());
30331cb0ef41Sopenharmony_ci}
30341cb0ef41Sopenharmony_ci
30351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_trunc_sat_f64x2_s_zero(LiftoffRegister dst,
30361cb0ef41Sopenharmony_ci                                                         LiftoffRegister src) {
30371cb0ef41Sopenharmony_ci  Fcvtzs(dst.fp().V2D(), src.fp().V2D());
30381cb0ef41Sopenharmony_ci  Sqxtn(dst.fp().V2S(), dst.fp().V2D());
30391cb0ef41Sopenharmony_ci}
30401cb0ef41Sopenharmony_ci
30411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_trunc_sat_f64x2_u_zero(LiftoffRegister dst,
30421cb0ef41Sopenharmony_ci                                                         LiftoffRegister src) {
30431cb0ef41Sopenharmony_ci  Fcvtzu(dst.fp().V2D(), src.fp().V2D());
30441cb0ef41Sopenharmony_ci  Uqxtn(dst.fp().V2S(), dst.fp().V2D());
30451cb0ef41Sopenharmony_ci}
30461cb0ef41Sopenharmony_ci
30471cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_and_not(LiftoffRegister dst,
30481cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs,
30491cb0ef41Sopenharmony_ci                                         LiftoffRegister rhs) {
30501cb0ef41Sopenharmony_ci  Bic(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
30511cb0ef41Sopenharmony_ci}
30521cb0ef41Sopenharmony_ci
30531cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_rounding_average_u(LiftoffRegister dst,
30541cb0ef41Sopenharmony_ci                                                     LiftoffRegister lhs,
30551cb0ef41Sopenharmony_ci                                                     LiftoffRegister rhs) {
30561cb0ef41Sopenharmony_ci  Urhadd(dst.fp().V16B(), lhs.fp().V16B(), rhs.fp().V16B());
30571cb0ef41Sopenharmony_ci}
30581cb0ef41Sopenharmony_ci
30591cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_rounding_average_u(LiftoffRegister dst,
30601cb0ef41Sopenharmony_ci                                                     LiftoffRegister lhs,
30611cb0ef41Sopenharmony_ci                                                     LiftoffRegister rhs) {
30621cb0ef41Sopenharmony_ci  Urhadd(dst.fp().V8H(), lhs.fp().V8H(), rhs.fp().V8H());
30631cb0ef41Sopenharmony_ci}
30641cb0ef41Sopenharmony_ci
30651cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_abs(LiftoffRegister dst,
30661cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
30671cb0ef41Sopenharmony_ci  Abs(dst.fp().V16B(), src.fp().V16B());
30681cb0ef41Sopenharmony_ci}
30691cb0ef41Sopenharmony_ci
30701cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_abs(LiftoffRegister dst,
30711cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
30721cb0ef41Sopenharmony_ci  Abs(dst.fp().V8H(), src.fp().V8H());
30731cb0ef41Sopenharmony_ci}
30741cb0ef41Sopenharmony_ci
30751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_s(LiftoffRegister dst,
30761cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
30771cb0ef41Sopenharmony_ci  Saddlp(dst.fp().V8H(), src.fp().V16B());
30781cb0ef41Sopenharmony_ci}
30791cb0ef41Sopenharmony_ci
30801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_u(LiftoffRegister dst,
30811cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
30821cb0ef41Sopenharmony_ci  Uaddlp(dst.fp().V8H(), src.fp().V16B());
30831cb0ef41Sopenharmony_ci}
30841cb0ef41Sopenharmony_ci
30851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_low_i8x16_s(LiftoffRegister dst,
30861cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
30871cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
30881cb0ef41Sopenharmony_ci  Smull(dst.fp().V8H(), src1.fp().V8B(), src2.fp().V8B());
30891cb0ef41Sopenharmony_ci}
30901cb0ef41Sopenharmony_ci
30911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_low_i8x16_u(LiftoffRegister dst,
30921cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
30931cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
30941cb0ef41Sopenharmony_ci  Umull(dst.fp().V8H(), src1.fp().V8B(), src2.fp().V8B());
30951cb0ef41Sopenharmony_ci}
30961cb0ef41Sopenharmony_ci
30971cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_high_i8x16_s(LiftoffRegister dst,
30981cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
30991cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
31001cb0ef41Sopenharmony_ci  Smull2(dst.fp().V8H(), src1.fp().V16B(), src2.fp().V16B());
31011cb0ef41Sopenharmony_ci}
31021cb0ef41Sopenharmony_ci
31031cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_high_i8x16_u(LiftoffRegister dst,
31041cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
31051cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
31061cb0ef41Sopenharmony_ci  Umull2(dst.fp().V8H(), src1.fp().V16B(), src2.fp().V16B());
31071cb0ef41Sopenharmony_ci}
31081cb0ef41Sopenharmony_ci
31091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_q15mulr_sat_s(LiftoffRegister dst,
31101cb0ef41Sopenharmony_ci                                                LiftoffRegister src1,
31111cb0ef41Sopenharmony_ci                                                LiftoffRegister src2) {
31121cb0ef41Sopenharmony_ci  Sqrdmulh(dst.fp().V8H(), src1.fp().V8H(), src2.fp().V8H());
31131cb0ef41Sopenharmony_ci}
31141cb0ef41Sopenharmony_ci
31151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_abs(LiftoffRegister dst,
31161cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
31171cb0ef41Sopenharmony_ci  Abs(dst.fp().V4S(), src.fp().V4S());
31181cb0ef41Sopenharmony_ci}
31191cb0ef41Sopenharmony_ci
31201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_abs(LiftoffRegister dst,
31211cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
31221cb0ef41Sopenharmony_ci  Abs(dst.fp().V2D(), src.fp().V2D());
31231cb0ef41Sopenharmony_ci}
31241cb0ef41Sopenharmony_ci
31251cb0ef41Sopenharmony_civoid LiftoffAssembler::StackCheck(Label* ool_code, Register limit_address) {
31261cb0ef41Sopenharmony_ci  Ldr(limit_address, MemOperand(limit_address));
31271cb0ef41Sopenharmony_ci  Cmp(sp, limit_address);
31281cb0ef41Sopenharmony_ci  B(ool_code, ls);
31291cb0ef41Sopenharmony_ci}
31301cb0ef41Sopenharmony_ci
31311cb0ef41Sopenharmony_civoid LiftoffAssembler::CallTrapCallbackForTesting() {
31321cb0ef41Sopenharmony_ci  CallCFunction(ExternalReference::wasm_call_trap_callback_for_testing(), 0);
31331cb0ef41Sopenharmony_ci}
31341cb0ef41Sopenharmony_ci
31351cb0ef41Sopenharmony_civoid LiftoffAssembler::AssertUnreachable(AbortReason reason) {
31361cb0ef41Sopenharmony_ci  TurboAssembler::AssertUnreachable(reason);
31371cb0ef41Sopenharmony_ci}
31381cb0ef41Sopenharmony_ci
31391cb0ef41Sopenharmony_civoid LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
31401cb0ef41Sopenharmony_ci  PushCPURegList(liftoff::PadRegList(regs.GetGpList()));
31411cb0ef41Sopenharmony_ci  PushCPURegList(liftoff::PadVRegList(regs.GetFpList()));
31421cb0ef41Sopenharmony_ci}
31431cb0ef41Sopenharmony_ci
31441cb0ef41Sopenharmony_civoid LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
31451cb0ef41Sopenharmony_ci  PopCPURegList(liftoff::PadVRegList(regs.GetFpList()));
31461cb0ef41Sopenharmony_ci  PopCPURegList(liftoff::PadRegList(regs.GetGpList()));
31471cb0ef41Sopenharmony_ci}
31481cb0ef41Sopenharmony_ci
31491cb0ef41Sopenharmony_civoid LiftoffAssembler::RecordSpillsInSafepoint(
31501cb0ef41Sopenharmony_ci    SafepointTableBuilder::Safepoint& safepoint, LiftoffRegList all_spills,
31511cb0ef41Sopenharmony_ci    LiftoffRegList ref_spills, int spill_offset) {
31521cb0ef41Sopenharmony_ci  int spill_space_size = 0;
31531cb0ef41Sopenharmony_ci  bool needs_padding = (all_spills.GetGpList().Count() & 1) != 0;
31541cb0ef41Sopenharmony_ci  if (needs_padding) {
31551cb0ef41Sopenharmony_ci    spill_space_size += kSystemPointerSize;
31561cb0ef41Sopenharmony_ci    ++spill_offset;
31571cb0ef41Sopenharmony_ci  }
31581cb0ef41Sopenharmony_ci  while (!all_spills.is_empty()) {
31591cb0ef41Sopenharmony_ci    LiftoffRegister reg = all_spills.GetLastRegSet();
31601cb0ef41Sopenharmony_ci    if (ref_spills.has(reg)) {
31611cb0ef41Sopenharmony_ci      safepoint.DefineTaggedStackSlot(spill_offset);
31621cb0ef41Sopenharmony_ci    }
31631cb0ef41Sopenharmony_ci    all_spills.clear(reg);
31641cb0ef41Sopenharmony_ci    ++spill_offset;
31651cb0ef41Sopenharmony_ci    spill_space_size += kSystemPointerSize;
31661cb0ef41Sopenharmony_ci  }
31671cb0ef41Sopenharmony_ci  // Record the number of additional spill slots.
31681cb0ef41Sopenharmony_ci  RecordOolSpillSpaceSize(spill_space_size);
31691cb0ef41Sopenharmony_ci}
31701cb0ef41Sopenharmony_ci
31711cb0ef41Sopenharmony_civoid LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
31721cb0ef41Sopenharmony_ci  DropSlots(num_stack_slots);
31731cb0ef41Sopenharmony_ci  Ret();
31741cb0ef41Sopenharmony_ci}
31751cb0ef41Sopenharmony_ci
31761cb0ef41Sopenharmony_civoid LiftoffAssembler::CallC(const ValueKindSig* sig,
31771cb0ef41Sopenharmony_ci                             const LiftoffRegister* args,
31781cb0ef41Sopenharmony_ci                             const LiftoffRegister* rets,
31791cb0ef41Sopenharmony_ci                             ValueKind out_argument_kind, int stack_bytes,
31801cb0ef41Sopenharmony_ci                             ExternalReference ext_ref) {
31811cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
31821cb0ef41Sopenharmony_ci  int total_size = RoundUp(stack_bytes, kQuadWordSizeInBytes);
31831cb0ef41Sopenharmony_ci  // Reserve space in the stack.
31841cb0ef41Sopenharmony_ci  Claim(total_size, 1);
31851cb0ef41Sopenharmony_ci
31861cb0ef41Sopenharmony_ci  int arg_bytes = 0;
31871cb0ef41Sopenharmony_ci  for (ValueKind param_kind : sig->parameters()) {
31881cb0ef41Sopenharmony_ci    Poke(liftoff::GetRegFromType(*args++, param_kind), arg_bytes);
31891cb0ef41Sopenharmony_ci    arg_bytes += value_kind_size(param_kind);
31901cb0ef41Sopenharmony_ci  }
31911cb0ef41Sopenharmony_ci  DCHECK_LE(arg_bytes, stack_bytes);
31921cb0ef41Sopenharmony_ci
31931cb0ef41Sopenharmony_ci  // Pass a pointer to the buffer with the arguments to the C function.
31941cb0ef41Sopenharmony_ci  Mov(x0, sp);
31951cb0ef41Sopenharmony_ci
31961cb0ef41Sopenharmony_ci  // Now call the C function.
31971cb0ef41Sopenharmony_ci  constexpr int kNumCCallArgs = 1;
31981cb0ef41Sopenharmony_ci  CallCFunction(ext_ref, kNumCCallArgs);
31991cb0ef41Sopenharmony_ci
32001cb0ef41Sopenharmony_ci  // Move return value to the right register.
32011cb0ef41Sopenharmony_ci  const LiftoffRegister* next_result_reg = rets;
32021cb0ef41Sopenharmony_ci  if (sig->return_count() > 0) {
32031cb0ef41Sopenharmony_ci    DCHECK_EQ(1, sig->return_count());
32041cb0ef41Sopenharmony_ci    constexpr Register kReturnReg = x0;
32051cb0ef41Sopenharmony_ci    if (kReturnReg != next_result_reg->gp()) {
32061cb0ef41Sopenharmony_ci      Move(*next_result_reg, LiftoffRegister(kReturnReg), sig->GetReturn(0));
32071cb0ef41Sopenharmony_ci    }
32081cb0ef41Sopenharmony_ci    ++next_result_reg;
32091cb0ef41Sopenharmony_ci  }
32101cb0ef41Sopenharmony_ci
32111cb0ef41Sopenharmony_ci  // Load potential output value from the buffer on the stack.
32121cb0ef41Sopenharmony_ci  if (out_argument_kind != kVoid) {
32131cb0ef41Sopenharmony_ci    Peek(liftoff::GetRegFromType(*next_result_reg, out_argument_kind), 0);
32141cb0ef41Sopenharmony_ci  }
32151cb0ef41Sopenharmony_ci
32161cb0ef41Sopenharmony_ci  Drop(total_size, 1);
32171cb0ef41Sopenharmony_ci}
32181cb0ef41Sopenharmony_ci
32191cb0ef41Sopenharmony_civoid LiftoffAssembler::CallNativeWasmCode(Address addr) {
32201cb0ef41Sopenharmony_ci  Call(addr, RelocInfo::WASM_CALL);
32211cb0ef41Sopenharmony_ci}
32221cb0ef41Sopenharmony_ci
32231cb0ef41Sopenharmony_civoid LiftoffAssembler::TailCallNativeWasmCode(Address addr) {
32241cb0ef41Sopenharmony_ci  Jump(addr, RelocInfo::WASM_CALL);
32251cb0ef41Sopenharmony_ci}
32261cb0ef41Sopenharmony_ci
32271cb0ef41Sopenharmony_civoid LiftoffAssembler::CallIndirect(const ValueKindSig* sig,
32281cb0ef41Sopenharmony_ci                                    compiler::CallDescriptor* call_descriptor,
32291cb0ef41Sopenharmony_ci                                    Register target) {
32301cb0ef41Sopenharmony_ci  // For Arm64, we have more cache registers than wasm parameters. That means
32311cb0ef41Sopenharmony_ci  // that target will always be in a register.
32321cb0ef41Sopenharmony_ci  DCHECK(target.is_valid());
32331cb0ef41Sopenharmony_ci  Call(target);
32341cb0ef41Sopenharmony_ci}
32351cb0ef41Sopenharmony_ci
32361cb0ef41Sopenharmony_civoid LiftoffAssembler::TailCallIndirect(Register target) {
32371cb0ef41Sopenharmony_ci  DCHECK(target.is_valid());
32381cb0ef41Sopenharmony_ci  // When control flow integrity is enabled, the target is a "bti c"
32391cb0ef41Sopenharmony_ci  // instruction, which enforces that the jump instruction is either a "blr", or
32401cb0ef41Sopenharmony_ci  // a "br" with x16 or x17 as its destination.
32411cb0ef41Sopenharmony_ci  UseScratchRegisterScope temps(this);
32421cb0ef41Sopenharmony_ci  temps.Exclude(x17);
32431cb0ef41Sopenharmony_ci  Mov(x17, target);
32441cb0ef41Sopenharmony_ci  Jump(x17);
32451cb0ef41Sopenharmony_ci}
32461cb0ef41Sopenharmony_ci
32471cb0ef41Sopenharmony_civoid LiftoffAssembler::CallRuntimeStub(WasmCode::RuntimeStubId sid) {
32481cb0ef41Sopenharmony_ci  // A direct call to a wasm runtime stub defined in this module.
32491cb0ef41Sopenharmony_ci  // Just encode the stub index. This will be patched at relocation.
32501cb0ef41Sopenharmony_ci  Call(static_cast<Address>(sid), RelocInfo::WASM_STUB_CALL);
32511cb0ef41Sopenharmony_ci}
32521cb0ef41Sopenharmony_ci
32531cb0ef41Sopenharmony_civoid LiftoffAssembler::AllocateStackSlot(Register addr, uint32_t size) {
32541cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
32551cb0ef41Sopenharmony_ci  size = RoundUp(size, kQuadWordSizeInBytes);
32561cb0ef41Sopenharmony_ci  Claim(size, 1);
32571cb0ef41Sopenharmony_ci  Mov(addr, sp);
32581cb0ef41Sopenharmony_ci}
32591cb0ef41Sopenharmony_ci
32601cb0ef41Sopenharmony_civoid LiftoffAssembler::DeallocateStackSlot(uint32_t size) {
32611cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
32621cb0ef41Sopenharmony_ci  size = RoundUp(size, kQuadWordSizeInBytes);
32631cb0ef41Sopenharmony_ci  Drop(size, 1);
32641cb0ef41Sopenharmony_ci}
32651cb0ef41Sopenharmony_ci
32661cb0ef41Sopenharmony_civoid LiftoffAssembler::MaybeOSR() {}
32671cb0ef41Sopenharmony_ci
32681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_set_if_nan(Register dst, DoubleRegister src,
32691cb0ef41Sopenharmony_ci                                       ValueKind kind) {
32701cb0ef41Sopenharmony_ci  Label not_nan;
32711cb0ef41Sopenharmony_ci  if (kind == kF32) {
32721cb0ef41Sopenharmony_ci    Fcmp(src.S(), src.S());
32731cb0ef41Sopenharmony_ci    B(eq, &not_nan);  // x != x iff isnan(x)
32741cb0ef41Sopenharmony_ci    // If it's a NaN, it must be non-zero, so store that as the set value.
32751cb0ef41Sopenharmony_ci    Str(src.S(), MemOperand(dst));
32761cb0ef41Sopenharmony_ci  } else {
32771cb0ef41Sopenharmony_ci    DCHECK_EQ(kind, kF64);
32781cb0ef41Sopenharmony_ci    Fcmp(src.D(), src.D());
32791cb0ef41Sopenharmony_ci    B(eq, &not_nan);  // x != x iff isnan(x)
32801cb0ef41Sopenharmony_ci    // Double-precision NaNs must be non-zero in the most-significant 32
32811cb0ef41Sopenharmony_ci    // bits, so store that.
32821cb0ef41Sopenharmony_ci    St1(src.V4S(), 1, MemOperand(dst));
32831cb0ef41Sopenharmony_ci  }
32841cb0ef41Sopenharmony_ci  Bind(&not_nan);
32851cb0ef41Sopenharmony_ci}
32861cb0ef41Sopenharmony_ci
32871cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_set_if_nan(Register dst, LiftoffRegister src,
32881cb0ef41Sopenharmony_ci                                            Register tmp_gp,
32891cb0ef41Sopenharmony_ci                                            LiftoffRegister tmp_s128,
32901cb0ef41Sopenharmony_ci                                            ValueKind lane_kind) {
32911cb0ef41Sopenharmony_ci  DoubleRegister tmp_fp = tmp_s128.fp();
32921cb0ef41Sopenharmony_ci  if (lane_kind == kF32) {
32931cb0ef41Sopenharmony_ci    Fmaxv(tmp_fp.S(), src.fp().V4S());
32941cb0ef41Sopenharmony_ci  } else {
32951cb0ef41Sopenharmony_ci    DCHECK_EQ(lane_kind, kF64);
32961cb0ef41Sopenharmony_ci    Fmaxp(tmp_fp.D(), src.fp().V2D());
32971cb0ef41Sopenharmony_ci  }
32981cb0ef41Sopenharmony_ci  emit_set_if_nan(dst, tmp_fp, lane_kind);
32991cb0ef41Sopenharmony_ci}
33001cb0ef41Sopenharmony_ci
33011cb0ef41Sopenharmony_civoid LiftoffStackSlots::Construct(int param_slots) {
33021cb0ef41Sopenharmony_ci  DCHECK_LT(0, slots_.size());
33031cb0ef41Sopenharmony_ci  // The stack pointer is required to be quadword aligned.
33041cb0ef41Sopenharmony_ci  asm_->Claim(RoundUp(param_slots, 2));
33051cb0ef41Sopenharmony_ci  for (auto& slot : slots_) {
33061cb0ef41Sopenharmony_ci    int poke_offset = slot.dst_slot_ * kSystemPointerSize;
33071cb0ef41Sopenharmony_ci    switch (slot.src_.loc()) {
33081cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kStack: {
33091cb0ef41Sopenharmony_ci        UseScratchRegisterScope temps(asm_);
33101cb0ef41Sopenharmony_ci        CPURegister scratch = liftoff::AcquireByType(&temps, slot.src_.kind());
33111cb0ef41Sopenharmony_ci        asm_->Ldr(scratch, liftoff::GetStackSlot(slot.src_offset_));
33121cb0ef41Sopenharmony_ci        asm_->Poke(scratch, poke_offset);
33131cb0ef41Sopenharmony_ci        break;
33141cb0ef41Sopenharmony_ci      }
33151cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kRegister:
33161cb0ef41Sopenharmony_ci        asm_->Poke(liftoff::GetRegFromType(slot.src_.reg(), slot.src_.kind()),
33171cb0ef41Sopenharmony_ci                   poke_offset);
33181cb0ef41Sopenharmony_ci        break;
33191cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kIntConst:
33201cb0ef41Sopenharmony_ci        DCHECK(slot.src_.kind() == kI32 || slot.src_.kind() == kI64);
33211cb0ef41Sopenharmony_ci        if (slot.src_.i32_const() == 0) {
33221cb0ef41Sopenharmony_ci          Register zero_reg = slot.src_.kind() == kI32 ? wzr : xzr;
33231cb0ef41Sopenharmony_ci          asm_->Poke(zero_reg, poke_offset);
33241cb0ef41Sopenharmony_ci        } else {
33251cb0ef41Sopenharmony_ci          UseScratchRegisterScope temps(asm_);
33261cb0ef41Sopenharmony_ci          Register scratch =
33271cb0ef41Sopenharmony_ci              slot.src_.kind() == kI32 ? temps.AcquireW() : temps.AcquireX();
33281cb0ef41Sopenharmony_ci          asm_->Mov(scratch, int64_t{slot.src_.i32_const()});
33291cb0ef41Sopenharmony_ci          asm_->Poke(scratch, poke_offset);
33301cb0ef41Sopenharmony_ci        }
33311cb0ef41Sopenharmony_ci        break;
33321cb0ef41Sopenharmony_ci    }
33331cb0ef41Sopenharmony_ci  }
33341cb0ef41Sopenharmony_ci}
33351cb0ef41Sopenharmony_ci
33361cb0ef41Sopenharmony_ci}  // namespace wasm
33371cb0ef41Sopenharmony_ci}  // namespace internal
33381cb0ef41Sopenharmony_ci}  // namespace v8
33391cb0ef41Sopenharmony_ci
33401cb0ef41Sopenharmony_ci#endif  // V8_WASM_BASELINE_ARM64_LIFTOFF_ASSEMBLER_ARM64_H_
3341