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_X64_LIFTOFF_ASSEMBLER_X64_H_
61cb0ef41Sopenharmony_ci#define V8_WASM_BASELINE_X64_LIFTOFF_ASSEMBLER_X64_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/cpu-features.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/x64/register-x64.h"
131cb0ef41Sopenharmony_ci#include "src/heap/memory-chunk.h"
141cb0ef41Sopenharmony_ci#include "src/wasm/baseline/liftoff-assembler.h"
151cb0ef41Sopenharmony_ci#include "src/wasm/simd-shuffle.h"
161cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects.h"
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cinamespace v8 {
191cb0ef41Sopenharmony_cinamespace internal {
201cb0ef41Sopenharmony_cinamespace wasm {
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#define RETURN_FALSE_IF_MISSING_CPU_FEATURE(name)    \
231cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(name)) return false; \
241cb0ef41Sopenharmony_ci  CpuFeatureScope feature(this, name);
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace liftoff {
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciinline constexpr Condition ToCondition(LiftoffCondition liftoff_cond) {
291cb0ef41Sopenharmony_ci  switch (liftoff_cond) {
301cb0ef41Sopenharmony_ci    case kEqual:
311cb0ef41Sopenharmony_ci      return equal;
321cb0ef41Sopenharmony_ci    case kUnequal:
331cb0ef41Sopenharmony_ci      return not_equal;
341cb0ef41Sopenharmony_ci    case kSignedLessThan:
351cb0ef41Sopenharmony_ci      return less;
361cb0ef41Sopenharmony_ci    case kSignedLessEqual:
371cb0ef41Sopenharmony_ci      return less_equal;
381cb0ef41Sopenharmony_ci    case kSignedGreaterThan:
391cb0ef41Sopenharmony_ci      return greater;
401cb0ef41Sopenharmony_ci    case kSignedGreaterEqual:
411cb0ef41Sopenharmony_ci      return greater_equal;
421cb0ef41Sopenharmony_ci    case kUnsignedLessThan:
431cb0ef41Sopenharmony_ci      return below;
441cb0ef41Sopenharmony_ci    case kUnsignedLessEqual:
451cb0ef41Sopenharmony_ci      return below_equal;
461cb0ef41Sopenharmony_ci    case kUnsignedGreaterThan:
471cb0ef41Sopenharmony_ci      return above;
481cb0ef41Sopenharmony_ci    case kUnsignedGreaterEqual:
491cb0ef41Sopenharmony_ci      return above_equal;
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciconstexpr Register kScratchRegister2 = r11;
541cb0ef41Sopenharmony_cistatic_assert(kScratchRegister != kScratchRegister2, "collision");
551cb0ef41Sopenharmony_cistatic_assert((kLiftoffAssemblerGpCacheRegs &
561cb0ef41Sopenharmony_ci               RegList{kScratchRegister, kScratchRegister2})
571cb0ef41Sopenharmony_ci                  .is_empty(),
581cb0ef41Sopenharmony_ci              "scratch registers must not be used as cache registers");
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciconstexpr DoubleRegister kScratchDoubleReg2 = xmm14;
611cb0ef41Sopenharmony_cistatic_assert(kScratchDoubleReg != kScratchDoubleReg2, "collision");
621cb0ef41Sopenharmony_cistatic_assert((kLiftoffAssemblerFpCacheRegs &
631cb0ef41Sopenharmony_ci               DoubleRegList{kScratchDoubleReg, kScratchDoubleReg2})
641cb0ef41Sopenharmony_ci                  .is_empty(),
651cb0ef41Sopenharmony_ci              "scratch registers must not be used as cache registers");
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// rbp-8 holds the stack marker, rbp-16 is the instance parameter.
681cb0ef41Sopenharmony_ciconstexpr int kInstanceOffset = 16;
691cb0ef41Sopenharmony_ciconstexpr int kFeedbackVectorOffset = 24;  // rbp-24 is the feedback vector.
701cb0ef41Sopenharmony_ciconstexpr int kTierupBudgetOffset = 32;    // rbp-32 is the feedback vector.
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciinline Operand GetStackSlot(int offset) { return Operand(rbp, -offset); }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci// TODO(clemensb): Make this a constexpr variable once Operand is constexpr.
751cb0ef41Sopenharmony_ciinline Operand GetInstanceOperand() { return GetStackSlot(kInstanceOffset); }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciinline Operand GetOSRTargetSlot() { return GetStackSlot(kOSRTargetOffset); }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciinline Operand GetMemOp(LiftoffAssembler* assm, Register addr, Register offset,
801cb0ef41Sopenharmony_ci                        uintptr_t offset_imm) {
811cb0ef41Sopenharmony_ci  if (is_uint31(offset_imm)) {
821cb0ef41Sopenharmony_ci    int32_t offset_imm32 = static_cast<int32_t>(offset_imm);
831cb0ef41Sopenharmony_ci    return offset == no_reg ? Operand(addr, offset_imm32)
841cb0ef41Sopenharmony_ci                            : Operand(addr, offset, times_1, offset_imm32);
851cb0ef41Sopenharmony_ci  }
861cb0ef41Sopenharmony_ci  // Offset immediate does not fit in 31 bits.
871cb0ef41Sopenharmony_ci  Register scratch = kScratchRegister;
881cb0ef41Sopenharmony_ci  assm->TurboAssembler::Move(scratch, offset_imm);
891cb0ef41Sopenharmony_ci  if (offset != no_reg) assm->addq(scratch, offset);
901cb0ef41Sopenharmony_ci  return Operand(addr, scratch, times_1, 0);
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciinline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
941cb0ef41Sopenharmony_ci                 ValueKind kind) {
951cb0ef41Sopenharmony_ci  switch (kind) {
961cb0ef41Sopenharmony_ci    case kI32:
971cb0ef41Sopenharmony_ci      assm->movl(dst.gp(), src);
981cb0ef41Sopenharmony_ci      break;
991cb0ef41Sopenharmony_ci    case kI64:
1001cb0ef41Sopenharmony_ci    case kOptRef:
1011cb0ef41Sopenharmony_ci    case kRef:
1021cb0ef41Sopenharmony_ci    case kRtt:
1031cb0ef41Sopenharmony_ci      assm->movq(dst.gp(), src);
1041cb0ef41Sopenharmony_ci      break;
1051cb0ef41Sopenharmony_ci    case kF32:
1061cb0ef41Sopenharmony_ci      assm->Movss(dst.fp(), src);
1071cb0ef41Sopenharmony_ci      break;
1081cb0ef41Sopenharmony_ci    case kF64:
1091cb0ef41Sopenharmony_ci      assm->Movsd(dst.fp(), src);
1101cb0ef41Sopenharmony_ci      break;
1111cb0ef41Sopenharmony_ci    case kS128:
1121cb0ef41Sopenharmony_ci      assm->Movdqu(dst.fp(), src);
1131cb0ef41Sopenharmony_ci      break;
1141cb0ef41Sopenharmony_ci    default:
1151cb0ef41Sopenharmony_ci      UNREACHABLE();
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ciinline void Store(LiftoffAssembler* assm, Operand dst, LiftoffRegister src,
1201cb0ef41Sopenharmony_ci                  ValueKind kind) {
1211cb0ef41Sopenharmony_ci  switch (kind) {
1221cb0ef41Sopenharmony_ci    case kI32:
1231cb0ef41Sopenharmony_ci      assm->movl(dst, src.gp());
1241cb0ef41Sopenharmony_ci      break;
1251cb0ef41Sopenharmony_ci    case kI64:
1261cb0ef41Sopenharmony_ci      assm->movq(dst, src.gp());
1271cb0ef41Sopenharmony_ci      break;
1281cb0ef41Sopenharmony_ci    case kOptRef:
1291cb0ef41Sopenharmony_ci    case kRef:
1301cb0ef41Sopenharmony_ci    case kRtt:
1311cb0ef41Sopenharmony_ci      assm->StoreTaggedField(dst, src.gp());
1321cb0ef41Sopenharmony_ci      break;
1331cb0ef41Sopenharmony_ci    case kF32:
1341cb0ef41Sopenharmony_ci      assm->Movss(dst, src.fp());
1351cb0ef41Sopenharmony_ci      break;
1361cb0ef41Sopenharmony_ci    case kF64:
1371cb0ef41Sopenharmony_ci      assm->Movsd(dst, src.fp());
1381cb0ef41Sopenharmony_ci      break;
1391cb0ef41Sopenharmony_ci    case kS128:
1401cb0ef41Sopenharmony_ci      assm->Movdqu(dst, src.fp());
1411cb0ef41Sopenharmony_ci      break;
1421cb0ef41Sopenharmony_ci    default:
1431cb0ef41Sopenharmony_ci      UNREACHABLE();
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ciinline void push(LiftoffAssembler* assm, LiftoffRegister reg, ValueKind kind,
1481cb0ef41Sopenharmony_ci                 int padding = 0) {
1491cb0ef41Sopenharmony_ci  switch (kind) {
1501cb0ef41Sopenharmony_ci    case kI32:
1511cb0ef41Sopenharmony_ci    case kI64:
1521cb0ef41Sopenharmony_ci    case kRef:
1531cb0ef41Sopenharmony_ci    case kOptRef:
1541cb0ef41Sopenharmony_ci      assm->AllocateStackSpace(padding);
1551cb0ef41Sopenharmony_ci      assm->pushq(reg.gp());
1561cb0ef41Sopenharmony_ci      break;
1571cb0ef41Sopenharmony_ci    case kF32:
1581cb0ef41Sopenharmony_ci      assm->AllocateStackSpace(kSystemPointerSize + padding);
1591cb0ef41Sopenharmony_ci      assm->Movss(Operand(rsp, 0), reg.fp());
1601cb0ef41Sopenharmony_ci      break;
1611cb0ef41Sopenharmony_ci    case kF64:
1621cb0ef41Sopenharmony_ci      assm->AllocateStackSpace(kSystemPointerSize + padding);
1631cb0ef41Sopenharmony_ci      assm->Movsd(Operand(rsp, 0), reg.fp());
1641cb0ef41Sopenharmony_ci      break;
1651cb0ef41Sopenharmony_ci    case kS128:
1661cb0ef41Sopenharmony_ci      assm->AllocateStackSpace(kSystemPointerSize * 2 + padding);
1671cb0ef41Sopenharmony_ci      assm->Movdqu(Operand(rsp, 0), reg.fp());
1681cb0ef41Sopenharmony_ci      break;
1691cb0ef41Sopenharmony_ci    default:
1701cb0ef41Sopenharmony_ci      UNREACHABLE();
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ciconstexpr int kSubSpSize = 7;  // 7 bytes for "subq rsp, <imm32>"
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci}  // namespace liftoff
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ciint LiftoffAssembler::PrepareStackFrame() {
1791cb0ef41Sopenharmony_ci  int offset = pc_offset();
1801cb0ef41Sopenharmony_ci  // Next we reserve the memory for the whole stack frame. We do not know yet
1811cb0ef41Sopenharmony_ci  // how big the stack frame will be so we just emit a placeholder instruction.
1821cb0ef41Sopenharmony_ci  // PatchPrepareStackFrame will patch this in order to increase the stack
1831cb0ef41Sopenharmony_ci  // appropriately.
1841cb0ef41Sopenharmony_ci  sub_sp_32(0);
1851cb0ef41Sopenharmony_ci  DCHECK_EQ(liftoff::kSubSpSize, pc_offset() - offset);
1861cb0ef41Sopenharmony_ci  return offset;
1871cb0ef41Sopenharmony_ci}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_civoid LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
1901cb0ef41Sopenharmony_ci                                       int stack_param_delta) {
1911cb0ef41Sopenharmony_ci  // Push the return address and frame pointer to complete the stack frame.
1921cb0ef41Sopenharmony_ci  pushq(Operand(rbp, 8));
1931cb0ef41Sopenharmony_ci  pushq(Operand(rbp, 0));
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci  // Shift the whole frame upwards.
1961cb0ef41Sopenharmony_ci  const int slot_count = num_callee_stack_params + 2;
1971cb0ef41Sopenharmony_ci  for (int i = slot_count - 1; i >= 0; --i) {
1981cb0ef41Sopenharmony_ci    movq(kScratchRegister, Operand(rsp, i * 8));
1991cb0ef41Sopenharmony_ci    movq(Operand(rbp, (i - stack_param_delta) * 8), kScratchRegister);
2001cb0ef41Sopenharmony_ci  }
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci  // Set the new stack and frame pointer.
2031cb0ef41Sopenharmony_ci  leaq(rsp, Operand(rbp, -stack_param_delta * 8));
2041cb0ef41Sopenharmony_ci  popq(rbp);
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_civoid LiftoffAssembler::AlignFrameSize() {
2081cb0ef41Sopenharmony_ci  max_used_spill_offset_ = RoundUp(max_used_spill_offset_, kSystemPointerSize);
2091cb0ef41Sopenharmony_ci}
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_civoid LiftoffAssembler::PatchPrepareStackFrame(
2121cb0ef41Sopenharmony_ci    int offset, SafepointTableBuilder* safepoint_table_builder) {
2131cb0ef41Sopenharmony_ci  // The frame_size includes the frame marker and the instance slot. Both are
2141cb0ef41Sopenharmony_ci  // pushed as part of frame construction, so we don't need to allocate memory
2151cb0ef41Sopenharmony_ci  // for them anymore.
2161cb0ef41Sopenharmony_ci  int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
2171cb0ef41Sopenharmony_ci  DCHECK_EQ(0, frame_size % kSystemPointerSize);
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  // We can't run out of space when patching, just pass anything big enough to
2201cb0ef41Sopenharmony_ci  // not cause the assembler to try to grow the buffer.
2211cb0ef41Sopenharmony_ci  constexpr int kAvailableSpace = 64;
2221cb0ef41Sopenharmony_ci  Assembler patching_assembler(
2231cb0ef41Sopenharmony_ci      AssemblerOptions{},
2241cb0ef41Sopenharmony_ci      ExternalAssemblerBuffer(buffer_start_ + offset, kAvailableSpace));
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  if (V8_LIKELY(frame_size < 4 * KB)) {
2271cb0ef41Sopenharmony_ci    // This is the standard case for small frames: just subtract from SP and be
2281cb0ef41Sopenharmony_ci    // done with it.
2291cb0ef41Sopenharmony_ci    patching_assembler.sub_sp_32(frame_size);
2301cb0ef41Sopenharmony_ci    DCHECK_EQ(liftoff::kSubSpSize, patching_assembler.pc_offset());
2311cb0ef41Sopenharmony_ci    return;
2321cb0ef41Sopenharmony_ci  }
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  // The frame size is bigger than 4KB, so we might overflow the available stack
2351cb0ef41Sopenharmony_ci  // space if we first allocate the frame and then do the stack check (we will
2361cb0ef41Sopenharmony_ci  // need some remaining stack space for throwing the exception). That's why we
2371cb0ef41Sopenharmony_ci  // check the available stack space before we allocate the frame. To do this we
2381cb0ef41Sopenharmony_ci  // replace the {__ sub(sp, framesize)} with a jump to OOL code that does this
2391cb0ef41Sopenharmony_ci  // "extended stack check".
2401cb0ef41Sopenharmony_ci  //
2411cb0ef41Sopenharmony_ci  // The OOL code can simply be generated here with the normal assembler,
2421cb0ef41Sopenharmony_ci  // because all other code generation, including OOL code, has already finished
2431cb0ef41Sopenharmony_ci  // when {PatchPrepareStackFrame} is called. The function prologue then jumps
2441cb0ef41Sopenharmony_ci  // to the current {pc_offset()} to execute the OOL code for allocating the
2451cb0ef41Sopenharmony_ci  // large frame.
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  // Emit the unconditional branch in the function prologue (from {offset} to
2481cb0ef41Sopenharmony_ci  // {pc_offset()}).
2491cb0ef41Sopenharmony_ci  patching_assembler.jmp_rel(pc_offset() - offset);
2501cb0ef41Sopenharmony_ci  DCHECK_GE(liftoff::kSubSpSize, patching_assembler.pc_offset());
2511cb0ef41Sopenharmony_ci  patching_assembler.Nop(liftoff::kSubSpSize - patching_assembler.pc_offset());
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  // If the frame is bigger than the stack, we throw the stack overflow
2541cb0ef41Sopenharmony_ci  // exception unconditionally. Thereby we can avoid the integer overflow
2551cb0ef41Sopenharmony_ci  // check in the condition code.
2561cb0ef41Sopenharmony_ci  RecordComment("OOL: stack check for large frame");
2571cb0ef41Sopenharmony_ci  Label continuation;
2581cb0ef41Sopenharmony_ci  if (frame_size < FLAG_stack_size * 1024) {
2591cb0ef41Sopenharmony_ci    movq(kScratchRegister,
2601cb0ef41Sopenharmony_ci         FieldOperand(kWasmInstanceRegister,
2611cb0ef41Sopenharmony_ci                      WasmInstanceObject::kRealStackLimitAddressOffset));
2621cb0ef41Sopenharmony_ci    movq(kScratchRegister, Operand(kScratchRegister, 0));
2631cb0ef41Sopenharmony_ci    addq(kScratchRegister, Immediate(frame_size));
2641cb0ef41Sopenharmony_ci    cmpq(rsp, kScratchRegister);
2651cb0ef41Sopenharmony_ci    j(above_equal, &continuation, Label::kNear);
2661cb0ef41Sopenharmony_ci  }
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  near_call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
2691cb0ef41Sopenharmony_ci  // The call will not return; just define an empty safepoint.
2701cb0ef41Sopenharmony_ci  safepoint_table_builder->DefineSafepoint(this);
2711cb0ef41Sopenharmony_ci  AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci  bind(&continuation);
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  // Now allocate the stack space. Note that this might do more than just
2761cb0ef41Sopenharmony_ci  // decrementing the SP; consult {TurboAssembler::AllocateStackSpace}.
2771cb0ef41Sopenharmony_ci  AllocateStackSpace(frame_size);
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  // Jump back to the start of the function, from {pc_offset()} to
2801cb0ef41Sopenharmony_ci  // right after the reserved space for the {__ sub(sp, sp, framesize)} (which
2811cb0ef41Sopenharmony_ci  // is a branch now).
2821cb0ef41Sopenharmony_ci  int func_start_offset = offset + liftoff::kSubSpSize;
2831cb0ef41Sopenharmony_ci  jmp_rel(func_start_offset - pc_offset());
2841cb0ef41Sopenharmony_ci}
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_civoid LiftoffAssembler::FinishCode() {}
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_civoid LiftoffAssembler::AbortCompilation() {}
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci// static
2911cb0ef41Sopenharmony_ciconstexpr int LiftoffAssembler::StaticStackFrameSize() {
2921cb0ef41Sopenharmony_ci  return kOSRTargetOffset;
2931cb0ef41Sopenharmony_ci}
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ciint LiftoffAssembler::SlotSizeForType(ValueKind kind) {
2961cb0ef41Sopenharmony_ci  return value_kind_full_size(kind);
2971cb0ef41Sopenharmony_ci}
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_cibool LiftoffAssembler::NeedsAlignment(ValueKind kind) {
3001cb0ef41Sopenharmony_ci  return is_reference(kind);
3011cb0ef41Sopenharmony_ci}
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value,
3041cb0ef41Sopenharmony_ci                                    RelocInfo::Mode rmode) {
3051cb0ef41Sopenharmony_ci  switch (value.type().kind()) {
3061cb0ef41Sopenharmony_ci    case kI32:
3071cb0ef41Sopenharmony_ci      if (value.to_i32() == 0 && RelocInfo::IsNoInfo(rmode)) {
3081cb0ef41Sopenharmony_ci        xorl(reg.gp(), reg.gp());
3091cb0ef41Sopenharmony_ci      } else {
3101cb0ef41Sopenharmony_ci        movl(reg.gp(), Immediate(value.to_i32(), rmode));
3111cb0ef41Sopenharmony_ci      }
3121cb0ef41Sopenharmony_ci      break;
3131cb0ef41Sopenharmony_ci    case kI64:
3141cb0ef41Sopenharmony_ci      if (RelocInfo::IsNoInfo(rmode)) {
3151cb0ef41Sopenharmony_ci        TurboAssembler::Move(reg.gp(), value.to_i64());
3161cb0ef41Sopenharmony_ci      } else {
3171cb0ef41Sopenharmony_ci        movq(reg.gp(), Immediate64(value.to_i64(), rmode));
3181cb0ef41Sopenharmony_ci      }
3191cb0ef41Sopenharmony_ci      break;
3201cb0ef41Sopenharmony_ci    case kF32:
3211cb0ef41Sopenharmony_ci      TurboAssembler::Move(reg.fp(), value.to_f32_boxed().get_bits());
3221cb0ef41Sopenharmony_ci      break;
3231cb0ef41Sopenharmony_ci    case kF64:
3241cb0ef41Sopenharmony_ci      TurboAssembler::Move(reg.fp(), value.to_f64_boxed().get_bits());
3251cb0ef41Sopenharmony_ci      break;
3261cb0ef41Sopenharmony_ci    default:
3271cb0ef41Sopenharmony_ci      UNREACHABLE();
3281cb0ef41Sopenharmony_ci  }
3291cb0ef41Sopenharmony_ci}
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadInstanceFromFrame(Register dst) {
3321cb0ef41Sopenharmony_ci  movq(dst, liftoff::GetInstanceOperand());
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadFromInstance(Register dst, Register instance,
3361cb0ef41Sopenharmony_ci                                        int offset, int size) {
3371cb0ef41Sopenharmony_ci  DCHECK_LE(0, offset);
3381cb0ef41Sopenharmony_ci  Operand src{instance, offset};
3391cb0ef41Sopenharmony_ci  switch (size) {
3401cb0ef41Sopenharmony_ci    case 1:
3411cb0ef41Sopenharmony_ci      movzxbl(dst, src);
3421cb0ef41Sopenharmony_ci      break;
3431cb0ef41Sopenharmony_ci    case 4:
3441cb0ef41Sopenharmony_ci      movl(dst, src);
3451cb0ef41Sopenharmony_ci      break;
3461cb0ef41Sopenharmony_ci    case 8:
3471cb0ef41Sopenharmony_ci      movq(dst, src);
3481cb0ef41Sopenharmony_ci      break;
3491cb0ef41Sopenharmony_ci    default:
3501cb0ef41Sopenharmony_ci      UNIMPLEMENTED();
3511cb0ef41Sopenharmony_ci  }
3521cb0ef41Sopenharmony_ci}
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTaggedPointerFromInstance(Register dst,
3551cb0ef41Sopenharmony_ci                                                     Register instance,
3561cb0ef41Sopenharmony_ci                                                     int offset) {
3571cb0ef41Sopenharmony_ci  DCHECK_LE(0, offset);
3581cb0ef41Sopenharmony_ci  LoadTaggedPointerField(dst, Operand(instance, offset));
3591cb0ef41Sopenharmony_ci}
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadExternalPointer(Register dst, Register instance,
3621cb0ef41Sopenharmony_ci                                           int offset, ExternalPointerTag tag,
3631cb0ef41Sopenharmony_ci                                           Register isolate_root) {
3641cb0ef41Sopenharmony_ci  LoadExternalPointerField(dst, FieldOperand(instance, offset), tag,
3651cb0ef41Sopenharmony_ci                           isolate_root,
3661cb0ef41Sopenharmony_ci                           IsolateRootLocation::kInScratchRegister);
3671cb0ef41Sopenharmony_ci}
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_civoid LiftoffAssembler::SpillInstance(Register instance) {
3701cb0ef41Sopenharmony_ci  movq(liftoff::GetInstanceOperand(), instance);
3711cb0ef41Sopenharmony_ci}
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_civoid LiftoffAssembler::ResetOSRTarget() {
3741cb0ef41Sopenharmony_ci  movq(liftoff::GetOSRTargetSlot(), Immediate(0));
3751cb0ef41Sopenharmony_ci}
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
3781cb0ef41Sopenharmony_ci                                         Register offset_reg,
3791cb0ef41Sopenharmony_ci                                         int32_t offset_imm,
3801cb0ef41Sopenharmony_ci                                         LiftoffRegList pinned) {
3811cb0ef41Sopenharmony_ci  DCHECK_GE(offset_imm, 0);
3821cb0ef41Sopenharmony_ci  if (FLAG_debug_code && offset_reg != no_reg) {
3831cb0ef41Sopenharmony_ci    AssertZeroExtended(offset_reg);
3841cb0ef41Sopenharmony_ci  }
3851cb0ef41Sopenharmony_ci  Operand src_op = liftoff::GetMemOp(this, src_addr, offset_reg,
3861cb0ef41Sopenharmony_ci                                     static_cast<uint32_t>(offset_imm));
3871cb0ef41Sopenharmony_ci  LoadTaggedPointerField(dst, src_op);
3881cb0ef41Sopenharmony_ci}
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadFullPointer(Register dst, Register src_addr,
3911cb0ef41Sopenharmony_ci                                       int32_t offset_imm) {
3921cb0ef41Sopenharmony_ci  Operand src_op = liftoff::GetMemOp(this, src_addr, no_reg,
3931cb0ef41Sopenharmony_ci                                     static_cast<uint32_t>(offset_imm));
3941cb0ef41Sopenharmony_ci  movq(dst, src_op);
3951cb0ef41Sopenharmony_ci}
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
3981cb0ef41Sopenharmony_ci                                          Register offset_reg,
3991cb0ef41Sopenharmony_ci                                          int32_t offset_imm,
4001cb0ef41Sopenharmony_ci                                          LiftoffRegister src,
4011cb0ef41Sopenharmony_ci                                          LiftoffRegList pinned,
4021cb0ef41Sopenharmony_ci                                          SkipWriteBarrier skip_write_barrier) {
4031cb0ef41Sopenharmony_ci  DCHECK_GE(offset_imm, 0);
4041cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg,
4051cb0ef41Sopenharmony_ci                                     static_cast<uint32_t>(offset_imm));
4061cb0ef41Sopenharmony_ci  StoreTaggedField(dst_op, src.gp());
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci  if (skip_write_barrier || FLAG_disable_write_barriers) return;
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci  Register scratch = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
4111cb0ef41Sopenharmony_ci  Label write_barrier;
4121cb0ef41Sopenharmony_ci  Label exit;
4131cb0ef41Sopenharmony_ci  CheckPageFlag(dst_addr, scratch,
4141cb0ef41Sopenharmony_ci                MemoryChunk::kPointersFromHereAreInterestingMask, not_zero,
4151cb0ef41Sopenharmony_ci                &write_barrier, Label::kNear);
4161cb0ef41Sopenharmony_ci  jmp(&exit, Label::kNear);
4171cb0ef41Sopenharmony_ci  bind(&write_barrier);
4181cb0ef41Sopenharmony_ci  JumpIfSmi(src.gp(), &exit, Label::kNear);
4191cb0ef41Sopenharmony_ci  if (COMPRESS_POINTERS_BOOL) {
4201cb0ef41Sopenharmony_ci    DecompressTaggedPointer(src.gp(), src.gp());
4211cb0ef41Sopenharmony_ci  }
4221cb0ef41Sopenharmony_ci  CheckPageFlag(src.gp(), scratch,
4231cb0ef41Sopenharmony_ci                MemoryChunk::kPointersToHereAreInterestingMask, zero, &exit,
4241cb0ef41Sopenharmony_ci                Label::kNear);
4251cb0ef41Sopenharmony_ci  leaq(scratch, dst_op);
4261cb0ef41Sopenharmony_ci
4271cb0ef41Sopenharmony_ci  CallRecordWriteStubSaveRegisters(
4281cb0ef41Sopenharmony_ci      dst_addr, scratch, RememberedSetAction::kEmit, SaveFPRegsMode::kSave,
4291cb0ef41Sopenharmony_ci      StubCallMode::kCallWasmRuntimeStub);
4301cb0ef41Sopenharmony_ci  bind(&exit);
4311cb0ef41Sopenharmony_ci}
4321cb0ef41Sopenharmony_ci
4331cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicLoad(LiftoffRegister dst, Register src_addr,
4341cb0ef41Sopenharmony_ci                                  Register offset_reg, uintptr_t offset_imm,
4351cb0ef41Sopenharmony_ci                                  LoadType type, LiftoffRegList pinned) {
4361cb0ef41Sopenharmony_ci  Load(dst, src_addr, offset_reg, offset_imm, type, pinned, nullptr, true);
4371cb0ef41Sopenharmony_ci}
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_civoid LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
4401cb0ef41Sopenharmony_ci                            Register offset_reg, uintptr_t offset_imm,
4411cb0ef41Sopenharmony_ci                            LoadType type, LiftoffRegList pinned,
4421cb0ef41Sopenharmony_ci                            uint32_t* protected_load_pc, bool is_load_mem,
4431cb0ef41Sopenharmony_ci                            bool i64_offset) {
4441cb0ef41Sopenharmony_ci  if (offset_reg != no_reg && !i64_offset) {
4451cb0ef41Sopenharmony_ci    AssertZeroExtended(offset_reg);
4461cb0ef41Sopenharmony_ci  }
4471cb0ef41Sopenharmony_ci  Operand src_op = liftoff::GetMemOp(this, src_addr, offset_reg, offset_imm);
4481cb0ef41Sopenharmony_ci  if (protected_load_pc) *protected_load_pc = pc_offset();
4491cb0ef41Sopenharmony_ci  switch (type.value()) {
4501cb0ef41Sopenharmony_ci    case LoadType::kI32Load8U:
4511cb0ef41Sopenharmony_ci    case LoadType::kI64Load8U:
4521cb0ef41Sopenharmony_ci      movzxbl(dst.gp(), src_op);
4531cb0ef41Sopenharmony_ci      break;
4541cb0ef41Sopenharmony_ci    case LoadType::kI32Load8S:
4551cb0ef41Sopenharmony_ci      movsxbl(dst.gp(), src_op);
4561cb0ef41Sopenharmony_ci      break;
4571cb0ef41Sopenharmony_ci    case LoadType::kI64Load8S:
4581cb0ef41Sopenharmony_ci      movsxbq(dst.gp(), src_op);
4591cb0ef41Sopenharmony_ci      break;
4601cb0ef41Sopenharmony_ci    case LoadType::kI32Load16U:
4611cb0ef41Sopenharmony_ci    case LoadType::kI64Load16U:
4621cb0ef41Sopenharmony_ci      movzxwl(dst.gp(), src_op);
4631cb0ef41Sopenharmony_ci      break;
4641cb0ef41Sopenharmony_ci    case LoadType::kI32Load16S:
4651cb0ef41Sopenharmony_ci      movsxwl(dst.gp(), src_op);
4661cb0ef41Sopenharmony_ci      break;
4671cb0ef41Sopenharmony_ci    case LoadType::kI64Load16S:
4681cb0ef41Sopenharmony_ci      movsxwq(dst.gp(), src_op);
4691cb0ef41Sopenharmony_ci      break;
4701cb0ef41Sopenharmony_ci    case LoadType::kI32Load:
4711cb0ef41Sopenharmony_ci    case LoadType::kI64Load32U:
4721cb0ef41Sopenharmony_ci      movl(dst.gp(), src_op);
4731cb0ef41Sopenharmony_ci      break;
4741cb0ef41Sopenharmony_ci    case LoadType::kI64Load32S:
4751cb0ef41Sopenharmony_ci      movsxlq(dst.gp(), src_op);
4761cb0ef41Sopenharmony_ci      break;
4771cb0ef41Sopenharmony_ci    case LoadType::kI64Load:
4781cb0ef41Sopenharmony_ci      movq(dst.gp(), src_op);
4791cb0ef41Sopenharmony_ci      break;
4801cb0ef41Sopenharmony_ci    case LoadType::kF32Load:
4811cb0ef41Sopenharmony_ci      Movss(dst.fp(), src_op);
4821cb0ef41Sopenharmony_ci      break;
4831cb0ef41Sopenharmony_ci    case LoadType::kF64Load:
4841cb0ef41Sopenharmony_ci      Movsd(dst.fp(), src_op);
4851cb0ef41Sopenharmony_ci      break;
4861cb0ef41Sopenharmony_ci    case LoadType::kS128Load:
4871cb0ef41Sopenharmony_ci      Movdqu(dst.fp(), src_op);
4881cb0ef41Sopenharmony_ci      break;
4891cb0ef41Sopenharmony_ci  }
4901cb0ef41Sopenharmony_ci}
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_civoid LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
4931cb0ef41Sopenharmony_ci                             uintptr_t offset_imm, LiftoffRegister src,
4941cb0ef41Sopenharmony_ci                             StoreType type, LiftoffRegList /* pinned */,
4951cb0ef41Sopenharmony_ci                             uint32_t* protected_store_pc, bool is_store_mem) {
4961cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
4971cb0ef41Sopenharmony_ci  if (protected_store_pc) *protected_store_pc = pc_offset();
4981cb0ef41Sopenharmony_ci  switch (type.value()) {
4991cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
5001cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
5011cb0ef41Sopenharmony_ci      movb(dst_op, src.gp());
5021cb0ef41Sopenharmony_ci      break;
5031cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
5041cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
5051cb0ef41Sopenharmony_ci      movw(dst_op, src.gp());
5061cb0ef41Sopenharmony_ci      break;
5071cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
5081cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
5091cb0ef41Sopenharmony_ci      movl(dst_op, src.gp());
5101cb0ef41Sopenharmony_ci      break;
5111cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
5121cb0ef41Sopenharmony_ci      movq(dst_op, src.gp());
5131cb0ef41Sopenharmony_ci      break;
5141cb0ef41Sopenharmony_ci    case StoreType::kF32Store:
5151cb0ef41Sopenharmony_ci      Movss(dst_op, src.fp());
5161cb0ef41Sopenharmony_ci      break;
5171cb0ef41Sopenharmony_ci    case StoreType::kF64Store:
5181cb0ef41Sopenharmony_ci      Movsd(dst_op, src.fp());
5191cb0ef41Sopenharmony_ci      break;
5201cb0ef41Sopenharmony_ci    case StoreType::kS128Store:
5211cb0ef41Sopenharmony_ci      Movdqu(dst_op, src.fp());
5221cb0ef41Sopenharmony_ci      break;
5231cb0ef41Sopenharmony_ci  }
5241cb0ef41Sopenharmony_ci}
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
5271cb0ef41Sopenharmony_ci                                   uintptr_t offset_imm, LiftoffRegister src,
5281cb0ef41Sopenharmony_ci                                   StoreType type, LiftoffRegList pinned) {
5291cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
5301cb0ef41Sopenharmony_ci  Register src_reg = src.gp();
5311cb0ef41Sopenharmony_ci  if (cache_state()->is_used(src)) {
5321cb0ef41Sopenharmony_ci    movq(kScratchRegister, src_reg);
5331cb0ef41Sopenharmony_ci    src_reg = kScratchRegister;
5341cb0ef41Sopenharmony_ci  }
5351cb0ef41Sopenharmony_ci  switch (type.value()) {
5361cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
5371cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
5381cb0ef41Sopenharmony_ci      xchgb(src_reg, dst_op);
5391cb0ef41Sopenharmony_ci      break;
5401cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
5411cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
5421cb0ef41Sopenharmony_ci      xchgw(src_reg, dst_op);
5431cb0ef41Sopenharmony_ci      break;
5441cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
5451cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
5461cb0ef41Sopenharmony_ci      xchgl(src_reg, dst_op);
5471cb0ef41Sopenharmony_ci      break;
5481cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
5491cb0ef41Sopenharmony_ci      xchgq(src_reg, dst_op);
5501cb0ef41Sopenharmony_ci      break;
5511cb0ef41Sopenharmony_ci    default:
5521cb0ef41Sopenharmony_ci      UNREACHABLE();
5531cb0ef41Sopenharmony_ci  }
5541cb0ef41Sopenharmony_ci}
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
5571cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
5581cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
5591cb0ef41Sopenharmony_ci  DCHECK(!cache_state()->is_used(result));
5601cb0ef41Sopenharmony_ci  if (cache_state()->is_used(value)) {
5611cb0ef41Sopenharmony_ci    // We cannot overwrite {value}, but the {value} register is changed in the
5621cb0ef41Sopenharmony_ci    // code we generate. Therefore we copy {value} to {result} and use the
5631cb0ef41Sopenharmony_ci    // {result} register in the code below.
5641cb0ef41Sopenharmony_ci    movq(result.gp(), value.gp());
5651cb0ef41Sopenharmony_ci    value = result;
5661cb0ef41Sopenharmony_ci  }
5671cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
5681cb0ef41Sopenharmony_ci  lock();
5691cb0ef41Sopenharmony_ci  switch (type.value()) {
5701cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
5711cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
5721cb0ef41Sopenharmony_ci      xaddb(dst_op, value.gp());
5731cb0ef41Sopenharmony_ci      movzxbq(result.gp(), value.gp());
5741cb0ef41Sopenharmony_ci      break;
5751cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
5761cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
5771cb0ef41Sopenharmony_ci      xaddw(dst_op, value.gp());
5781cb0ef41Sopenharmony_ci      movzxwq(result.gp(), value.gp());
5791cb0ef41Sopenharmony_ci      break;
5801cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
5811cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
5821cb0ef41Sopenharmony_ci      xaddl(dst_op, value.gp());
5831cb0ef41Sopenharmony_ci      if (value != result) {
5841cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
5851cb0ef41Sopenharmony_ci      }
5861cb0ef41Sopenharmony_ci      break;
5871cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
5881cb0ef41Sopenharmony_ci      xaddq(dst_op, value.gp());
5891cb0ef41Sopenharmony_ci      if (value != result) {
5901cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
5911cb0ef41Sopenharmony_ci      }
5921cb0ef41Sopenharmony_ci      break;
5931cb0ef41Sopenharmony_ci    default:
5941cb0ef41Sopenharmony_ci      UNREACHABLE();
5951cb0ef41Sopenharmony_ci  }
5961cb0ef41Sopenharmony_ci}
5971cb0ef41Sopenharmony_ci
5981cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
5991cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
6001cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
6011cb0ef41Sopenharmony_ci  LiftoffRegList dont_overwrite =
6021cb0ef41Sopenharmony_ci      cache_state()->used_registers | LiftoffRegList{dst_addr, offset_reg};
6031cb0ef41Sopenharmony_ci  DCHECK(!dont_overwrite.has(result));
6041cb0ef41Sopenharmony_ci  if (dont_overwrite.has(value)) {
6051cb0ef41Sopenharmony_ci    // We cannot overwrite {value}, but the {value} register is changed in the
6061cb0ef41Sopenharmony_ci    // code we generate. Therefore we copy {value} to {result} and use the
6071cb0ef41Sopenharmony_ci    // {result} register in the code below.
6081cb0ef41Sopenharmony_ci    movq(result.gp(), value.gp());
6091cb0ef41Sopenharmony_ci    value = result;
6101cb0ef41Sopenharmony_ci  }
6111cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
6121cb0ef41Sopenharmony_ci  switch (type.value()) {
6131cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
6141cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
6151cb0ef41Sopenharmony_ci      negb(value.gp());
6161cb0ef41Sopenharmony_ci      lock();
6171cb0ef41Sopenharmony_ci      xaddb(dst_op, value.gp());
6181cb0ef41Sopenharmony_ci      movzxbq(result.gp(), value.gp());
6191cb0ef41Sopenharmony_ci      break;
6201cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
6211cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
6221cb0ef41Sopenharmony_ci      negw(value.gp());
6231cb0ef41Sopenharmony_ci      lock();
6241cb0ef41Sopenharmony_ci      xaddw(dst_op, value.gp());
6251cb0ef41Sopenharmony_ci      movzxwq(result.gp(), value.gp());
6261cb0ef41Sopenharmony_ci      break;
6271cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
6281cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
6291cb0ef41Sopenharmony_ci      negl(value.gp());
6301cb0ef41Sopenharmony_ci      lock();
6311cb0ef41Sopenharmony_ci      xaddl(dst_op, value.gp());
6321cb0ef41Sopenharmony_ci      if (value != result) {
6331cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
6341cb0ef41Sopenharmony_ci      }
6351cb0ef41Sopenharmony_ci      break;
6361cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
6371cb0ef41Sopenharmony_ci      negq(value.gp());
6381cb0ef41Sopenharmony_ci      lock();
6391cb0ef41Sopenharmony_ci      xaddq(dst_op, value.gp());
6401cb0ef41Sopenharmony_ci      if (value != result) {
6411cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
6421cb0ef41Sopenharmony_ci      }
6431cb0ef41Sopenharmony_ci      break;
6441cb0ef41Sopenharmony_ci    default:
6451cb0ef41Sopenharmony_ci      UNREACHABLE();
6461cb0ef41Sopenharmony_ci  }
6471cb0ef41Sopenharmony_ci}
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_cinamespace liftoff {
6501cb0ef41Sopenharmony_ci#define __ lasm->
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ciinline void AtomicBinop(LiftoffAssembler* lasm,
6531cb0ef41Sopenharmony_ci                        void (Assembler::*opl)(Register, Register),
6541cb0ef41Sopenharmony_ci                        void (Assembler::*opq)(Register, Register),
6551cb0ef41Sopenharmony_ci                        Register dst_addr, Register offset_reg,
6561cb0ef41Sopenharmony_ci                        uintptr_t offset_imm, LiftoffRegister value,
6571cb0ef41Sopenharmony_ci                        LiftoffRegister result, StoreType type) {
6581cb0ef41Sopenharmony_ci  DCHECK(!__ cache_state()->is_used(result));
6591cb0ef41Sopenharmony_ci  Register value_reg = value.gp();
6601cb0ef41Sopenharmony_ci  // The cmpxchg instruction uses rax to store the old value of the
6611cb0ef41Sopenharmony_ci  // compare-exchange primitive. Therefore we have to spill the register and
6621cb0ef41Sopenharmony_ci  // move any use to another register.
6631cb0ef41Sopenharmony_ci  LiftoffRegList pinned = LiftoffRegList{dst_addr, offset_reg, value_reg};
6641cb0ef41Sopenharmony_ci  __ ClearRegister(rax, {&dst_addr, &offset_reg, &value_reg}, pinned);
6651cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(lasm, dst_addr, offset_reg, offset_imm);
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci  switch (type.value()) {
6681cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
6691cb0ef41Sopenharmony_ci    case StoreType::kI64Store8: {
6701cb0ef41Sopenharmony_ci      Label binop;
6711cb0ef41Sopenharmony_ci      __ xorq(rax, rax);
6721cb0ef41Sopenharmony_ci      __ movb(rax, dst_op);
6731cb0ef41Sopenharmony_ci      __ bind(&binop);
6741cb0ef41Sopenharmony_ci      __ movl(kScratchRegister, rax);
6751cb0ef41Sopenharmony_ci      (lasm->*opl)(kScratchRegister, value_reg);
6761cb0ef41Sopenharmony_ci      __ lock();
6771cb0ef41Sopenharmony_ci      __ cmpxchgb(dst_op, kScratchRegister);
6781cb0ef41Sopenharmony_ci      __ j(not_equal, &binop);
6791cb0ef41Sopenharmony_ci      break;
6801cb0ef41Sopenharmony_ci    }
6811cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
6821cb0ef41Sopenharmony_ci    case StoreType::kI64Store16: {
6831cb0ef41Sopenharmony_ci      Label binop;
6841cb0ef41Sopenharmony_ci      __ xorq(rax, rax);
6851cb0ef41Sopenharmony_ci      __ movw(rax, dst_op);
6861cb0ef41Sopenharmony_ci      __ bind(&binop);
6871cb0ef41Sopenharmony_ci      __ movl(kScratchRegister, rax);
6881cb0ef41Sopenharmony_ci      (lasm->*opl)(kScratchRegister, value_reg);
6891cb0ef41Sopenharmony_ci      __ lock();
6901cb0ef41Sopenharmony_ci      __ cmpxchgw(dst_op, kScratchRegister);
6911cb0ef41Sopenharmony_ci      __ j(not_equal, &binop);
6921cb0ef41Sopenharmony_ci      break;
6931cb0ef41Sopenharmony_ci    }
6941cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
6951cb0ef41Sopenharmony_ci    case StoreType::kI64Store32: {
6961cb0ef41Sopenharmony_ci      Label binop;
6971cb0ef41Sopenharmony_ci      __ movl(rax, dst_op);
6981cb0ef41Sopenharmony_ci      __ bind(&binop);
6991cb0ef41Sopenharmony_ci      __ movl(kScratchRegister, rax);
7001cb0ef41Sopenharmony_ci      (lasm->*opl)(kScratchRegister, value_reg);
7011cb0ef41Sopenharmony_ci      __ lock();
7021cb0ef41Sopenharmony_ci      __ cmpxchgl(dst_op, kScratchRegister);
7031cb0ef41Sopenharmony_ci      __ j(not_equal, &binop);
7041cb0ef41Sopenharmony_ci      break;
7051cb0ef41Sopenharmony_ci    }
7061cb0ef41Sopenharmony_ci    case StoreType::kI64Store: {
7071cb0ef41Sopenharmony_ci      Label binop;
7081cb0ef41Sopenharmony_ci      __ movq(rax, dst_op);
7091cb0ef41Sopenharmony_ci      __ bind(&binop);
7101cb0ef41Sopenharmony_ci      __ movq(kScratchRegister, rax);
7111cb0ef41Sopenharmony_ci      (lasm->*opq)(kScratchRegister, value_reg);
7121cb0ef41Sopenharmony_ci      __ lock();
7131cb0ef41Sopenharmony_ci      __ cmpxchgq(dst_op, kScratchRegister);
7141cb0ef41Sopenharmony_ci      __ j(not_equal, &binop);
7151cb0ef41Sopenharmony_ci      break;
7161cb0ef41Sopenharmony_ci    }
7171cb0ef41Sopenharmony_ci    default:
7181cb0ef41Sopenharmony_ci      UNREACHABLE();
7191cb0ef41Sopenharmony_ci  }
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci  if (result.gp() != rax) {
7221cb0ef41Sopenharmony_ci    __ movq(result.gp(), rax);
7231cb0ef41Sopenharmony_ci  }
7241cb0ef41Sopenharmony_ci}
7251cb0ef41Sopenharmony_ci#undef __
7261cb0ef41Sopenharmony_ci}  // namespace liftoff
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
7291cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
7301cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
7311cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, &Assembler::andl, &Assembler::andq, dst_addr,
7321cb0ef41Sopenharmony_ci                       offset_reg, offset_imm, value, result, type);
7331cb0ef41Sopenharmony_ci}
7341cb0ef41Sopenharmony_ci
7351cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
7361cb0ef41Sopenharmony_ci                                uintptr_t offset_imm, LiftoffRegister value,
7371cb0ef41Sopenharmony_ci                                LiftoffRegister result, StoreType type) {
7381cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, &Assembler::orl, &Assembler::orq, dst_addr,
7391cb0ef41Sopenharmony_ci                       offset_reg, offset_imm, value, result, type);
7401cb0ef41Sopenharmony_ci}
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
7431cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister value,
7441cb0ef41Sopenharmony_ci                                 LiftoffRegister result, StoreType type) {
7451cb0ef41Sopenharmony_ci  liftoff::AtomicBinop(this, &Assembler::xorl, &Assembler::xorq, dst_addr,
7461cb0ef41Sopenharmony_ci                       offset_reg, offset_imm, value, result, type);
7471cb0ef41Sopenharmony_ci}
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
7501cb0ef41Sopenharmony_ci                                      uintptr_t offset_imm,
7511cb0ef41Sopenharmony_ci                                      LiftoffRegister value,
7521cb0ef41Sopenharmony_ci                                      LiftoffRegister result, StoreType type) {
7531cb0ef41Sopenharmony_ci  DCHECK(!cache_state()->is_used(result));
7541cb0ef41Sopenharmony_ci  if (cache_state()->is_used(value)) {
7551cb0ef41Sopenharmony_ci    // We cannot overwrite {value}, but the {value} register is changed in the
7561cb0ef41Sopenharmony_ci    // code we generate. Therefore we copy {value} to {result} and use the
7571cb0ef41Sopenharmony_ci    // {result} register in the code below.
7581cb0ef41Sopenharmony_ci    movq(result.gp(), value.gp());
7591cb0ef41Sopenharmony_ci    value = result;
7601cb0ef41Sopenharmony_ci  }
7611cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
7621cb0ef41Sopenharmony_ci  switch (type.value()) {
7631cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
7641cb0ef41Sopenharmony_ci    case StoreType::kI64Store8:
7651cb0ef41Sopenharmony_ci      xchgb(value.gp(), dst_op);
7661cb0ef41Sopenharmony_ci      movzxbq(result.gp(), value.gp());
7671cb0ef41Sopenharmony_ci      break;
7681cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
7691cb0ef41Sopenharmony_ci    case StoreType::kI64Store16:
7701cb0ef41Sopenharmony_ci      xchgw(value.gp(), dst_op);
7711cb0ef41Sopenharmony_ci      movzxwq(result.gp(), value.gp());
7721cb0ef41Sopenharmony_ci      break;
7731cb0ef41Sopenharmony_ci    case StoreType::kI32Store:
7741cb0ef41Sopenharmony_ci    case StoreType::kI64Store32:
7751cb0ef41Sopenharmony_ci      xchgl(value.gp(), dst_op);
7761cb0ef41Sopenharmony_ci      if (value != result) {
7771cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
7781cb0ef41Sopenharmony_ci      }
7791cb0ef41Sopenharmony_ci      break;
7801cb0ef41Sopenharmony_ci    case StoreType::kI64Store:
7811cb0ef41Sopenharmony_ci      xchgq(value.gp(), dst_op);
7821cb0ef41Sopenharmony_ci      if (value != result) {
7831cb0ef41Sopenharmony_ci        movq(result.gp(), value.gp());
7841cb0ef41Sopenharmony_ci      }
7851cb0ef41Sopenharmony_ci      break;
7861cb0ef41Sopenharmony_ci    default:
7871cb0ef41Sopenharmony_ci      UNREACHABLE();
7881cb0ef41Sopenharmony_ci  }
7891cb0ef41Sopenharmony_ci}
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicCompareExchange(
7921cb0ef41Sopenharmony_ci    Register dst_addr, Register offset_reg, uintptr_t offset_imm,
7931cb0ef41Sopenharmony_ci    LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result,
7941cb0ef41Sopenharmony_ci    StoreType type) {
7951cb0ef41Sopenharmony_ci  Register value_reg = new_value.gp();
7961cb0ef41Sopenharmony_ci  // The cmpxchg instruction uses rax to store the old value of the
7971cb0ef41Sopenharmony_ci  // compare-exchange primitive. Therefore we have to spill the register and
7981cb0ef41Sopenharmony_ci  // move any use to another register.
7991cb0ef41Sopenharmony_ci  LiftoffRegList pinned =
8001cb0ef41Sopenharmony_ci      LiftoffRegList{dst_addr, offset_reg, expected, value_reg};
8011cb0ef41Sopenharmony_ci  ClearRegister(rax, {&dst_addr, &offset_reg, &value_reg}, pinned);
8021cb0ef41Sopenharmony_ci  if (expected.gp() != rax) {
8031cb0ef41Sopenharmony_ci    movq(rax, expected.gp());
8041cb0ef41Sopenharmony_ci  }
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci  lock();
8091cb0ef41Sopenharmony_ci  switch (type.value()) {
8101cb0ef41Sopenharmony_ci    case StoreType::kI32Store8:
8111cb0ef41Sopenharmony_ci    case StoreType::kI64Store8: {
8121cb0ef41Sopenharmony_ci      cmpxchgb(dst_op, value_reg);
8131cb0ef41Sopenharmony_ci      movzxbq(result.gp(), rax);
8141cb0ef41Sopenharmony_ci      break;
8151cb0ef41Sopenharmony_ci    }
8161cb0ef41Sopenharmony_ci    case StoreType::kI32Store16:
8171cb0ef41Sopenharmony_ci    case StoreType::kI64Store16: {
8181cb0ef41Sopenharmony_ci      cmpxchgw(dst_op, value_reg);
8191cb0ef41Sopenharmony_ci      movzxwq(result.gp(), rax);
8201cb0ef41Sopenharmony_ci      break;
8211cb0ef41Sopenharmony_ci    }
8221cb0ef41Sopenharmony_ci    case StoreType::kI32Store: {
8231cb0ef41Sopenharmony_ci      cmpxchgl(dst_op, value_reg);
8241cb0ef41Sopenharmony_ci      if (result.gp() != rax) {
8251cb0ef41Sopenharmony_ci        movl(result.gp(), rax);
8261cb0ef41Sopenharmony_ci      }
8271cb0ef41Sopenharmony_ci      break;
8281cb0ef41Sopenharmony_ci    }
8291cb0ef41Sopenharmony_ci    case StoreType::kI64Store32: {
8301cb0ef41Sopenharmony_ci      cmpxchgl(dst_op, value_reg);
8311cb0ef41Sopenharmony_ci      // Zero extension.
8321cb0ef41Sopenharmony_ci      movl(result.gp(), rax);
8331cb0ef41Sopenharmony_ci      break;
8341cb0ef41Sopenharmony_ci    }
8351cb0ef41Sopenharmony_ci    case StoreType::kI64Store: {
8361cb0ef41Sopenharmony_ci      cmpxchgq(dst_op, value_reg);
8371cb0ef41Sopenharmony_ci      if (result.gp() != rax) {
8381cb0ef41Sopenharmony_ci        movq(result.gp(), rax);
8391cb0ef41Sopenharmony_ci      }
8401cb0ef41Sopenharmony_ci      break;
8411cb0ef41Sopenharmony_ci    }
8421cb0ef41Sopenharmony_ci    default:
8431cb0ef41Sopenharmony_ci      UNREACHABLE();
8441cb0ef41Sopenharmony_ci  }
8451cb0ef41Sopenharmony_ci}
8461cb0ef41Sopenharmony_ci
8471cb0ef41Sopenharmony_civoid LiftoffAssembler::AtomicFence() { mfence(); }
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
8501cb0ef41Sopenharmony_ci                                           uint32_t caller_slot_idx,
8511cb0ef41Sopenharmony_ci                                           ValueKind kind) {
8521cb0ef41Sopenharmony_ci  Operand src(rbp, kSystemPointerSize * (caller_slot_idx + 1));
8531cb0ef41Sopenharmony_ci  liftoff::Load(this, dst, src, kind);
8541cb0ef41Sopenharmony_ci}
8551cb0ef41Sopenharmony_ci
8561cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreCallerFrameSlot(LiftoffRegister src,
8571cb0ef41Sopenharmony_ci                                            uint32_t caller_slot_idx,
8581cb0ef41Sopenharmony_ci                                            ValueKind kind) {
8591cb0ef41Sopenharmony_ci  Operand dst(rbp, kSystemPointerSize * (caller_slot_idx + 1));
8601cb0ef41Sopenharmony_ci  liftoff::Store(this, dst, src, kind);
8611cb0ef41Sopenharmony_ci}
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadReturnStackSlot(LiftoffRegister reg, int offset,
8641cb0ef41Sopenharmony_ci                                           ValueKind kind) {
8651cb0ef41Sopenharmony_ci  Operand src(rsp, offset);
8661cb0ef41Sopenharmony_ci  liftoff::Load(this, reg, src, kind);
8671cb0ef41Sopenharmony_ci}
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_civoid LiftoffAssembler::MoveStackValue(uint32_t dst_offset, uint32_t src_offset,
8701cb0ef41Sopenharmony_ci                                      ValueKind kind) {
8711cb0ef41Sopenharmony_ci  DCHECK_NE(dst_offset, src_offset);
8721cb0ef41Sopenharmony_ci  Operand dst = liftoff::GetStackSlot(dst_offset);
8731cb0ef41Sopenharmony_ci  Operand src = liftoff::GetStackSlot(src_offset);
8741cb0ef41Sopenharmony_ci  switch (SlotSizeForType(kind)) {
8751cb0ef41Sopenharmony_ci    case 4:
8761cb0ef41Sopenharmony_ci      movl(kScratchRegister, src);
8771cb0ef41Sopenharmony_ci      movl(dst, kScratchRegister);
8781cb0ef41Sopenharmony_ci      break;
8791cb0ef41Sopenharmony_ci    case 8:
8801cb0ef41Sopenharmony_ci      movq(kScratchRegister, src);
8811cb0ef41Sopenharmony_ci      movq(dst, kScratchRegister);
8821cb0ef41Sopenharmony_ci      break;
8831cb0ef41Sopenharmony_ci    case 16:
8841cb0ef41Sopenharmony_ci      Movdqu(kScratchDoubleReg, src);
8851cb0ef41Sopenharmony_ci      Movdqu(dst, kScratchDoubleReg);
8861cb0ef41Sopenharmony_ci      break;
8871cb0ef41Sopenharmony_ci    default:
8881cb0ef41Sopenharmony_ci      UNREACHABLE();
8891cb0ef41Sopenharmony_ci  }
8901cb0ef41Sopenharmony_ci}
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_civoid LiftoffAssembler::Move(Register dst, Register src, ValueKind kind) {
8931cb0ef41Sopenharmony_ci  DCHECK_NE(dst, src);
8941cb0ef41Sopenharmony_ci  if (kind == kI32) {
8951cb0ef41Sopenharmony_ci    movl(dst, src);
8961cb0ef41Sopenharmony_ci  } else {
8971cb0ef41Sopenharmony_ci    DCHECK(kI64 == kind || is_reference(kind));
8981cb0ef41Sopenharmony_ci    movq(dst, src);
8991cb0ef41Sopenharmony_ci  }
9001cb0ef41Sopenharmony_ci}
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_civoid LiftoffAssembler::Move(DoubleRegister dst, DoubleRegister src,
9031cb0ef41Sopenharmony_ci                            ValueKind kind) {
9041cb0ef41Sopenharmony_ci  DCHECK_NE(dst, src);
9051cb0ef41Sopenharmony_ci  if (kind == kF32) {
9061cb0ef41Sopenharmony_ci    Movss(dst, src);
9071cb0ef41Sopenharmony_ci  } else if (kind == kF64) {
9081cb0ef41Sopenharmony_ci    Movsd(dst, src);
9091cb0ef41Sopenharmony_ci  } else {
9101cb0ef41Sopenharmony_ci    DCHECK_EQ(kS128, kind);
9111cb0ef41Sopenharmony_ci    Movapd(dst, src);
9121cb0ef41Sopenharmony_ci  }
9131cb0ef41Sopenharmony_ci}
9141cb0ef41Sopenharmony_ci
9151cb0ef41Sopenharmony_civoid LiftoffAssembler::Spill(int offset, LiftoffRegister reg, ValueKind kind) {
9161cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(offset);
9171cb0ef41Sopenharmony_ci  Operand dst = liftoff::GetStackSlot(offset);
9181cb0ef41Sopenharmony_ci  switch (kind) {
9191cb0ef41Sopenharmony_ci    case kI32:
9201cb0ef41Sopenharmony_ci      movl(dst, reg.gp());
9211cb0ef41Sopenharmony_ci      break;
9221cb0ef41Sopenharmony_ci    case kI64:
9231cb0ef41Sopenharmony_ci    case kOptRef:
9241cb0ef41Sopenharmony_ci    case kRef:
9251cb0ef41Sopenharmony_ci    case kRtt:
9261cb0ef41Sopenharmony_ci      movq(dst, reg.gp());
9271cb0ef41Sopenharmony_ci      break;
9281cb0ef41Sopenharmony_ci    case kF32:
9291cb0ef41Sopenharmony_ci      Movss(dst, reg.fp());
9301cb0ef41Sopenharmony_ci      break;
9311cb0ef41Sopenharmony_ci    case kF64:
9321cb0ef41Sopenharmony_ci      Movsd(dst, reg.fp());
9331cb0ef41Sopenharmony_ci      break;
9341cb0ef41Sopenharmony_ci    case kS128:
9351cb0ef41Sopenharmony_ci      Movdqu(dst, reg.fp());
9361cb0ef41Sopenharmony_ci      break;
9371cb0ef41Sopenharmony_ci    default:
9381cb0ef41Sopenharmony_ci      UNREACHABLE();
9391cb0ef41Sopenharmony_ci  }
9401cb0ef41Sopenharmony_ci}
9411cb0ef41Sopenharmony_ci
9421cb0ef41Sopenharmony_civoid LiftoffAssembler::Spill(int offset, WasmValue value) {
9431cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(offset);
9441cb0ef41Sopenharmony_ci  Operand dst = liftoff::GetStackSlot(offset);
9451cb0ef41Sopenharmony_ci  switch (value.type().kind()) {
9461cb0ef41Sopenharmony_ci    case kI32:
9471cb0ef41Sopenharmony_ci      movl(dst, Immediate(value.to_i32()));
9481cb0ef41Sopenharmony_ci      break;
9491cb0ef41Sopenharmony_ci    case kI64: {
9501cb0ef41Sopenharmony_ci      if (is_int32(value.to_i64())) {
9511cb0ef41Sopenharmony_ci        // Sign extend low word.
9521cb0ef41Sopenharmony_ci        movq(dst, Immediate(static_cast<int32_t>(value.to_i64())));
9531cb0ef41Sopenharmony_ci      } else if (is_uint32(value.to_i64())) {
9541cb0ef41Sopenharmony_ci        // Zero extend low word.
9551cb0ef41Sopenharmony_ci        movl(kScratchRegister, Immediate(static_cast<int32_t>(value.to_i64())));
9561cb0ef41Sopenharmony_ci        movq(dst, kScratchRegister);
9571cb0ef41Sopenharmony_ci      } else {
9581cb0ef41Sopenharmony_ci        movq(kScratchRegister, value.to_i64());
9591cb0ef41Sopenharmony_ci        movq(dst, kScratchRegister);
9601cb0ef41Sopenharmony_ci      }
9611cb0ef41Sopenharmony_ci      break;
9621cb0ef41Sopenharmony_ci    }
9631cb0ef41Sopenharmony_ci    default:
9641cb0ef41Sopenharmony_ci      // We do not track f32 and f64 constants, hence they are unreachable.
9651cb0ef41Sopenharmony_ci      UNREACHABLE();
9661cb0ef41Sopenharmony_ci  }
9671cb0ef41Sopenharmony_ci}
9681cb0ef41Sopenharmony_ci
9691cb0ef41Sopenharmony_civoid LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
9701cb0ef41Sopenharmony_ci  liftoff::Load(this, reg, liftoff::GetStackSlot(offset), kind);
9711cb0ef41Sopenharmony_ci}
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_civoid LiftoffAssembler::FillI64Half(Register, int offset, RegPairHalf) {
9741cb0ef41Sopenharmony_ci  UNREACHABLE();
9751cb0ef41Sopenharmony_ci}
9761cb0ef41Sopenharmony_ci
9771cb0ef41Sopenharmony_civoid LiftoffAssembler::FillStackSlotsWithZero(int start, int size) {
9781cb0ef41Sopenharmony_ci  DCHECK_LT(0, size);
9791cb0ef41Sopenharmony_ci  RecordUsedSpillOffset(start + size);
9801cb0ef41Sopenharmony_ci
9811cb0ef41Sopenharmony_ci  if (size <= 3 * kStackSlotSize) {
9821cb0ef41Sopenharmony_ci    // Special straight-line code for up to three slots
9831cb0ef41Sopenharmony_ci    // (7-10 bytes per slot: REX C7 <1-4 bytes op> <4 bytes imm>),
9841cb0ef41Sopenharmony_ci    // And a movd (6-9 byte) when size % 8 != 0;
9851cb0ef41Sopenharmony_ci    uint32_t remainder = size;
9861cb0ef41Sopenharmony_ci    for (; remainder >= kStackSlotSize; remainder -= kStackSlotSize) {
9871cb0ef41Sopenharmony_ci      movq(liftoff::GetStackSlot(start + remainder), Immediate(0));
9881cb0ef41Sopenharmony_ci    }
9891cb0ef41Sopenharmony_ci    DCHECK(remainder == 4 || remainder == 0);
9901cb0ef41Sopenharmony_ci    if (remainder) {
9911cb0ef41Sopenharmony_ci      movl(liftoff::GetStackSlot(start + remainder), Immediate(0));
9921cb0ef41Sopenharmony_ci    }
9931cb0ef41Sopenharmony_ci  } else {
9941cb0ef41Sopenharmony_ci    // General case for bigger counts.
9951cb0ef41Sopenharmony_ci    // This sequence takes 19-22 bytes (3 for pushes, 4-7 for lea, 2 for xor, 5
9961cb0ef41Sopenharmony_ci    // for mov, 2 for repstosl, 3 for pops).
9971cb0ef41Sopenharmony_ci    pushq(rax);
9981cb0ef41Sopenharmony_ci    pushq(rcx);
9991cb0ef41Sopenharmony_ci    pushq(rdi);
10001cb0ef41Sopenharmony_ci    leaq(rdi, liftoff::GetStackSlot(start + size));
10011cb0ef41Sopenharmony_ci    xorl(rax, rax);
10021cb0ef41Sopenharmony_ci    // Convert size (bytes) to doublewords (4-bytes).
10031cb0ef41Sopenharmony_ci    movl(rcx, Immediate(size / 4));
10041cb0ef41Sopenharmony_ci    repstosl();
10051cb0ef41Sopenharmony_ci    popq(rdi);
10061cb0ef41Sopenharmony_ci    popq(rcx);
10071cb0ef41Sopenharmony_ci    popq(rax);
10081cb0ef41Sopenharmony_ci  }
10091cb0ef41Sopenharmony_ci}
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {
10121cb0ef41Sopenharmony_ci  if (lhs != dst) {
10131cb0ef41Sopenharmony_ci    leal(dst, Operand(lhs, rhs, times_1, 0));
10141cb0ef41Sopenharmony_ci  } else {
10151cb0ef41Sopenharmony_ci    addl(dst, rhs);
10161cb0ef41Sopenharmony_ci  }
10171cb0ef41Sopenharmony_ci}
10181cb0ef41Sopenharmony_ci
10191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_addi(Register dst, Register lhs, int32_t imm) {
10201cb0ef41Sopenharmony_ci  if (lhs != dst) {
10211cb0ef41Sopenharmony_ci    leal(dst, Operand(lhs, imm));
10221cb0ef41Sopenharmony_ci  } else {
10231cb0ef41Sopenharmony_ci    addl(dst, Immediate(imm));
10241cb0ef41Sopenharmony_ci  }
10251cb0ef41Sopenharmony_ci}
10261cb0ef41Sopenharmony_ci
10271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_sub(Register dst, Register lhs, Register rhs) {
10281cb0ef41Sopenharmony_ci  if (dst != rhs) {
10291cb0ef41Sopenharmony_ci    // Default path.
10301cb0ef41Sopenharmony_ci    if (dst != lhs) movl(dst, lhs);
10311cb0ef41Sopenharmony_ci    subl(dst, rhs);
10321cb0ef41Sopenharmony_ci  } else if (lhs == rhs) {
10331cb0ef41Sopenharmony_ci    // Degenerate case.
10341cb0ef41Sopenharmony_ci    xorl(dst, dst);
10351cb0ef41Sopenharmony_ci  } else {
10361cb0ef41Sopenharmony_ci    // Emit {dst = lhs + -rhs} if dst == rhs.
10371cb0ef41Sopenharmony_ci    negl(dst);
10381cb0ef41Sopenharmony_ci    addl(dst, lhs);
10391cb0ef41Sopenharmony_ci  }
10401cb0ef41Sopenharmony_ci}
10411cb0ef41Sopenharmony_ci
10421cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_subi(Register dst, Register lhs, int32_t imm) {
10431cb0ef41Sopenharmony_ci  if (dst != lhs) {
10441cb0ef41Sopenharmony_ci    // We'll have to implement an UB-safe version if we need this corner case.
10451cb0ef41Sopenharmony_ci    DCHECK_NE(imm, kMinInt);
10461cb0ef41Sopenharmony_ci    leal(dst, Operand(lhs, -imm));
10471cb0ef41Sopenharmony_ci  } else {
10481cb0ef41Sopenharmony_ci    subl(dst, Immediate(imm));
10491cb0ef41Sopenharmony_ci  }
10501cb0ef41Sopenharmony_ci}
10511cb0ef41Sopenharmony_ci
10521cb0ef41Sopenharmony_cinamespace liftoff {
10531cb0ef41Sopenharmony_citemplate <void (Assembler::*op)(Register, Register),
10541cb0ef41Sopenharmony_ci          void (Assembler::*mov)(Register, Register)>
10551cb0ef41Sopenharmony_civoid EmitCommutativeBinOp(LiftoffAssembler* assm, Register dst, Register lhs,
10561cb0ef41Sopenharmony_ci                          Register rhs) {
10571cb0ef41Sopenharmony_ci  if (dst == rhs) {
10581cb0ef41Sopenharmony_ci    (assm->*op)(dst, lhs);
10591cb0ef41Sopenharmony_ci  } else {
10601cb0ef41Sopenharmony_ci    if (dst != lhs) (assm->*mov)(dst, lhs);
10611cb0ef41Sopenharmony_ci    (assm->*op)(dst, rhs);
10621cb0ef41Sopenharmony_ci  }
10631cb0ef41Sopenharmony_ci}
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_citemplate <void (Assembler::*op)(Register, Immediate),
10661cb0ef41Sopenharmony_ci          void (Assembler::*mov)(Register, Register)>
10671cb0ef41Sopenharmony_civoid EmitCommutativeBinOpImm(LiftoffAssembler* assm, Register dst, Register lhs,
10681cb0ef41Sopenharmony_ci                             int32_t imm) {
10691cb0ef41Sopenharmony_ci  if (dst != lhs) (assm->*mov)(dst, lhs);
10701cb0ef41Sopenharmony_ci  (assm->*op)(dst, Immediate(imm));
10711cb0ef41Sopenharmony_ci}
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci}  // namespace liftoff
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_mul(Register dst, Register lhs, Register rhs) {
10761cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::imull, &Assembler::movl>(this, dst,
10771cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
10781cb0ef41Sopenharmony_ci}
10791cb0ef41Sopenharmony_ci
10801cb0ef41Sopenharmony_cinamespace liftoff {
10811cb0ef41Sopenharmony_cienum class DivOrRem : uint8_t { kDiv, kRem };
10821cb0ef41Sopenharmony_citemplate <typename type, DivOrRem div_or_rem>
10831cb0ef41Sopenharmony_civoid EmitIntDivOrRem(LiftoffAssembler* assm, Register dst, Register lhs,
10841cb0ef41Sopenharmony_ci                     Register rhs, Label* trap_div_by_zero,
10851cb0ef41Sopenharmony_ci                     Label* trap_div_unrepresentable) {
10861cb0ef41Sopenharmony_ci  constexpr bool needs_unrepresentable_check =
10871cb0ef41Sopenharmony_ci      std::is_signed<type>::value && div_or_rem == DivOrRem::kDiv;
10881cb0ef41Sopenharmony_ci  constexpr bool special_case_minus_1 =
10891cb0ef41Sopenharmony_ci      std::is_signed<type>::value && div_or_rem == DivOrRem::kRem;
10901cb0ef41Sopenharmony_ci  DCHECK_EQ(needs_unrepresentable_check, trap_div_unrepresentable != nullptr);
10911cb0ef41Sopenharmony_ci
10921cb0ef41Sopenharmony_ci#define iop(name, ...)            \
10931cb0ef41Sopenharmony_ci  do {                            \
10941cb0ef41Sopenharmony_ci    if (sizeof(type) == 4) {      \
10951cb0ef41Sopenharmony_ci      assm->name##l(__VA_ARGS__); \
10961cb0ef41Sopenharmony_ci    } else {                      \
10971cb0ef41Sopenharmony_ci      assm->name##q(__VA_ARGS__); \
10981cb0ef41Sopenharmony_ci    }                             \
10991cb0ef41Sopenharmony_ci  } while (false)
11001cb0ef41Sopenharmony_ci
11011cb0ef41Sopenharmony_ci  // For division, the lhs is always taken from {edx:eax}. Thus, make sure that
11021cb0ef41Sopenharmony_ci  // these registers are unused. If {rhs} is stored in one of them, move it to
11031cb0ef41Sopenharmony_ci  // another temporary register.
11041cb0ef41Sopenharmony_ci  // Do all this before any branch, such that the code is executed
11051cb0ef41Sopenharmony_ci  // unconditionally, as the cache state will also be modified unconditionally.
11061cb0ef41Sopenharmony_ci  assm->SpillRegisters(rdx, rax);
11071cb0ef41Sopenharmony_ci  if (rhs == rax || rhs == rdx) {
11081cb0ef41Sopenharmony_ci    iop(mov, kScratchRegister, rhs);
11091cb0ef41Sopenharmony_ci    rhs = kScratchRegister;
11101cb0ef41Sopenharmony_ci  }
11111cb0ef41Sopenharmony_ci
11121cb0ef41Sopenharmony_ci  // Check for division by zero.
11131cb0ef41Sopenharmony_ci  iop(test, rhs, rhs);
11141cb0ef41Sopenharmony_ci  assm->j(zero, trap_div_by_zero);
11151cb0ef41Sopenharmony_ci
11161cb0ef41Sopenharmony_ci  Label done;
11171cb0ef41Sopenharmony_ci  if (needs_unrepresentable_check) {
11181cb0ef41Sopenharmony_ci    // Check for {kMinInt / -1}. This is unrepresentable.
11191cb0ef41Sopenharmony_ci    Label do_div;
11201cb0ef41Sopenharmony_ci    iop(cmp, rhs, Immediate(-1));
11211cb0ef41Sopenharmony_ci    assm->j(not_equal, &do_div);
11221cb0ef41Sopenharmony_ci    // {lhs} is min int if {lhs - 1} overflows.
11231cb0ef41Sopenharmony_ci    iop(cmp, lhs, Immediate(1));
11241cb0ef41Sopenharmony_ci    assm->j(overflow, trap_div_unrepresentable);
11251cb0ef41Sopenharmony_ci    assm->bind(&do_div);
11261cb0ef41Sopenharmony_ci  } else if (special_case_minus_1) {
11271cb0ef41Sopenharmony_ci    // {lhs % -1} is always 0 (needs to be special cased because {kMinInt / -1}
11281cb0ef41Sopenharmony_ci    // cannot be computed).
11291cb0ef41Sopenharmony_ci    Label do_rem;
11301cb0ef41Sopenharmony_ci    iop(cmp, rhs, Immediate(-1));
11311cb0ef41Sopenharmony_ci    assm->j(not_equal, &do_rem);
11321cb0ef41Sopenharmony_ci    // clang-format off
11331cb0ef41Sopenharmony_ci    // (conflicts with presubmit checks because it is confused about "xor")
11341cb0ef41Sopenharmony_ci    iop(xor, dst, dst);
11351cb0ef41Sopenharmony_ci    // clang-format on
11361cb0ef41Sopenharmony_ci    assm->jmp(&done);
11371cb0ef41Sopenharmony_ci    assm->bind(&do_rem);
11381cb0ef41Sopenharmony_ci  }
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_ci  // Now move {lhs} into {eax}, then zero-extend or sign-extend into {edx}, then
11411cb0ef41Sopenharmony_ci  // do the division.
11421cb0ef41Sopenharmony_ci  if (lhs != rax) iop(mov, rax, lhs);
11431cb0ef41Sopenharmony_ci  if (std::is_same<int32_t, type>::value) {  // i32
11441cb0ef41Sopenharmony_ci    assm->cdq();
11451cb0ef41Sopenharmony_ci    assm->idivl(rhs);
11461cb0ef41Sopenharmony_ci  } else if (std::is_same<uint32_t, type>::value) {  // u32
11471cb0ef41Sopenharmony_ci    assm->xorl(rdx, rdx);
11481cb0ef41Sopenharmony_ci    assm->divl(rhs);
11491cb0ef41Sopenharmony_ci  } else if (std::is_same<int64_t, type>::value) {  // i64
11501cb0ef41Sopenharmony_ci    assm->cqo();
11511cb0ef41Sopenharmony_ci    assm->idivq(rhs);
11521cb0ef41Sopenharmony_ci  } else {  // u64
11531cb0ef41Sopenharmony_ci    assm->xorq(rdx, rdx);
11541cb0ef41Sopenharmony_ci    assm->divq(rhs);
11551cb0ef41Sopenharmony_ci  }
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ci  // Move back the result (in {eax} or {edx}) into the {dst} register.
11581cb0ef41Sopenharmony_ci  constexpr Register kResultReg = div_or_rem == DivOrRem::kDiv ? rax : rdx;
11591cb0ef41Sopenharmony_ci  if (dst != kResultReg) {
11601cb0ef41Sopenharmony_ci    iop(mov, dst, kResultReg);
11611cb0ef41Sopenharmony_ci  }
11621cb0ef41Sopenharmony_ci  if (special_case_minus_1) assm->bind(&done);
11631cb0ef41Sopenharmony_ci}
11641cb0ef41Sopenharmony_ci}  // namespace liftoff
11651cb0ef41Sopenharmony_ci
11661cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_divs(Register dst, Register lhs, Register rhs,
11671cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero,
11681cb0ef41Sopenharmony_ci                                     Label* trap_div_unrepresentable) {
11691cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<int32_t, liftoff::DivOrRem::kDiv>(
11701cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, trap_div_by_zero, trap_div_unrepresentable);
11711cb0ef41Sopenharmony_ci}
11721cb0ef41Sopenharmony_ci
11731cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_divu(Register dst, Register lhs, Register rhs,
11741cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
11751cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<uint32_t, liftoff::DivOrRem::kDiv>(
11761cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, trap_div_by_zero, nullptr);
11771cb0ef41Sopenharmony_ci}
11781cb0ef41Sopenharmony_ci
11791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_rems(Register dst, Register lhs, Register rhs,
11801cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
11811cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<int32_t, liftoff::DivOrRem::kRem>(
11821cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, trap_div_by_zero, nullptr);
11831cb0ef41Sopenharmony_ci}
11841cb0ef41Sopenharmony_ci
11851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
11861cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
11871cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<uint32_t, liftoff::DivOrRem::kRem>(
11881cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, trap_div_by_zero, nullptr);
11891cb0ef41Sopenharmony_ci}
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_and(Register dst, Register lhs, Register rhs) {
11921cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::andl, &Assembler::movl>(this, dst,
11931cb0ef41Sopenharmony_ci                                                                    lhs, rhs);
11941cb0ef41Sopenharmony_ci}
11951cb0ef41Sopenharmony_ci
11961cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_andi(Register dst, Register lhs, int32_t imm) {
11971cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::andl, &Assembler::movl>(
11981cb0ef41Sopenharmony_ci      this, dst, lhs, imm);
11991cb0ef41Sopenharmony_ci}
12001cb0ef41Sopenharmony_ci
12011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_or(Register dst, Register lhs, Register rhs) {
12021cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::orl, &Assembler::movl>(this, dst,
12031cb0ef41Sopenharmony_ci                                                                   lhs, rhs);
12041cb0ef41Sopenharmony_ci}
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_ori(Register dst, Register lhs, int32_t imm) {
12071cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::orl, &Assembler::movl>(this, dst,
12081cb0ef41Sopenharmony_ci                                                                      lhs, imm);
12091cb0ef41Sopenharmony_ci}
12101cb0ef41Sopenharmony_ci
12111cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_xor(Register dst, Register lhs, Register rhs) {
12121cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::xorl, &Assembler::movl>(this, dst,
12131cb0ef41Sopenharmony_ci                                                                    lhs, rhs);
12141cb0ef41Sopenharmony_ci}
12151cb0ef41Sopenharmony_ci
12161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_xori(Register dst, Register lhs, int32_t imm) {
12171cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::xorl, &Assembler::movl>(
12181cb0ef41Sopenharmony_ci      this, dst, lhs, imm);
12191cb0ef41Sopenharmony_ci}
12201cb0ef41Sopenharmony_ci
12211cb0ef41Sopenharmony_cinamespace liftoff {
12221cb0ef41Sopenharmony_citemplate <ValueKind kind>
12231cb0ef41Sopenharmony_ciinline void EmitShiftOperation(LiftoffAssembler* assm, Register dst,
12241cb0ef41Sopenharmony_ci                               Register src, Register amount,
12251cb0ef41Sopenharmony_ci                               void (Assembler::*emit_shift)(Register)) {
12261cb0ef41Sopenharmony_ci  // If dst is rcx, compute into the scratch register first, then move to rcx.
12271cb0ef41Sopenharmony_ci  if (dst == rcx) {
12281cb0ef41Sopenharmony_ci    assm->Move(kScratchRegister, src, kind);
12291cb0ef41Sopenharmony_ci    if (amount != rcx) assm->Move(rcx, amount, kind);
12301cb0ef41Sopenharmony_ci    (assm->*emit_shift)(kScratchRegister);
12311cb0ef41Sopenharmony_ci    assm->Move(rcx, kScratchRegister, kind);
12321cb0ef41Sopenharmony_ci    return;
12331cb0ef41Sopenharmony_ci  }
12341cb0ef41Sopenharmony_ci
12351cb0ef41Sopenharmony_ci  // Move amount into rcx. If rcx is in use, move its content into the scratch
12361cb0ef41Sopenharmony_ci  // register. If src is rcx, src is now the scratch register.
12371cb0ef41Sopenharmony_ci  bool use_scratch = false;
12381cb0ef41Sopenharmony_ci  if (amount != rcx) {
12391cb0ef41Sopenharmony_ci    use_scratch =
12401cb0ef41Sopenharmony_ci        src == rcx || assm->cache_state()->is_used(LiftoffRegister(rcx));
12411cb0ef41Sopenharmony_ci    if (use_scratch) assm->movq(kScratchRegister, rcx);
12421cb0ef41Sopenharmony_ci    if (src == rcx) src = kScratchRegister;
12431cb0ef41Sopenharmony_ci    assm->Move(rcx, amount, kind);
12441cb0ef41Sopenharmony_ci  }
12451cb0ef41Sopenharmony_ci
12461cb0ef41Sopenharmony_ci  // Do the actual shift.
12471cb0ef41Sopenharmony_ci  if (dst != src) assm->Move(dst, src, kind);
12481cb0ef41Sopenharmony_ci  (assm->*emit_shift)(dst);
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci  // Restore rcx if needed.
12511cb0ef41Sopenharmony_ci  if (use_scratch) assm->movq(rcx, kScratchRegister);
12521cb0ef41Sopenharmony_ci}
12531cb0ef41Sopenharmony_ci}  // namespace liftoff
12541cb0ef41Sopenharmony_ci
12551cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_shl(Register dst, Register src,
12561cb0ef41Sopenharmony_ci                                    Register amount) {
12571cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI32>(this, dst, src, amount,
12581cb0ef41Sopenharmony_ci                                    &Assembler::shll_cl);
12591cb0ef41Sopenharmony_ci}
12601cb0ef41Sopenharmony_ci
12611cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_shli(Register dst, Register src,
12621cb0ef41Sopenharmony_ci                                     int32_t amount) {
12631cb0ef41Sopenharmony_ci  if (dst != src) movl(dst, src);
12641cb0ef41Sopenharmony_ci  shll(dst, Immediate(amount & 31));
12651cb0ef41Sopenharmony_ci}
12661cb0ef41Sopenharmony_ci
12671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_sar(Register dst, Register src,
12681cb0ef41Sopenharmony_ci                                    Register amount) {
12691cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI32>(this, dst, src, amount,
12701cb0ef41Sopenharmony_ci                                    &Assembler::sarl_cl);
12711cb0ef41Sopenharmony_ci}
12721cb0ef41Sopenharmony_ci
12731cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_sari(Register dst, Register src,
12741cb0ef41Sopenharmony_ci                                     int32_t amount) {
12751cb0ef41Sopenharmony_ci  if (dst != src) movl(dst, src);
12761cb0ef41Sopenharmony_ci  sarl(dst, Immediate(amount & 31));
12771cb0ef41Sopenharmony_ci}
12781cb0ef41Sopenharmony_ci
12791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_shr(Register dst, Register src,
12801cb0ef41Sopenharmony_ci                                    Register amount) {
12811cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI32>(this, dst, src, amount,
12821cb0ef41Sopenharmony_ci                                    &Assembler::shrl_cl);
12831cb0ef41Sopenharmony_ci}
12841cb0ef41Sopenharmony_ci
12851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_shri(Register dst, Register src,
12861cb0ef41Sopenharmony_ci                                     int32_t amount) {
12871cb0ef41Sopenharmony_ci  if (dst != src) movl(dst, src);
12881cb0ef41Sopenharmony_ci  shrl(dst, Immediate(amount & 31));
12891cb0ef41Sopenharmony_ci}
12901cb0ef41Sopenharmony_ci
12911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
12921cb0ef41Sopenharmony_ci  Lzcntl(dst, src);
12931cb0ef41Sopenharmony_ci}
12941cb0ef41Sopenharmony_ci
12951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
12961cb0ef41Sopenharmony_ci  Tzcntl(dst, src);
12971cb0ef41Sopenharmony_ci}
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i32_popcnt(Register dst, Register src) {
13001cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(POPCNT)) return false;
13011cb0ef41Sopenharmony_ci  CpuFeatureScope scope(this, POPCNT);
13021cb0ef41Sopenharmony_ci  popcntl(dst, src);
13031cb0ef41Sopenharmony_ci  return true;
13041cb0ef41Sopenharmony_ci}
13051cb0ef41Sopenharmony_ci
13061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_add(LiftoffRegister dst, LiftoffRegister lhs,
13071cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
13081cb0ef41Sopenharmony_ci  if (lhs.gp() != dst.gp()) {
13091cb0ef41Sopenharmony_ci    leaq(dst.gp(), Operand(lhs.gp(), rhs.gp(), times_1, 0));
13101cb0ef41Sopenharmony_ci  } else {
13111cb0ef41Sopenharmony_ci    addq(dst.gp(), rhs.gp());
13121cb0ef41Sopenharmony_ci  }
13131cb0ef41Sopenharmony_ci}
13141cb0ef41Sopenharmony_ci
13151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_addi(LiftoffRegister dst, LiftoffRegister lhs,
13161cb0ef41Sopenharmony_ci                                     int64_t imm) {
13171cb0ef41Sopenharmony_ci  if (!is_int32(imm)) {
13181cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchRegister, imm);
13191cb0ef41Sopenharmony_ci    if (lhs.gp() == dst.gp()) {
13201cb0ef41Sopenharmony_ci      addq(dst.gp(), kScratchRegister);
13211cb0ef41Sopenharmony_ci    } else {
13221cb0ef41Sopenharmony_ci      leaq(dst.gp(), Operand(lhs.gp(), kScratchRegister, times_1, 0));
13231cb0ef41Sopenharmony_ci    }
13241cb0ef41Sopenharmony_ci  } else if (lhs.gp() == dst.gp()) {
13251cb0ef41Sopenharmony_ci    addq(dst.gp(), Immediate(static_cast<int32_t>(imm)));
13261cb0ef41Sopenharmony_ci  } else {
13271cb0ef41Sopenharmony_ci    leaq(dst.gp(), Operand(lhs.gp(), static_cast<int32_t>(imm)));
13281cb0ef41Sopenharmony_ci  }
13291cb0ef41Sopenharmony_ci}
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_sub(LiftoffRegister dst, LiftoffRegister lhs,
13321cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
13331cb0ef41Sopenharmony_ci  if (lhs.gp() == rhs.gp()) {
13341cb0ef41Sopenharmony_ci    xorq(dst.gp(), dst.gp());
13351cb0ef41Sopenharmony_ci  } else if (dst.gp() == rhs.gp()) {
13361cb0ef41Sopenharmony_ci    negq(dst.gp());
13371cb0ef41Sopenharmony_ci    addq(dst.gp(), lhs.gp());
13381cb0ef41Sopenharmony_ci  } else {
13391cb0ef41Sopenharmony_ci    if (dst.gp() != lhs.gp()) movq(dst.gp(), lhs.gp());
13401cb0ef41Sopenharmony_ci    subq(dst.gp(), rhs.gp());
13411cb0ef41Sopenharmony_ci  }
13421cb0ef41Sopenharmony_ci}
13431cb0ef41Sopenharmony_ci
13441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_mul(LiftoffRegister dst, LiftoffRegister lhs,
13451cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
13461cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::imulq, &Assembler::movq>(
13471cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp());
13481cb0ef41Sopenharmony_ci}
13491cb0ef41Sopenharmony_ci
13501cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_divs(LiftoffRegister dst, LiftoffRegister lhs,
13511cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13521cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero,
13531cb0ef41Sopenharmony_ci                                     Label* trap_div_unrepresentable) {
13541cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<int64_t, liftoff::DivOrRem::kDiv>(
13551cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp(), trap_div_by_zero,
13561cb0ef41Sopenharmony_ci      trap_div_unrepresentable);
13571cb0ef41Sopenharmony_ci  return true;
13581cb0ef41Sopenharmony_ci}
13591cb0ef41Sopenharmony_ci
13601cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_divu(LiftoffRegister dst, LiftoffRegister lhs,
13611cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13621cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13631cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<uint64_t, liftoff::DivOrRem::kDiv>(
13641cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp(), trap_div_by_zero, nullptr);
13651cb0ef41Sopenharmony_ci  return true;
13661cb0ef41Sopenharmony_ci}
13671cb0ef41Sopenharmony_ci
13681cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_rems(LiftoffRegister dst, LiftoffRegister lhs,
13691cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13701cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13711cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<int64_t, liftoff::DivOrRem::kRem>(
13721cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp(), trap_div_by_zero, nullptr);
13731cb0ef41Sopenharmony_ci  return true;
13741cb0ef41Sopenharmony_ci}
13751cb0ef41Sopenharmony_ci
13761cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
13771cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs,
13781cb0ef41Sopenharmony_ci                                     Label* trap_div_by_zero) {
13791cb0ef41Sopenharmony_ci  liftoff::EmitIntDivOrRem<uint64_t, liftoff::DivOrRem::kRem>(
13801cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp(), trap_div_by_zero, nullptr);
13811cb0ef41Sopenharmony_ci  return true;
13821cb0ef41Sopenharmony_ci}
13831cb0ef41Sopenharmony_ci
13841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_and(LiftoffRegister dst, LiftoffRegister lhs,
13851cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
13861cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::andq, &Assembler::movq>(
13871cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp());
13881cb0ef41Sopenharmony_ci}
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_andi(LiftoffRegister dst, LiftoffRegister lhs,
13911cb0ef41Sopenharmony_ci                                     int32_t imm) {
13921cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::andq, &Assembler::movq>(
13931cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), imm);
13941cb0ef41Sopenharmony_ci}
13951cb0ef41Sopenharmony_ci
13961cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_or(LiftoffRegister dst, LiftoffRegister lhs,
13971cb0ef41Sopenharmony_ci                                   LiftoffRegister rhs) {
13981cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::orq, &Assembler::movq>(
13991cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp());
14001cb0ef41Sopenharmony_ci}
14011cb0ef41Sopenharmony_ci
14021cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_ori(LiftoffRegister dst, LiftoffRegister lhs,
14031cb0ef41Sopenharmony_ci                                    int32_t imm) {
14041cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::orq, &Assembler::movq>(
14051cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), imm);
14061cb0ef41Sopenharmony_ci}
14071cb0ef41Sopenharmony_ci
14081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_xor(LiftoffRegister dst, LiftoffRegister lhs,
14091cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
14101cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOp<&Assembler::xorq, &Assembler::movq>(
14111cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), rhs.gp());
14121cb0ef41Sopenharmony_ci}
14131cb0ef41Sopenharmony_ci
14141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_xori(LiftoffRegister dst, LiftoffRegister lhs,
14151cb0ef41Sopenharmony_ci                                     int32_t imm) {
14161cb0ef41Sopenharmony_ci  liftoff::EmitCommutativeBinOpImm<&Assembler::xorq, &Assembler::movq>(
14171cb0ef41Sopenharmony_ci      this, dst.gp(), lhs.gp(), imm);
14181cb0ef41Sopenharmony_ci}
14191cb0ef41Sopenharmony_ci
14201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_shl(LiftoffRegister dst, LiftoffRegister src,
14211cb0ef41Sopenharmony_ci                                    Register amount) {
14221cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI64>(this, dst.gp(), src.gp(), amount,
14231cb0ef41Sopenharmony_ci                                    &Assembler::shlq_cl);
14241cb0ef41Sopenharmony_ci}
14251cb0ef41Sopenharmony_ci
14261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_shli(LiftoffRegister dst, LiftoffRegister src,
14271cb0ef41Sopenharmony_ci                                     int32_t amount) {
14281cb0ef41Sopenharmony_ci  if (dst.gp() != src.gp()) movq(dst.gp(), src.gp());
14291cb0ef41Sopenharmony_ci  shlq(dst.gp(), Immediate(amount & 63));
14301cb0ef41Sopenharmony_ci}
14311cb0ef41Sopenharmony_ci
14321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_sar(LiftoffRegister dst, LiftoffRegister src,
14331cb0ef41Sopenharmony_ci                                    Register amount) {
14341cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI64>(this, dst.gp(), src.gp(), amount,
14351cb0ef41Sopenharmony_ci                                    &Assembler::sarq_cl);
14361cb0ef41Sopenharmony_ci}
14371cb0ef41Sopenharmony_ci
14381cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_sari(LiftoffRegister dst, LiftoffRegister src,
14391cb0ef41Sopenharmony_ci                                     int32_t amount) {
14401cb0ef41Sopenharmony_ci  if (dst.gp() != src.gp()) movq(dst.gp(), src.gp());
14411cb0ef41Sopenharmony_ci  sarq(dst.gp(), Immediate(amount & 63));
14421cb0ef41Sopenharmony_ci}
14431cb0ef41Sopenharmony_ci
14441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
14451cb0ef41Sopenharmony_ci                                    Register amount) {
14461cb0ef41Sopenharmony_ci  liftoff::EmitShiftOperation<kI64>(this, dst.gp(), src.gp(), amount,
14471cb0ef41Sopenharmony_ci                                    &Assembler::shrq_cl);
14481cb0ef41Sopenharmony_ci}
14491cb0ef41Sopenharmony_ci
14501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_shri(LiftoffRegister dst, LiftoffRegister src,
14511cb0ef41Sopenharmony_ci                                     int32_t amount) {
14521cb0ef41Sopenharmony_ci  if (dst != src) movq(dst.gp(), src.gp());
14531cb0ef41Sopenharmony_ci  shrq(dst.gp(), Immediate(amount & 63));
14541cb0ef41Sopenharmony_ci}
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_clz(LiftoffRegister dst, LiftoffRegister src) {
14571cb0ef41Sopenharmony_ci  Lzcntq(dst.gp(), src.gp());
14581cb0ef41Sopenharmony_ci}
14591cb0ef41Sopenharmony_ci
14601cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) {
14611cb0ef41Sopenharmony_ci  Tzcntq(dst.gp(), src.gp());
14621cb0ef41Sopenharmony_ci}
14631cb0ef41Sopenharmony_ci
14641cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst,
14651cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
14661cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(POPCNT)) return false;
14671cb0ef41Sopenharmony_ci  CpuFeatureScope scope(this, POPCNT);
14681cb0ef41Sopenharmony_ci  popcntq(dst.gp(), src.gp());
14691cb0ef41Sopenharmony_ci  return true;
14701cb0ef41Sopenharmony_ci}
14711cb0ef41Sopenharmony_ci
14721cb0ef41Sopenharmony_civoid LiftoffAssembler::IncrementSmi(LiftoffRegister dst, int offset) {
14731cb0ef41Sopenharmony_ci  SmiAddConstant(Operand(dst.gp(), offset), Smi::FromInt(1));
14741cb0ef41Sopenharmony_ci}
14751cb0ef41Sopenharmony_ci
14761cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_u32_to_uintptr(Register dst, Register src) {
14771cb0ef41Sopenharmony_ci  movl(dst, src);
14781cb0ef41Sopenharmony_ci}
14791cb0ef41Sopenharmony_ci
14801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
14811cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
14821cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
14831cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
14841cb0ef41Sopenharmony_ci    vaddss(dst, lhs, rhs);
14851cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
14861cb0ef41Sopenharmony_ci    addss(dst, lhs);
14871cb0ef41Sopenharmony_ci  } else {
14881cb0ef41Sopenharmony_ci    if (dst != lhs) movss(dst, lhs);
14891cb0ef41Sopenharmony_ci    addss(dst, rhs);
14901cb0ef41Sopenharmony_ci  }
14911cb0ef41Sopenharmony_ci}
14921cb0ef41Sopenharmony_ci
14931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
14941cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
14951cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
14961cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
14971cb0ef41Sopenharmony_ci    vsubss(dst, lhs, rhs);
14981cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
14991cb0ef41Sopenharmony_ci    movss(kScratchDoubleReg, rhs);
15001cb0ef41Sopenharmony_ci    movss(dst, lhs);
15011cb0ef41Sopenharmony_ci    subss(dst, kScratchDoubleReg);
15021cb0ef41Sopenharmony_ci  } else {
15031cb0ef41Sopenharmony_ci    if (dst != lhs) movss(dst, lhs);
15041cb0ef41Sopenharmony_ci    subss(dst, rhs);
15051cb0ef41Sopenharmony_ci  }
15061cb0ef41Sopenharmony_ci}
15071cb0ef41Sopenharmony_ci
15081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
15091cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
15101cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
15111cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
15121cb0ef41Sopenharmony_ci    vmulss(dst, lhs, rhs);
15131cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
15141cb0ef41Sopenharmony_ci    mulss(dst, lhs);
15151cb0ef41Sopenharmony_ci  } else {
15161cb0ef41Sopenharmony_ci    if (dst != lhs) movss(dst, lhs);
15171cb0ef41Sopenharmony_ci    mulss(dst, rhs);
15181cb0ef41Sopenharmony_ci  }
15191cb0ef41Sopenharmony_ci}
15201cb0ef41Sopenharmony_ci
15211cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_div(DoubleRegister dst, DoubleRegister lhs,
15221cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
15231cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
15241cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
15251cb0ef41Sopenharmony_ci    vdivss(dst, lhs, rhs);
15261cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
15271cb0ef41Sopenharmony_ci    movss(kScratchDoubleReg, rhs);
15281cb0ef41Sopenharmony_ci    movss(dst, lhs);
15291cb0ef41Sopenharmony_ci    divss(dst, kScratchDoubleReg);
15301cb0ef41Sopenharmony_ci  } else {
15311cb0ef41Sopenharmony_ci    if (dst != lhs) movss(dst, lhs);
15321cb0ef41Sopenharmony_ci    divss(dst, rhs);
15331cb0ef41Sopenharmony_ci  }
15341cb0ef41Sopenharmony_ci}
15351cb0ef41Sopenharmony_ci
15361cb0ef41Sopenharmony_cinamespace liftoff {
15371cb0ef41Sopenharmony_cienum class MinOrMax : uint8_t { kMin, kMax };
15381cb0ef41Sopenharmony_citemplate <typename type>
15391cb0ef41Sopenharmony_ciinline void EmitFloatMinOrMax(LiftoffAssembler* assm, DoubleRegister dst,
15401cb0ef41Sopenharmony_ci                              DoubleRegister lhs, DoubleRegister rhs,
15411cb0ef41Sopenharmony_ci                              MinOrMax min_or_max) {
15421cb0ef41Sopenharmony_ci  Label is_nan;
15431cb0ef41Sopenharmony_ci  Label lhs_below_rhs;
15441cb0ef41Sopenharmony_ci  Label lhs_above_rhs;
15451cb0ef41Sopenharmony_ci  Label done;
15461cb0ef41Sopenharmony_ci
15471cb0ef41Sopenharmony_ci#define dop(name, ...)            \
15481cb0ef41Sopenharmony_ci  do {                            \
15491cb0ef41Sopenharmony_ci    if (sizeof(type) == 4) {      \
15501cb0ef41Sopenharmony_ci      assm->name##s(__VA_ARGS__); \
15511cb0ef41Sopenharmony_ci    } else {                      \
15521cb0ef41Sopenharmony_ci      assm->name##d(__VA_ARGS__); \
15531cb0ef41Sopenharmony_ci    }                             \
15541cb0ef41Sopenharmony_ci  } while (false)
15551cb0ef41Sopenharmony_ci
15561cb0ef41Sopenharmony_ci  // Check the easy cases first: nan (e.g. unordered), smaller and greater.
15571cb0ef41Sopenharmony_ci  // NaN has to be checked first, because PF=1 implies CF=1.
15581cb0ef41Sopenharmony_ci  dop(Ucomis, lhs, rhs);
15591cb0ef41Sopenharmony_ci  assm->j(parity_even, &is_nan, Label::kNear);   // PF=1
15601cb0ef41Sopenharmony_ci  assm->j(below, &lhs_below_rhs, Label::kNear);  // CF=1
15611cb0ef41Sopenharmony_ci  assm->j(above, &lhs_above_rhs, Label::kNear);  // CF=0 && ZF=0
15621cb0ef41Sopenharmony_ci
15631cb0ef41Sopenharmony_ci  // If we get here, then either
15641cb0ef41Sopenharmony_ci  // a) {lhs == rhs},
15651cb0ef41Sopenharmony_ci  // b) {lhs == -0.0} and {rhs == 0.0}, or
15661cb0ef41Sopenharmony_ci  // c) {lhs == 0.0} and {rhs == -0.0}.
15671cb0ef41Sopenharmony_ci  // For a), it does not matter whether we return {lhs} or {rhs}. Check the sign
15681cb0ef41Sopenharmony_ci  // bit of {rhs} to differentiate b) and c).
15691cb0ef41Sopenharmony_ci  dop(Movmskp, kScratchRegister, rhs);
15701cb0ef41Sopenharmony_ci  assm->testl(kScratchRegister, Immediate(1));
15711cb0ef41Sopenharmony_ci  assm->j(zero, &lhs_below_rhs, Label::kNear);
15721cb0ef41Sopenharmony_ci  assm->jmp(&lhs_above_rhs, Label::kNear);
15731cb0ef41Sopenharmony_ci
15741cb0ef41Sopenharmony_ci  assm->bind(&is_nan);
15751cb0ef41Sopenharmony_ci  // Create a NaN output.
15761cb0ef41Sopenharmony_ci  dop(Xorp, dst, dst);
15771cb0ef41Sopenharmony_ci  dop(Divs, dst, dst);
15781cb0ef41Sopenharmony_ci  assm->jmp(&done, Label::kNear);
15791cb0ef41Sopenharmony_ci
15801cb0ef41Sopenharmony_ci  assm->bind(&lhs_below_rhs);
15811cb0ef41Sopenharmony_ci  DoubleRegister lhs_below_rhs_src = min_or_max == MinOrMax::kMin ? lhs : rhs;
15821cb0ef41Sopenharmony_ci  if (dst != lhs_below_rhs_src) dop(Movs, dst, lhs_below_rhs_src);
15831cb0ef41Sopenharmony_ci  assm->jmp(&done, Label::kNear);
15841cb0ef41Sopenharmony_ci
15851cb0ef41Sopenharmony_ci  assm->bind(&lhs_above_rhs);
15861cb0ef41Sopenharmony_ci  DoubleRegister lhs_above_rhs_src = min_or_max == MinOrMax::kMin ? rhs : lhs;
15871cb0ef41Sopenharmony_ci  if (dst != lhs_above_rhs_src) dop(Movs, dst, lhs_above_rhs_src);
15881cb0ef41Sopenharmony_ci
15891cb0ef41Sopenharmony_ci  assm->bind(&done);
15901cb0ef41Sopenharmony_ci}
15911cb0ef41Sopenharmony_ci}  // namespace liftoff
15921cb0ef41Sopenharmony_ci
15931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_min(DoubleRegister dst, DoubleRegister lhs,
15941cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
15951cb0ef41Sopenharmony_ci  liftoff::EmitFloatMinOrMax<float>(this, dst, lhs, rhs,
15961cb0ef41Sopenharmony_ci                                    liftoff::MinOrMax::kMin);
15971cb0ef41Sopenharmony_ci}
15981cb0ef41Sopenharmony_ci
15991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_max(DoubleRegister dst, DoubleRegister lhs,
16001cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
16011cb0ef41Sopenharmony_ci  liftoff::EmitFloatMinOrMax<float>(this, dst, lhs, rhs,
16021cb0ef41Sopenharmony_ci                                    liftoff::MinOrMax::kMax);
16031cb0ef41Sopenharmony_ci}
16041cb0ef41Sopenharmony_ci
16051cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_copysign(DoubleRegister dst, DoubleRegister lhs,
16061cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
16071cb0ef41Sopenharmony_ci  static constexpr int kF32SignBit = 1 << 31;
16081cb0ef41Sopenharmony_ci  Movd(kScratchRegister, lhs);
16091cb0ef41Sopenharmony_ci  andl(kScratchRegister, Immediate(~kF32SignBit));
16101cb0ef41Sopenharmony_ci  Movd(liftoff::kScratchRegister2, rhs);
16111cb0ef41Sopenharmony_ci  andl(liftoff::kScratchRegister2, Immediate(kF32SignBit));
16121cb0ef41Sopenharmony_ci  orl(kScratchRegister, liftoff::kScratchRegister2);
16131cb0ef41Sopenharmony_ci  Movd(dst, kScratchRegister);
16141cb0ef41Sopenharmony_ci}
16151cb0ef41Sopenharmony_ci
16161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_abs(DoubleRegister dst, DoubleRegister src) {
16171cb0ef41Sopenharmony_ci  static constexpr uint32_t kSignBit = uint32_t{1} << 31;
16181cb0ef41Sopenharmony_ci  if (dst == src) {
16191cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchDoubleReg, kSignBit - 1);
16201cb0ef41Sopenharmony_ci    Andps(dst, kScratchDoubleReg);
16211cb0ef41Sopenharmony_ci  } else {
16221cb0ef41Sopenharmony_ci    TurboAssembler::Move(dst, kSignBit - 1);
16231cb0ef41Sopenharmony_ci    Andps(dst, src);
16241cb0ef41Sopenharmony_ci  }
16251cb0ef41Sopenharmony_ci}
16261cb0ef41Sopenharmony_ci
16271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_neg(DoubleRegister dst, DoubleRegister src) {
16281cb0ef41Sopenharmony_ci  static constexpr uint32_t kSignBit = uint32_t{1} << 31;
16291cb0ef41Sopenharmony_ci  if (dst == src) {
16301cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchDoubleReg, kSignBit);
16311cb0ef41Sopenharmony_ci    Xorps(dst, kScratchDoubleReg);
16321cb0ef41Sopenharmony_ci  } else {
16331cb0ef41Sopenharmony_ci    TurboAssembler::Move(dst, kSignBit);
16341cb0ef41Sopenharmony_ci    Xorps(dst, src);
16351cb0ef41Sopenharmony_ci  }
16361cb0ef41Sopenharmony_ci}
16371cb0ef41Sopenharmony_ci
16381cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32_ceil(DoubleRegister dst, DoubleRegister src) {
16391cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
16401cb0ef41Sopenharmony_ci  Roundss(dst, src, kRoundUp);
16411cb0ef41Sopenharmony_ci  return true;
16421cb0ef41Sopenharmony_ci}
16431cb0ef41Sopenharmony_ci
16441cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32_floor(DoubleRegister dst, DoubleRegister src) {
16451cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
16461cb0ef41Sopenharmony_ci  Roundss(dst, src, kRoundDown);
16471cb0ef41Sopenharmony_ci  return true;
16481cb0ef41Sopenharmony_ci}
16491cb0ef41Sopenharmony_ci
16501cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32_trunc(DoubleRegister dst, DoubleRegister src) {
16511cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
16521cb0ef41Sopenharmony_ci  Roundss(dst, src, kRoundToZero);
16531cb0ef41Sopenharmony_ci  return true;
16541cb0ef41Sopenharmony_ci}
16551cb0ef41Sopenharmony_ci
16561cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32_nearest_int(DoubleRegister dst,
16571cb0ef41Sopenharmony_ci                                            DoubleRegister src) {
16581cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
16591cb0ef41Sopenharmony_ci  Roundss(dst, src, kRoundToNearest);
16601cb0ef41Sopenharmony_ci  return true;
16611cb0ef41Sopenharmony_ci}
16621cb0ef41Sopenharmony_ci
16631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_sqrt(DoubleRegister dst, DoubleRegister src) {
16641cb0ef41Sopenharmony_ci  Sqrtss(dst, src);
16651cb0ef41Sopenharmony_ci}
16661cb0ef41Sopenharmony_ci
16671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_add(DoubleRegister dst, DoubleRegister lhs,
16681cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
16691cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
16701cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
16711cb0ef41Sopenharmony_ci    vaddsd(dst, lhs, rhs);
16721cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
16731cb0ef41Sopenharmony_ci    addsd(dst, lhs);
16741cb0ef41Sopenharmony_ci  } else {
16751cb0ef41Sopenharmony_ci    if (dst != lhs) movsd(dst, lhs);
16761cb0ef41Sopenharmony_ci    addsd(dst, rhs);
16771cb0ef41Sopenharmony_ci  }
16781cb0ef41Sopenharmony_ci}
16791cb0ef41Sopenharmony_ci
16801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_sub(DoubleRegister dst, DoubleRegister lhs,
16811cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
16821cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
16831cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
16841cb0ef41Sopenharmony_ci    vsubsd(dst, lhs, rhs);
16851cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
16861cb0ef41Sopenharmony_ci    movsd(kScratchDoubleReg, rhs);
16871cb0ef41Sopenharmony_ci    movsd(dst, lhs);
16881cb0ef41Sopenharmony_ci    subsd(dst, kScratchDoubleReg);
16891cb0ef41Sopenharmony_ci  } else {
16901cb0ef41Sopenharmony_ci    if (dst != lhs) movsd(dst, lhs);
16911cb0ef41Sopenharmony_ci    subsd(dst, rhs);
16921cb0ef41Sopenharmony_ci  }
16931cb0ef41Sopenharmony_ci}
16941cb0ef41Sopenharmony_ci
16951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
16961cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
16971cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
16981cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
16991cb0ef41Sopenharmony_ci    vmulsd(dst, lhs, rhs);
17001cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
17011cb0ef41Sopenharmony_ci    mulsd(dst, lhs);
17021cb0ef41Sopenharmony_ci  } else {
17031cb0ef41Sopenharmony_ci    if (dst != lhs) movsd(dst, lhs);
17041cb0ef41Sopenharmony_ci    mulsd(dst, rhs);
17051cb0ef41Sopenharmony_ci  }
17061cb0ef41Sopenharmony_ci}
17071cb0ef41Sopenharmony_ci
17081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_div(DoubleRegister dst, DoubleRegister lhs,
17091cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
17101cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
17111cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
17121cb0ef41Sopenharmony_ci    vdivsd(dst, lhs, rhs);
17131cb0ef41Sopenharmony_ci  } else if (dst == rhs) {
17141cb0ef41Sopenharmony_ci    movsd(kScratchDoubleReg, rhs);
17151cb0ef41Sopenharmony_ci    movsd(dst, lhs);
17161cb0ef41Sopenharmony_ci    divsd(dst, kScratchDoubleReg);
17171cb0ef41Sopenharmony_ci  } else {
17181cb0ef41Sopenharmony_ci    if (dst != lhs) movsd(dst, lhs);
17191cb0ef41Sopenharmony_ci    divsd(dst, rhs);
17201cb0ef41Sopenharmony_ci  }
17211cb0ef41Sopenharmony_ci}
17221cb0ef41Sopenharmony_ci
17231cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_min(DoubleRegister dst, DoubleRegister lhs,
17241cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
17251cb0ef41Sopenharmony_ci  liftoff::EmitFloatMinOrMax<double>(this, dst, lhs, rhs,
17261cb0ef41Sopenharmony_ci                                     liftoff::MinOrMax::kMin);
17271cb0ef41Sopenharmony_ci}
17281cb0ef41Sopenharmony_ci
17291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_copysign(DoubleRegister dst, DoubleRegister lhs,
17301cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
17311cb0ef41Sopenharmony_ci  // Extract sign bit from {rhs} into {kScratchRegister2}.
17321cb0ef41Sopenharmony_ci  Movq(liftoff::kScratchRegister2, rhs);
17331cb0ef41Sopenharmony_ci  shrq(liftoff::kScratchRegister2, Immediate(63));
17341cb0ef41Sopenharmony_ci  shlq(liftoff::kScratchRegister2, Immediate(63));
17351cb0ef41Sopenharmony_ci  // Reset sign bit of {lhs} (in {kScratchRegister}).
17361cb0ef41Sopenharmony_ci  Movq(kScratchRegister, lhs);
17371cb0ef41Sopenharmony_ci  btrq(kScratchRegister, Immediate(63));
17381cb0ef41Sopenharmony_ci  // Combine both values into {kScratchRegister} and move into {dst}.
17391cb0ef41Sopenharmony_ci  orq(kScratchRegister, liftoff::kScratchRegister2);
17401cb0ef41Sopenharmony_ci  Movq(dst, kScratchRegister);
17411cb0ef41Sopenharmony_ci}
17421cb0ef41Sopenharmony_ci
17431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_max(DoubleRegister dst, DoubleRegister lhs,
17441cb0ef41Sopenharmony_ci                                    DoubleRegister rhs) {
17451cb0ef41Sopenharmony_ci  liftoff::EmitFloatMinOrMax<double>(this, dst, lhs, rhs,
17461cb0ef41Sopenharmony_ci                                     liftoff::MinOrMax::kMax);
17471cb0ef41Sopenharmony_ci}
17481cb0ef41Sopenharmony_ci
17491cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_abs(DoubleRegister dst, DoubleRegister src) {
17501cb0ef41Sopenharmony_ci  static constexpr uint64_t kSignBit = uint64_t{1} << 63;
17511cb0ef41Sopenharmony_ci  if (dst == src) {
17521cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchDoubleReg, kSignBit - 1);
17531cb0ef41Sopenharmony_ci    Andpd(dst, kScratchDoubleReg);
17541cb0ef41Sopenharmony_ci  } else {
17551cb0ef41Sopenharmony_ci    TurboAssembler::Move(dst, kSignBit - 1);
17561cb0ef41Sopenharmony_ci    Andpd(dst, src);
17571cb0ef41Sopenharmony_ci  }
17581cb0ef41Sopenharmony_ci}
17591cb0ef41Sopenharmony_ci
17601cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_neg(DoubleRegister dst, DoubleRegister src) {
17611cb0ef41Sopenharmony_ci  static constexpr uint64_t kSignBit = uint64_t{1} << 63;
17621cb0ef41Sopenharmony_ci  if (dst == src) {
17631cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchDoubleReg, kSignBit);
17641cb0ef41Sopenharmony_ci    Xorpd(dst, kScratchDoubleReg);
17651cb0ef41Sopenharmony_ci  } else {
17661cb0ef41Sopenharmony_ci    TurboAssembler::Move(dst, kSignBit);
17671cb0ef41Sopenharmony_ci    Xorpd(dst, src);
17681cb0ef41Sopenharmony_ci  }
17691cb0ef41Sopenharmony_ci}
17701cb0ef41Sopenharmony_ci
17711cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64_ceil(DoubleRegister dst, DoubleRegister src) {
17721cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
17731cb0ef41Sopenharmony_ci  Roundsd(dst, src, kRoundUp);
17741cb0ef41Sopenharmony_ci  return true;
17751cb0ef41Sopenharmony_ci}
17761cb0ef41Sopenharmony_ci
17771cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64_floor(DoubleRegister dst, DoubleRegister src) {
17781cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
17791cb0ef41Sopenharmony_ci  Roundsd(dst, src, kRoundDown);
17801cb0ef41Sopenharmony_ci  return true;
17811cb0ef41Sopenharmony_ci}
17821cb0ef41Sopenharmony_ci
17831cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64_trunc(DoubleRegister dst, DoubleRegister src) {
17841cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
17851cb0ef41Sopenharmony_ci  Roundsd(dst, src, kRoundToZero);
17861cb0ef41Sopenharmony_ci  return true;
17871cb0ef41Sopenharmony_ci}
17881cb0ef41Sopenharmony_ci
17891cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64_nearest_int(DoubleRegister dst,
17901cb0ef41Sopenharmony_ci                                            DoubleRegister src) {
17911cb0ef41Sopenharmony_ci  RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
17921cb0ef41Sopenharmony_ci  Roundsd(dst, src, kRoundToNearest);
17931cb0ef41Sopenharmony_ci  return true;
17941cb0ef41Sopenharmony_ci}
17951cb0ef41Sopenharmony_ci
17961cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_sqrt(DoubleRegister dst, DoubleRegister src) {
17971cb0ef41Sopenharmony_ci  Sqrtsd(dst, src);
17981cb0ef41Sopenharmony_ci}
17991cb0ef41Sopenharmony_ci
18001cb0ef41Sopenharmony_cinamespace liftoff {
18011cb0ef41Sopenharmony_ci#define __ assm->
18021cb0ef41Sopenharmony_ci// Used for float to int conversions. If the value in {converted_back} equals
18031cb0ef41Sopenharmony_ci// {src} afterwards, the conversion succeeded.
18041cb0ef41Sopenharmony_citemplate <typename dst_type, typename src_type>
18051cb0ef41Sopenharmony_ciinline void ConvertFloatToIntAndBack(LiftoffAssembler* assm, Register dst,
18061cb0ef41Sopenharmony_ci                                     DoubleRegister src,
18071cb0ef41Sopenharmony_ci                                     DoubleRegister converted_back) {
18081cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
18091cb0ef41Sopenharmony_ci    if (std::is_same<int32_t, dst_type>::value) {  // f64 -> i32
18101cb0ef41Sopenharmony_ci      __ Cvttsd2si(dst, src);
18111cb0ef41Sopenharmony_ci      __ Cvtlsi2sd(converted_back, dst);
18121cb0ef41Sopenharmony_ci    } else if (std::is_same<uint32_t, dst_type>::value) {  // f64 -> u32
18131cb0ef41Sopenharmony_ci      __ Cvttsd2siq(dst, src);
18141cb0ef41Sopenharmony_ci      __ movl(dst, dst);
18151cb0ef41Sopenharmony_ci      __ Cvtqsi2sd(converted_back, dst);
18161cb0ef41Sopenharmony_ci    } else if (std::is_same<int64_t, dst_type>::value) {  // f64 -> i64
18171cb0ef41Sopenharmony_ci      __ Cvttsd2siq(dst, src);
18181cb0ef41Sopenharmony_ci      __ Cvtqsi2sd(converted_back, dst);
18191cb0ef41Sopenharmony_ci    } else {
18201cb0ef41Sopenharmony_ci      UNREACHABLE();
18211cb0ef41Sopenharmony_ci    }
18221cb0ef41Sopenharmony_ci  } else {                                  // f32
18231cb0ef41Sopenharmony_ci    if (std::is_same<int32_t, dst_type>::value) {  // f32 -> i32
18241cb0ef41Sopenharmony_ci      __ Cvttss2si(dst, src);
18251cb0ef41Sopenharmony_ci      __ Cvtlsi2ss(converted_back, dst);
18261cb0ef41Sopenharmony_ci    } else if (std::is_same<uint32_t, dst_type>::value) {  // f32 -> u32
18271cb0ef41Sopenharmony_ci      __ Cvttss2siq(dst, src);
18281cb0ef41Sopenharmony_ci      __ movl(dst, dst);
18291cb0ef41Sopenharmony_ci      __ Cvtqsi2ss(converted_back, dst);
18301cb0ef41Sopenharmony_ci    } else if (std::is_same<int64_t, dst_type>::value) {  // f32 -> i64
18311cb0ef41Sopenharmony_ci      __ Cvttss2siq(dst, src);
18321cb0ef41Sopenharmony_ci      __ Cvtqsi2ss(converted_back, dst);
18331cb0ef41Sopenharmony_ci    } else {
18341cb0ef41Sopenharmony_ci      UNREACHABLE();
18351cb0ef41Sopenharmony_ci    }
18361cb0ef41Sopenharmony_ci  }
18371cb0ef41Sopenharmony_ci}
18381cb0ef41Sopenharmony_ci
18391cb0ef41Sopenharmony_citemplate <typename dst_type, typename src_type>
18401cb0ef41Sopenharmony_ciinline bool EmitTruncateFloatToInt(LiftoffAssembler* assm, Register dst,
18411cb0ef41Sopenharmony_ci                                   DoubleRegister src, Label* trap) {
18421cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(SSE4_1)) {
18431cb0ef41Sopenharmony_ci    __ bailout(kMissingCPUFeature, "no SSE4.1");
18441cb0ef41Sopenharmony_ci    return true;
18451cb0ef41Sopenharmony_ci  }
18461cb0ef41Sopenharmony_ci  CpuFeatureScope feature(assm, SSE4_1);
18471cb0ef41Sopenharmony_ci
18481cb0ef41Sopenharmony_ci  DoubleRegister rounded = kScratchDoubleReg;
18491cb0ef41Sopenharmony_ci  DoubleRegister converted_back = kScratchDoubleReg2;
18501cb0ef41Sopenharmony_ci
18511cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
18521cb0ef41Sopenharmony_ci    __ Roundsd(rounded, src, kRoundToZero);
18531cb0ef41Sopenharmony_ci  } else {  // f32
18541cb0ef41Sopenharmony_ci    __ Roundss(rounded, src, kRoundToZero);
18551cb0ef41Sopenharmony_ci  }
18561cb0ef41Sopenharmony_ci  ConvertFloatToIntAndBack<dst_type, src_type>(assm, dst, rounded,
18571cb0ef41Sopenharmony_ci                                               converted_back);
18581cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
18591cb0ef41Sopenharmony_ci    __ Ucomisd(converted_back, rounded);
18601cb0ef41Sopenharmony_ci  } else {  // f32
18611cb0ef41Sopenharmony_ci    __ Ucomiss(converted_back, rounded);
18621cb0ef41Sopenharmony_ci  }
18631cb0ef41Sopenharmony_ci
18641cb0ef41Sopenharmony_ci  // Jump to trap if PF is 0 (one of the operands was NaN) or they are not
18651cb0ef41Sopenharmony_ci  // equal.
18661cb0ef41Sopenharmony_ci  __ j(parity_even, trap);
18671cb0ef41Sopenharmony_ci  __ j(not_equal, trap);
18681cb0ef41Sopenharmony_ci  return true;
18691cb0ef41Sopenharmony_ci}
18701cb0ef41Sopenharmony_ci
18711cb0ef41Sopenharmony_citemplate <typename dst_type, typename src_type>
18721cb0ef41Sopenharmony_ciinline bool EmitSatTruncateFloatToInt(LiftoffAssembler* assm, Register dst,
18731cb0ef41Sopenharmony_ci                                      DoubleRegister src) {
18741cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(SSE4_1)) {
18751cb0ef41Sopenharmony_ci    __ bailout(kMissingCPUFeature, "no SSE4.1");
18761cb0ef41Sopenharmony_ci    return true;
18771cb0ef41Sopenharmony_ci  }
18781cb0ef41Sopenharmony_ci  CpuFeatureScope feature(assm, SSE4_1);
18791cb0ef41Sopenharmony_ci
18801cb0ef41Sopenharmony_ci  Label done;
18811cb0ef41Sopenharmony_ci  Label not_nan;
18821cb0ef41Sopenharmony_ci  Label src_positive;
18831cb0ef41Sopenharmony_ci
18841cb0ef41Sopenharmony_ci  DoubleRegister rounded = kScratchDoubleReg;
18851cb0ef41Sopenharmony_ci  DoubleRegister converted_back = kScratchDoubleReg2;
18861cb0ef41Sopenharmony_ci  DoubleRegister zero_reg = kScratchDoubleReg;
18871cb0ef41Sopenharmony_ci
18881cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
18891cb0ef41Sopenharmony_ci    __ Roundsd(rounded, src, kRoundToZero);
18901cb0ef41Sopenharmony_ci  } else {  // f32
18911cb0ef41Sopenharmony_ci    __ Roundss(rounded, src, kRoundToZero);
18921cb0ef41Sopenharmony_ci  }
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_ci  ConvertFloatToIntAndBack<dst_type, src_type>(assm, dst, rounded,
18951cb0ef41Sopenharmony_ci                                               converted_back);
18961cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
18971cb0ef41Sopenharmony_ci    __ Ucomisd(converted_back, rounded);
18981cb0ef41Sopenharmony_ci  } else {  // f32
18991cb0ef41Sopenharmony_ci    __ Ucomiss(converted_back, rounded);
19001cb0ef41Sopenharmony_ci  }
19011cb0ef41Sopenharmony_ci
19021cb0ef41Sopenharmony_ci  // Return 0 if PF is 0 (one of the operands was NaN)
19031cb0ef41Sopenharmony_ci  __ j(parity_odd, &not_nan);
19041cb0ef41Sopenharmony_ci  __ xorl(dst, dst);
19051cb0ef41Sopenharmony_ci  __ jmp(&done);
19061cb0ef41Sopenharmony_ci
19071cb0ef41Sopenharmony_ci  __ bind(&not_nan);
19081cb0ef41Sopenharmony_ci  // If rounding is as expected, return result
19091cb0ef41Sopenharmony_ci  __ j(equal, &done);
19101cb0ef41Sopenharmony_ci
19111cb0ef41Sopenharmony_ci  __ xorpd(zero_reg, zero_reg);
19121cb0ef41Sopenharmony_ci
19131cb0ef41Sopenharmony_ci  // if out-of-bounds, check if src is positive
19141cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
19151cb0ef41Sopenharmony_ci    __ Ucomisd(src, zero_reg);
19161cb0ef41Sopenharmony_ci  } else {  // f32
19171cb0ef41Sopenharmony_ci    __ Ucomiss(src, zero_reg);
19181cb0ef41Sopenharmony_ci  }
19191cb0ef41Sopenharmony_ci  __ j(above, &src_positive);
19201cb0ef41Sopenharmony_ci  if (std::is_same<int32_t, dst_type>::value ||
19211cb0ef41Sopenharmony_ci      std::is_same<uint32_t, dst_type>::value) {  // i32
19221cb0ef41Sopenharmony_ci    __ movl(
19231cb0ef41Sopenharmony_ci        dst,
19241cb0ef41Sopenharmony_ci        Immediate(static_cast<int32_t>(std::numeric_limits<dst_type>::min())));
19251cb0ef41Sopenharmony_ci  } else if (std::is_same<int64_t, dst_type>::value) {  // i64s
19261cb0ef41Sopenharmony_ci    __ movq(dst, Immediate64(std::numeric_limits<dst_type>::min()));
19271cb0ef41Sopenharmony_ci  } else {
19281cb0ef41Sopenharmony_ci    UNREACHABLE();
19291cb0ef41Sopenharmony_ci  }
19301cb0ef41Sopenharmony_ci  __ jmp(&done);
19311cb0ef41Sopenharmony_ci
19321cb0ef41Sopenharmony_ci  __ bind(&src_positive);
19331cb0ef41Sopenharmony_ci  if (std::is_same<int32_t, dst_type>::value ||
19341cb0ef41Sopenharmony_ci      std::is_same<uint32_t, dst_type>::value) {  // i32
19351cb0ef41Sopenharmony_ci    __ movl(
19361cb0ef41Sopenharmony_ci        dst,
19371cb0ef41Sopenharmony_ci        Immediate(static_cast<int32_t>(std::numeric_limits<dst_type>::max())));
19381cb0ef41Sopenharmony_ci  } else if (std::is_same<int64_t, dst_type>::value) {  // i64s
19391cb0ef41Sopenharmony_ci    __ movq(dst, Immediate64(std::numeric_limits<dst_type>::max()));
19401cb0ef41Sopenharmony_ci  } else {
19411cb0ef41Sopenharmony_ci    UNREACHABLE();
19421cb0ef41Sopenharmony_ci  }
19431cb0ef41Sopenharmony_ci
19441cb0ef41Sopenharmony_ci  __ bind(&done);
19451cb0ef41Sopenharmony_ci  return true;
19461cb0ef41Sopenharmony_ci}
19471cb0ef41Sopenharmony_ci
19481cb0ef41Sopenharmony_citemplate <typename src_type>
19491cb0ef41Sopenharmony_ciinline bool EmitSatTruncateFloatToUInt64(LiftoffAssembler* assm, Register dst,
19501cb0ef41Sopenharmony_ci                                         DoubleRegister src) {
19511cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(SSE4_1)) {
19521cb0ef41Sopenharmony_ci    __ bailout(kMissingCPUFeature, "no SSE4.1");
19531cb0ef41Sopenharmony_ci    return true;
19541cb0ef41Sopenharmony_ci  }
19551cb0ef41Sopenharmony_ci  CpuFeatureScope feature(assm, SSE4_1);
19561cb0ef41Sopenharmony_ci
19571cb0ef41Sopenharmony_ci  Label done;
19581cb0ef41Sopenharmony_ci  Label neg_or_nan;
19591cb0ef41Sopenharmony_ci  Label overflow;
19601cb0ef41Sopenharmony_ci
19611cb0ef41Sopenharmony_ci  DoubleRegister zero_reg = kScratchDoubleReg;
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_ci  __ xorpd(zero_reg, zero_reg);
19641cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
19651cb0ef41Sopenharmony_ci    __ Ucomisd(src, zero_reg);
19661cb0ef41Sopenharmony_ci  } else {  // f32
19671cb0ef41Sopenharmony_ci    __ Ucomiss(src, zero_reg);
19681cb0ef41Sopenharmony_ci  }
19691cb0ef41Sopenharmony_ci  // Check if NaN
19701cb0ef41Sopenharmony_ci  __ j(parity_even, &neg_or_nan);
19711cb0ef41Sopenharmony_ci  __ j(below, &neg_or_nan);
19721cb0ef41Sopenharmony_ci  if (std::is_same<double, src_type>::value) {  // f64
19731cb0ef41Sopenharmony_ci    __ Cvttsd2uiq(dst, src, &overflow);
19741cb0ef41Sopenharmony_ci  } else {  // f32
19751cb0ef41Sopenharmony_ci    __ Cvttss2uiq(dst, src, &overflow);
19761cb0ef41Sopenharmony_ci  }
19771cb0ef41Sopenharmony_ci  __ jmp(&done);
19781cb0ef41Sopenharmony_ci
19791cb0ef41Sopenharmony_ci  __ bind(&neg_or_nan);
19801cb0ef41Sopenharmony_ci  __ movq(dst, zero_reg);
19811cb0ef41Sopenharmony_ci  __ jmp(&done);
19821cb0ef41Sopenharmony_ci
19831cb0ef41Sopenharmony_ci  __ bind(&overflow);
19841cb0ef41Sopenharmony_ci  __ movq(dst, Immediate64(std::numeric_limits<uint64_t>::max()));
19851cb0ef41Sopenharmony_ci  __ bind(&done);
19861cb0ef41Sopenharmony_ci  return true;
19871cb0ef41Sopenharmony_ci}
19881cb0ef41Sopenharmony_ci#undef __
19891cb0ef41Sopenharmony_ci}  // namespace liftoff
19901cb0ef41Sopenharmony_ci
19911cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode,
19921cb0ef41Sopenharmony_ci                                            LiftoffRegister dst,
19931cb0ef41Sopenharmony_ci                                            LiftoffRegister src, Label* trap) {
19941cb0ef41Sopenharmony_ci  switch (opcode) {
19951cb0ef41Sopenharmony_ci    case kExprI32ConvertI64:
19961cb0ef41Sopenharmony_ci      movl(dst.gp(), src.gp());
19971cb0ef41Sopenharmony_ci      return true;
19981cb0ef41Sopenharmony_ci    case kExprI32SConvertF32:
19991cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<int32_t, float>(this, dst.gp(),
20001cb0ef41Sopenharmony_ci                                                             src.fp(), trap);
20011cb0ef41Sopenharmony_ci    case kExprI32UConvertF32:
20021cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<uint32_t, float>(this, dst.gp(),
20031cb0ef41Sopenharmony_ci                                                              src.fp(), trap);
20041cb0ef41Sopenharmony_ci    case kExprI32SConvertF64:
20051cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<int32_t, double>(this, dst.gp(),
20061cb0ef41Sopenharmony_ci                                                              src.fp(), trap);
20071cb0ef41Sopenharmony_ci    case kExprI32UConvertF64:
20081cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<uint32_t, double>(this, dst.gp(),
20091cb0ef41Sopenharmony_ci                                                               src.fp(), trap);
20101cb0ef41Sopenharmony_ci    case kExprI32SConvertSatF32:
20111cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<int32_t, float>(this, dst.gp(),
20121cb0ef41Sopenharmony_ci                                                                src.fp());
20131cb0ef41Sopenharmony_ci    case kExprI32UConvertSatF32:
20141cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<uint32_t, float>(this, dst.gp(),
20151cb0ef41Sopenharmony_ci                                                                 src.fp());
20161cb0ef41Sopenharmony_ci    case kExprI32SConvertSatF64:
20171cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<int32_t, double>(this, dst.gp(),
20181cb0ef41Sopenharmony_ci                                                                 src.fp());
20191cb0ef41Sopenharmony_ci    case kExprI32UConvertSatF64:
20201cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<uint32_t, double>(
20211cb0ef41Sopenharmony_ci          this, dst.gp(), src.fp());
20221cb0ef41Sopenharmony_ci    case kExprI32ReinterpretF32:
20231cb0ef41Sopenharmony_ci      Movd(dst.gp(), src.fp());
20241cb0ef41Sopenharmony_ci      return true;
20251cb0ef41Sopenharmony_ci    case kExprI64SConvertI32:
20261cb0ef41Sopenharmony_ci      movsxlq(dst.gp(), src.gp());
20271cb0ef41Sopenharmony_ci      return true;
20281cb0ef41Sopenharmony_ci    case kExprI64SConvertF32:
20291cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<int64_t, float>(this, dst.gp(),
20301cb0ef41Sopenharmony_ci                                                             src.fp(), trap);
20311cb0ef41Sopenharmony_ci    case kExprI64UConvertF32: {
20321cb0ef41Sopenharmony_ci      RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
20331cb0ef41Sopenharmony_ci      Cvttss2uiq(dst.gp(), src.fp(), trap);
20341cb0ef41Sopenharmony_ci      return true;
20351cb0ef41Sopenharmony_ci    }
20361cb0ef41Sopenharmony_ci    case kExprI64SConvertF64:
20371cb0ef41Sopenharmony_ci      return liftoff::EmitTruncateFloatToInt<int64_t, double>(this, dst.gp(),
20381cb0ef41Sopenharmony_ci                                                              src.fp(), trap);
20391cb0ef41Sopenharmony_ci    case kExprI64UConvertF64: {
20401cb0ef41Sopenharmony_ci      RETURN_FALSE_IF_MISSING_CPU_FEATURE(SSE4_1);
20411cb0ef41Sopenharmony_ci      Cvttsd2uiq(dst.gp(), src.fp(), trap);
20421cb0ef41Sopenharmony_ci      return true;
20431cb0ef41Sopenharmony_ci    }
20441cb0ef41Sopenharmony_ci    case kExprI64SConvertSatF32:
20451cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<int64_t, float>(this, dst.gp(),
20461cb0ef41Sopenharmony_ci                                                                src.fp());
20471cb0ef41Sopenharmony_ci    case kExprI64UConvertSatF32: {
20481cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToUInt64<float>(this, dst.gp(),
20491cb0ef41Sopenharmony_ci                                                          src.fp());
20501cb0ef41Sopenharmony_ci    }
20511cb0ef41Sopenharmony_ci    case kExprI64SConvertSatF64:
20521cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToInt<int64_t, double>(this, dst.gp(),
20531cb0ef41Sopenharmony_ci                                                                 src.fp());
20541cb0ef41Sopenharmony_ci    case kExprI64UConvertSatF64: {
20551cb0ef41Sopenharmony_ci      return liftoff::EmitSatTruncateFloatToUInt64<double>(this, dst.gp(),
20561cb0ef41Sopenharmony_ci                                                           src.fp());
20571cb0ef41Sopenharmony_ci    }
20581cb0ef41Sopenharmony_ci    case kExprI64UConvertI32:
20591cb0ef41Sopenharmony_ci      AssertZeroExtended(src.gp());
20601cb0ef41Sopenharmony_ci      if (dst.gp() != src.gp()) movl(dst.gp(), src.gp());
20611cb0ef41Sopenharmony_ci      return true;
20621cb0ef41Sopenharmony_ci    case kExprI64ReinterpretF64:
20631cb0ef41Sopenharmony_ci      Movq(dst.gp(), src.fp());
20641cb0ef41Sopenharmony_ci      return true;
20651cb0ef41Sopenharmony_ci    case kExprF32SConvertI32:
20661cb0ef41Sopenharmony_ci      Cvtlsi2ss(dst.fp(), src.gp());
20671cb0ef41Sopenharmony_ci      return true;
20681cb0ef41Sopenharmony_ci    case kExprF32UConvertI32:
20691cb0ef41Sopenharmony_ci      movl(kScratchRegister, src.gp());
20701cb0ef41Sopenharmony_ci      Cvtqsi2ss(dst.fp(), kScratchRegister);
20711cb0ef41Sopenharmony_ci      return true;
20721cb0ef41Sopenharmony_ci    case kExprF32SConvertI64:
20731cb0ef41Sopenharmony_ci      Cvtqsi2ss(dst.fp(), src.gp());
20741cb0ef41Sopenharmony_ci      return true;
20751cb0ef41Sopenharmony_ci    case kExprF32UConvertI64:
20761cb0ef41Sopenharmony_ci      Cvtqui2ss(dst.fp(), src.gp());
20771cb0ef41Sopenharmony_ci      return true;
20781cb0ef41Sopenharmony_ci    case kExprF32ConvertF64:
20791cb0ef41Sopenharmony_ci      Cvtsd2ss(dst.fp(), src.fp());
20801cb0ef41Sopenharmony_ci      return true;
20811cb0ef41Sopenharmony_ci    case kExprF32ReinterpretI32:
20821cb0ef41Sopenharmony_ci      Movd(dst.fp(), src.gp());
20831cb0ef41Sopenharmony_ci      return true;
20841cb0ef41Sopenharmony_ci    case kExprF64SConvertI32:
20851cb0ef41Sopenharmony_ci      Cvtlsi2sd(dst.fp(), src.gp());
20861cb0ef41Sopenharmony_ci      return true;
20871cb0ef41Sopenharmony_ci    case kExprF64UConvertI32:
20881cb0ef41Sopenharmony_ci      movl(kScratchRegister, src.gp());
20891cb0ef41Sopenharmony_ci      Cvtqsi2sd(dst.fp(), kScratchRegister);
20901cb0ef41Sopenharmony_ci      return true;
20911cb0ef41Sopenharmony_ci    case kExprF64SConvertI64:
20921cb0ef41Sopenharmony_ci      Cvtqsi2sd(dst.fp(), src.gp());
20931cb0ef41Sopenharmony_ci      return true;
20941cb0ef41Sopenharmony_ci    case kExprF64UConvertI64:
20951cb0ef41Sopenharmony_ci      Cvtqui2sd(dst.fp(), src.gp());
20961cb0ef41Sopenharmony_ci      return true;
20971cb0ef41Sopenharmony_ci    case kExprF64ConvertF32:
20981cb0ef41Sopenharmony_ci      Cvtss2sd(dst.fp(), src.fp());
20991cb0ef41Sopenharmony_ci      return true;
21001cb0ef41Sopenharmony_ci    case kExprF64ReinterpretI64:
21011cb0ef41Sopenharmony_ci      Movq(dst.fp(), src.gp());
21021cb0ef41Sopenharmony_ci      return true;
21031cb0ef41Sopenharmony_ci    default:
21041cb0ef41Sopenharmony_ci      UNREACHABLE();
21051cb0ef41Sopenharmony_ci  }
21061cb0ef41Sopenharmony_ci}
21071cb0ef41Sopenharmony_ci
21081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_signextend_i8(Register dst, Register src) {
21091cb0ef41Sopenharmony_ci  movsxbl(dst, src);
21101cb0ef41Sopenharmony_ci}
21111cb0ef41Sopenharmony_ci
21121cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_signextend_i16(Register dst, Register src) {
21131cb0ef41Sopenharmony_ci  movsxwl(dst, src);
21141cb0ef41Sopenharmony_ci}
21151cb0ef41Sopenharmony_ci
21161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i8(LiftoffRegister dst,
21171cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
21181cb0ef41Sopenharmony_ci  movsxbq(dst.gp(), src.gp());
21191cb0ef41Sopenharmony_ci}
21201cb0ef41Sopenharmony_ci
21211cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i16(LiftoffRegister dst,
21221cb0ef41Sopenharmony_ci                                               LiftoffRegister src) {
21231cb0ef41Sopenharmony_ci  movsxwq(dst.gp(), src.gp());
21241cb0ef41Sopenharmony_ci}
21251cb0ef41Sopenharmony_ci
21261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_signextend_i32(LiftoffRegister dst,
21271cb0ef41Sopenharmony_ci                                               LiftoffRegister src) {
21281cb0ef41Sopenharmony_ci  movsxlq(dst.gp(), src.gp());
21291cb0ef41Sopenharmony_ci}
21301cb0ef41Sopenharmony_ci
21311cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_jump(Label* label) { jmp(label); }
21321cb0ef41Sopenharmony_ci
21331cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_jump(Register target) { jmp(target); }
21341cb0ef41Sopenharmony_ci
21351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_cond_jump(LiftoffCondition liftoff_cond,
21361cb0ef41Sopenharmony_ci                                      Label* label, ValueKind kind,
21371cb0ef41Sopenharmony_ci                                      Register lhs, Register rhs) {
21381cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
21391cb0ef41Sopenharmony_ci  if (rhs != no_reg) {
21401cb0ef41Sopenharmony_ci    switch (kind) {
21411cb0ef41Sopenharmony_ci      case kI32:
21421cb0ef41Sopenharmony_ci        cmpl(lhs, rhs);
21431cb0ef41Sopenharmony_ci        break;
21441cb0ef41Sopenharmony_ci      case kRef:
21451cb0ef41Sopenharmony_ci      case kOptRef:
21461cb0ef41Sopenharmony_ci      case kRtt:
21471cb0ef41Sopenharmony_ci        DCHECK(liftoff_cond == kEqual || liftoff_cond == kUnequal);
21481cb0ef41Sopenharmony_ci        V8_FALLTHROUGH;
21491cb0ef41Sopenharmony_ci      case kI64:
21501cb0ef41Sopenharmony_ci        cmpq(lhs, rhs);
21511cb0ef41Sopenharmony_ci        break;
21521cb0ef41Sopenharmony_ci      default:
21531cb0ef41Sopenharmony_ci        UNREACHABLE();
21541cb0ef41Sopenharmony_ci    }
21551cb0ef41Sopenharmony_ci  } else {
21561cb0ef41Sopenharmony_ci    DCHECK_EQ(kind, kI32);
21571cb0ef41Sopenharmony_ci    testl(lhs, lhs);
21581cb0ef41Sopenharmony_ci  }
21591cb0ef41Sopenharmony_ci
21601cb0ef41Sopenharmony_ci  j(cond, label);
21611cb0ef41Sopenharmony_ci}
21621cb0ef41Sopenharmony_ci
21631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_cond_jumpi(LiftoffCondition liftoff_cond,
21641cb0ef41Sopenharmony_ci                                           Label* label, Register lhs,
21651cb0ef41Sopenharmony_ci                                           int imm) {
21661cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
21671cb0ef41Sopenharmony_ci  cmpl(lhs, Immediate(imm));
21681cb0ef41Sopenharmony_ci  j(cond, label);
21691cb0ef41Sopenharmony_ci}
21701cb0ef41Sopenharmony_ci
21711cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_subi_jump_negative(Register value,
21721cb0ef41Sopenharmony_ci                                                   int subtrahend,
21731cb0ef41Sopenharmony_ci                                                   Label* result_negative) {
21741cb0ef41Sopenharmony_ci  subl(value, Immediate(subtrahend));
21751cb0ef41Sopenharmony_ci  j(negative, result_negative);
21761cb0ef41Sopenharmony_ci}
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
21791cb0ef41Sopenharmony_ci  testl(src, src);
21801cb0ef41Sopenharmony_ci  setcc(equal, dst);
21811cb0ef41Sopenharmony_ci  movzxbl(dst, dst);
21821cb0ef41Sopenharmony_ci}
21831cb0ef41Sopenharmony_ci
21841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32_set_cond(LiftoffCondition liftoff_cond,
21851cb0ef41Sopenharmony_ci                                         Register dst, Register lhs,
21861cb0ef41Sopenharmony_ci                                         Register rhs) {
21871cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
21881cb0ef41Sopenharmony_ci  cmpl(lhs, rhs);
21891cb0ef41Sopenharmony_ci  setcc(cond, dst);
21901cb0ef41Sopenharmony_ci  movzxbl(dst, dst);
21911cb0ef41Sopenharmony_ci}
21921cb0ef41Sopenharmony_ci
21931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
21941cb0ef41Sopenharmony_ci  testq(src.gp(), src.gp());
21951cb0ef41Sopenharmony_ci  setcc(equal, dst);
21961cb0ef41Sopenharmony_ci  movzxbl(dst, dst);
21971cb0ef41Sopenharmony_ci}
21981cb0ef41Sopenharmony_ci
21991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64_set_cond(LiftoffCondition liftoff_cond,
22001cb0ef41Sopenharmony_ci                                         Register dst, LiftoffRegister lhs,
22011cb0ef41Sopenharmony_ci                                         LiftoffRegister rhs) {
22021cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
22031cb0ef41Sopenharmony_ci  cmpq(lhs.gp(), rhs.gp());
22041cb0ef41Sopenharmony_ci  setcc(cond, dst);
22051cb0ef41Sopenharmony_ci  movzxbl(dst, dst);
22061cb0ef41Sopenharmony_ci}
22071cb0ef41Sopenharmony_ci
22081cb0ef41Sopenharmony_cinamespace liftoff {
22091cb0ef41Sopenharmony_citemplate <void (SharedTurboAssembler::*cmp_op)(DoubleRegister, DoubleRegister)>
22101cb0ef41Sopenharmony_civoid EmitFloatSetCond(LiftoffAssembler* assm, Condition cond, Register dst,
22111cb0ef41Sopenharmony_ci                      DoubleRegister lhs, DoubleRegister rhs) {
22121cb0ef41Sopenharmony_ci  Label cont;
22131cb0ef41Sopenharmony_ci  Label not_nan;
22141cb0ef41Sopenharmony_ci
22151cb0ef41Sopenharmony_ci  (assm->*cmp_op)(lhs, rhs);
22161cb0ef41Sopenharmony_ci  // If PF is one, one of the operands was NaN. This needs special handling.
22171cb0ef41Sopenharmony_ci  assm->j(parity_odd, &not_nan, Label::kNear);
22181cb0ef41Sopenharmony_ci  // Return 1 for f32.ne, 0 for all other cases.
22191cb0ef41Sopenharmony_ci  if (cond == not_equal) {
22201cb0ef41Sopenharmony_ci    assm->movl(dst, Immediate(1));
22211cb0ef41Sopenharmony_ci  } else {
22221cb0ef41Sopenharmony_ci    assm->xorl(dst, dst);
22231cb0ef41Sopenharmony_ci  }
22241cb0ef41Sopenharmony_ci  assm->jmp(&cont, Label::kNear);
22251cb0ef41Sopenharmony_ci  assm->bind(&not_nan);
22261cb0ef41Sopenharmony_ci
22271cb0ef41Sopenharmony_ci  assm->setcc(cond, dst);
22281cb0ef41Sopenharmony_ci  assm->movzxbl(dst, dst);
22291cb0ef41Sopenharmony_ci  assm->bind(&cont);
22301cb0ef41Sopenharmony_ci}
22311cb0ef41Sopenharmony_ci}  // namespace liftoff
22321cb0ef41Sopenharmony_ci
22331cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32_set_cond(LiftoffCondition liftoff_cond,
22341cb0ef41Sopenharmony_ci                                         Register dst, DoubleRegister lhs,
22351cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
22361cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
22371cb0ef41Sopenharmony_ci  liftoff::EmitFloatSetCond<&TurboAssembler::Ucomiss>(this, cond, dst, lhs,
22381cb0ef41Sopenharmony_ci                                                      rhs);
22391cb0ef41Sopenharmony_ci}
22401cb0ef41Sopenharmony_ci
22411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64_set_cond(LiftoffCondition liftoff_cond,
22421cb0ef41Sopenharmony_ci                                         Register dst, DoubleRegister lhs,
22431cb0ef41Sopenharmony_ci                                         DoubleRegister rhs) {
22441cb0ef41Sopenharmony_ci  Condition cond = liftoff::ToCondition(liftoff_cond);
22451cb0ef41Sopenharmony_ci  liftoff::EmitFloatSetCond<&TurboAssembler::Ucomisd>(this, cond, dst, lhs,
22461cb0ef41Sopenharmony_ci                                                      rhs);
22471cb0ef41Sopenharmony_ci}
22481cb0ef41Sopenharmony_ci
22491cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_select(LiftoffRegister dst, Register condition,
22501cb0ef41Sopenharmony_ci                                   LiftoffRegister true_value,
22511cb0ef41Sopenharmony_ci                                   LiftoffRegister false_value,
22521cb0ef41Sopenharmony_ci                                   ValueKind kind) {
22531cb0ef41Sopenharmony_ci  if (kind != kI32 && kind != kI64) return false;
22541cb0ef41Sopenharmony_ci
22551cb0ef41Sopenharmony_ci  testl(condition, condition);
22561cb0ef41Sopenharmony_ci
22571cb0ef41Sopenharmony_ci  if (kind == kI32) {
22581cb0ef41Sopenharmony_ci    if (dst == false_value) {
22591cb0ef41Sopenharmony_ci      cmovl(not_zero, dst.gp(), true_value.gp());
22601cb0ef41Sopenharmony_ci    } else {
22611cb0ef41Sopenharmony_ci      if (dst != true_value) movl(dst.gp(), true_value.gp());
22621cb0ef41Sopenharmony_ci      cmovl(zero, dst.gp(), false_value.gp());
22631cb0ef41Sopenharmony_ci    }
22641cb0ef41Sopenharmony_ci  } else {
22651cb0ef41Sopenharmony_ci    if (dst == false_value) {
22661cb0ef41Sopenharmony_ci      cmovq(not_zero, dst.gp(), true_value.gp());
22671cb0ef41Sopenharmony_ci    } else {
22681cb0ef41Sopenharmony_ci      if (dst != true_value) movq(dst.gp(), true_value.gp());
22691cb0ef41Sopenharmony_ci      cmovq(zero, dst.gp(), false_value.gp());
22701cb0ef41Sopenharmony_ci    }
22711cb0ef41Sopenharmony_ci  }
22721cb0ef41Sopenharmony_ci
22731cb0ef41Sopenharmony_ci  return true;
22741cb0ef41Sopenharmony_ci}
22751cb0ef41Sopenharmony_ci
22761cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_smi_check(Register obj, Label* target,
22771cb0ef41Sopenharmony_ci                                      SmiCheckMode mode) {
22781cb0ef41Sopenharmony_ci  testb(obj, Immediate(kSmiTagMask));
22791cb0ef41Sopenharmony_ci  Condition condition = mode == kJumpOnSmi ? zero : not_zero;
22801cb0ef41Sopenharmony_ci  j(condition, target);
22811cb0ef41Sopenharmony_ci}
22821cb0ef41Sopenharmony_ci
22831cb0ef41Sopenharmony_ci// TODO(fanchenk): Distinguish mov* if data bypass delay matter.
22841cb0ef41Sopenharmony_cinamespace liftoff {
22851cb0ef41Sopenharmony_citemplate <void (Assembler::*avx_op)(XMMRegister, XMMRegister, XMMRegister),
22861cb0ef41Sopenharmony_ci          void (Assembler::*sse_op)(XMMRegister, XMMRegister)>
22871cb0ef41Sopenharmony_civoid EmitSimdCommutativeBinOp(
22881cb0ef41Sopenharmony_ci    LiftoffAssembler* assm, LiftoffRegister dst, LiftoffRegister lhs,
22891cb0ef41Sopenharmony_ci    LiftoffRegister rhs, base::Optional<CpuFeature> feature = base::nullopt) {
22901cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
22911cb0ef41Sopenharmony_ci    CpuFeatureScope scope(assm, AVX);
22921cb0ef41Sopenharmony_ci    (assm->*avx_op)(dst.fp(), lhs.fp(), rhs.fp());
22931cb0ef41Sopenharmony_ci    return;
22941cb0ef41Sopenharmony_ci  }
22951cb0ef41Sopenharmony_ci
22961cb0ef41Sopenharmony_ci  base::Optional<CpuFeatureScope> sse_scope;
22971cb0ef41Sopenharmony_ci  if (feature.has_value()) sse_scope.emplace(assm, *feature);
22981cb0ef41Sopenharmony_ci
22991cb0ef41Sopenharmony_ci  if (dst.fp() == rhs.fp()) {
23001cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), lhs.fp());
23011cb0ef41Sopenharmony_ci  } else {
23021cb0ef41Sopenharmony_ci    if (dst.fp() != lhs.fp()) (assm->movaps)(dst.fp(), lhs.fp());
23031cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), rhs.fp());
23041cb0ef41Sopenharmony_ci  }
23051cb0ef41Sopenharmony_ci}
23061cb0ef41Sopenharmony_ci
23071cb0ef41Sopenharmony_citemplate <void (Assembler::*avx_op)(XMMRegister, XMMRegister, XMMRegister),
23081cb0ef41Sopenharmony_ci          void (Assembler::*sse_op)(XMMRegister, XMMRegister)>
23091cb0ef41Sopenharmony_civoid EmitSimdNonCommutativeBinOp(
23101cb0ef41Sopenharmony_ci    LiftoffAssembler* assm, LiftoffRegister dst, LiftoffRegister lhs,
23111cb0ef41Sopenharmony_ci    LiftoffRegister rhs, base::Optional<CpuFeature> feature = base::nullopt) {
23121cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
23131cb0ef41Sopenharmony_ci    CpuFeatureScope scope(assm, AVX);
23141cb0ef41Sopenharmony_ci    (assm->*avx_op)(dst.fp(), lhs.fp(), rhs.fp());
23151cb0ef41Sopenharmony_ci    return;
23161cb0ef41Sopenharmony_ci  }
23171cb0ef41Sopenharmony_ci
23181cb0ef41Sopenharmony_ci  base::Optional<CpuFeatureScope> sse_scope;
23191cb0ef41Sopenharmony_ci  if (feature.has_value()) sse_scope.emplace(assm, *feature);
23201cb0ef41Sopenharmony_ci
23211cb0ef41Sopenharmony_ci  if (dst.fp() == rhs.fp()) {
23221cb0ef41Sopenharmony_ci    assm->movaps(kScratchDoubleReg, rhs.fp());
23231cb0ef41Sopenharmony_ci    assm->movaps(dst.fp(), lhs.fp());
23241cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), kScratchDoubleReg);
23251cb0ef41Sopenharmony_ci  } else {
23261cb0ef41Sopenharmony_ci    if (dst.fp() != lhs.fp()) assm->movaps(dst.fp(), lhs.fp());
23271cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), rhs.fp());
23281cb0ef41Sopenharmony_ci  }
23291cb0ef41Sopenharmony_ci}
23301cb0ef41Sopenharmony_ci
23311cb0ef41Sopenharmony_citemplate <void (Assembler::*avx_op)(XMMRegister, XMMRegister, XMMRegister),
23321cb0ef41Sopenharmony_ci          void (Assembler::*sse_op)(XMMRegister, XMMRegister), uint8_t width>
23331cb0ef41Sopenharmony_civoid EmitSimdShiftOp(LiftoffAssembler* assm, LiftoffRegister dst,
23341cb0ef41Sopenharmony_ci                     LiftoffRegister operand, LiftoffRegister count) {
23351cb0ef41Sopenharmony_ci  constexpr int mask = (1 << width) - 1;
23361cb0ef41Sopenharmony_ci  assm->movq(kScratchRegister, count.gp());
23371cb0ef41Sopenharmony_ci  assm->andq(kScratchRegister, Immediate(mask));
23381cb0ef41Sopenharmony_ci  assm->Movq(kScratchDoubleReg, kScratchRegister);
23391cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
23401cb0ef41Sopenharmony_ci    CpuFeatureScope scope(assm, AVX);
23411cb0ef41Sopenharmony_ci    (assm->*avx_op)(dst.fp(), operand.fp(), kScratchDoubleReg);
23421cb0ef41Sopenharmony_ci  } else {
23431cb0ef41Sopenharmony_ci    if (dst.fp() != operand.fp()) assm->movaps(dst.fp(), operand.fp());
23441cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), kScratchDoubleReg);
23451cb0ef41Sopenharmony_ci  }
23461cb0ef41Sopenharmony_ci}
23471cb0ef41Sopenharmony_ci
23481cb0ef41Sopenharmony_citemplate <void (Assembler::*avx_op)(XMMRegister, XMMRegister, byte),
23491cb0ef41Sopenharmony_ci          void (Assembler::*sse_op)(XMMRegister, byte), uint8_t width>
23501cb0ef41Sopenharmony_civoid EmitSimdShiftOpImm(LiftoffAssembler* assm, LiftoffRegister dst,
23511cb0ef41Sopenharmony_ci                        LiftoffRegister operand, int32_t count) {
23521cb0ef41Sopenharmony_ci  constexpr int mask = (1 << width) - 1;
23531cb0ef41Sopenharmony_ci  byte shift = static_cast<byte>(count & mask);
23541cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
23551cb0ef41Sopenharmony_ci    CpuFeatureScope scope(assm, AVX);
23561cb0ef41Sopenharmony_ci    (assm->*avx_op)(dst.fp(), operand.fp(), shift);
23571cb0ef41Sopenharmony_ci  } else {
23581cb0ef41Sopenharmony_ci    if (dst.fp() != operand.fp()) assm->movaps(dst.fp(), operand.fp());
23591cb0ef41Sopenharmony_ci    (assm->*sse_op)(dst.fp(), shift);
23601cb0ef41Sopenharmony_ci  }
23611cb0ef41Sopenharmony_ci}
23621cb0ef41Sopenharmony_ci
23631cb0ef41Sopenharmony_ciinline void EmitAnyTrue(LiftoffAssembler* assm, LiftoffRegister dst,
23641cb0ef41Sopenharmony_ci                        LiftoffRegister src) {
23651cb0ef41Sopenharmony_ci  assm->xorq(dst.gp(), dst.gp());
23661cb0ef41Sopenharmony_ci  assm->Ptest(src.fp(), src.fp());
23671cb0ef41Sopenharmony_ci  assm->setcc(not_equal, dst.gp());
23681cb0ef41Sopenharmony_ci}
23691cb0ef41Sopenharmony_ci
23701cb0ef41Sopenharmony_citemplate <void (SharedTurboAssembler::*pcmp)(XMMRegister, XMMRegister)>
23711cb0ef41Sopenharmony_ciinline void EmitAllTrue(LiftoffAssembler* assm, LiftoffRegister dst,
23721cb0ef41Sopenharmony_ci                        LiftoffRegister src,
23731cb0ef41Sopenharmony_ci                        base::Optional<CpuFeature> feature = base::nullopt) {
23741cb0ef41Sopenharmony_ci  base::Optional<CpuFeatureScope> sse_scope;
23751cb0ef41Sopenharmony_ci  if (feature.has_value()) sse_scope.emplace(assm, *feature);
23761cb0ef41Sopenharmony_ci
23771cb0ef41Sopenharmony_ci  XMMRegister tmp = kScratchDoubleReg;
23781cb0ef41Sopenharmony_ci  assm->xorq(dst.gp(), dst.gp());
23791cb0ef41Sopenharmony_ci  assm->Pxor(tmp, tmp);
23801cb0ef41Sopenharmony_ci  (assm->*pcmp)(tmp, src.fp());
23811cb0ef41Sopenharmony_ci  assm->Ptest(tmp, tmp);
23821cb0ef41Sopenharmony_ci  assm->setcc(equal, dst.gp());
23831cb0ef41Sopenharmony_ci}
23841cb0ef41Sopenharmony_ci
23851cb0ef41Sopenharmony_ci}  // namespace liftoff
23861cb0ef41Sopenharmony_ci
23871cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadTransform(LiftoffRegister dst, Register src_addr,
23881cb0ef41Sopenharmony_ci                                     Register offset_reg, uintptr_t offset_imm,
23891cb0ef41Sopenharmony_ci                                     LoadType type,
23901cb0ef41Sopenharmony_ci                                     LoadTransformationKind transform,
23911cb0ef41Sopenharmony_ci                                     uint32_t* protected_load_pc) {
23921cb0ef41Sopenharmony_ci  Operand src_op = liftoff::GetMemOp(this, src_addr, offset_reg, offset_imm);
23931cb0ef41Sopenharmony_ci  *protected_load_pc = pc_offset();
23941cb0ef41Sopenharmony_ci  MachineType memtype = type.mem_type();
23951cb0ef41Sopenharmony_ci  if (transform == LoadTransformationKind::kExtend) {
23961cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int8()) {
23971cb0ef41Sopenharmony_ci      Pmovsxbw(dst.fp(), src_op);
23981cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint8()) {
23991cb0ef41Sopenharmony_ci      Pmovzxbw(dst.fp(), src_op);
24001cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int16()) {
24011cb0ef41Sopenharmony_ci      Pmovsxwd(dst.fp(), src_op);
24021cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint16()) {
24031cb0ef41Sopenharmony_ci      Pmovzxwd(dst.fp(), src_op);
24041cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int32()) {
24051cb0ef41Sopenharmony_ci      Pmovsxdq(dst.fp(), src_op);
24061cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Uint32()) {
24071cb0ef41Sopenharmony_ci      Pmovzxdq(dst.fp(), src_op);
24081cb0ef41Sopenharmony_ci    }
24091cb0ef41Sopenharmony_ci  } else if (transform == LoadTransformationKind::kZeroExtend) {
24101cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int32()) {
24111cb0ef41Sopenharmony_ci      Movss(dst.fp(), src_op);
24121cb0ef41Sopenharmony_ci    } else {
24131cb0ef41Sopenharmony_ci      DCHECK_EQ(MachineType::Int64(), memtype);
24141cb0ef41Sopenharmony_ci      Movsd(dst.fp(), src_op);
24151cb0ef41Sopenharmony_ci    }
24161cb0ef41Sopenharmony_ci  } else {
24171cb0ef41Sopenharmony_ci    DCHECK_EQ(LoadTransformationKind::kSplat, transform);
24181cb0ef41Sopenharmony_ci    if (memtype == MachineType::Int8()) {
24191cb0ef41Sopenharmony_ci      S128Load8Splat(dst.fp(), src_op, kScratchDoubleReg);
24201cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int16()) {
24211cb0ef41Sopenharmony_ci      S128Load16Splat(dst.fp(), src_op, kScratchDoubleReg);
24221cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int32()) {
24231cb0ef41Sopenharmony_ci      S128Load32Splat(dst.fp(), src_op);
24241cb0ef41Sopenharmony_ci    } else if (memtype == MachineType::Int64()) {
24251cb0ef41Sopenharmony_ci      Movddup(dst.fp(), src_op);
24261cb0ef41Sopenharmony_ci    }
24271cb0ef41Sopenharmony_ci  }
24281cb0ef41Sopenharmony_ci}
24291cb0ef41Sopenharmony_ci
24301cb0ef41Sopenharmony_civoid LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
24311cb0ef41Sopenharmony_ci                                Register addr, Register offset_reg,
24321cb0ef41Sopenharmony_ci                                uintptr_t offset_imm, LoadType type,
24331cb0ef41Sopenharmony_ci                                uint8_t laneidx, uint32_t* protected_load_pc) {
24341cb0ef41Sopenharmony_ci  Operand src_op = liftoff::GetMemOp(this, addr, offset_reg, offset_imm);
24351cb0ef41Sopenharmony_ci
24361cb0ef41Sopenharmony_ci  MachineType mem_type = type.mem_type();
24371cb0ef41Sopenharmony_ci  if (mem_type == MachineType::Int8()) {
24381cb0ef41Sopenharmony_ci    Pinsrb(dst.fp(), src.fp(), src_op, laneidx, protected_load_pc);
24391cb0ef41Sopenharmony_ci  } else if (mem_type == MachineType::Int16()) {
24401cb0ef41Sopenharmony_ci    Pinsrw(dst.fp(), src.fp(), src_op, laneidx, protected_load_pc);
24411cb0ef41Sopenharmony_ci  } else if (mem_type == MachineType::Int32()) {
24421cb0ef41Sopenharmony_ci    Pinsrd(dst.fp(), src.fp(), src_op, laneidx, protected_load_pc);
24431cb0ef41Sopenharmony_ci  } else {
24441cb0ef41Sopenharmony_ci    DCHECK_EQ(MachineType::Int64(), mem_type);
24451cb0ef41Sopenharmony_ci    Pinsrq(dst.fp(), src.fp(), src_op, laneidx, protected_load_pc);
24461cb0ef41Sopenharmony_ci  }
24471cb0ef41Sopenharmony_ci}
24481cb0ef41Sopenharmony_ci
24491cb0ef41Sopenharmony_civoid LiftoffAssembler::StoreLane(Register dst, Register offset,
24501cb0ef41Sopenharmony_ci                                 uintptr_t offset_imm, LiftoffRegister src,
24511cb0ef41Sopenharmony_ci                                 StoreType type, uint8_t lane,
24521cb0ef41Sopenharmony_ci                                 uint32_t* protected_store_pc) {
24531cb0ef41Sopenharmony_ci  Operand dst_op = liftoff::GetMemOp(this, dst, offset, offset_imm);
24541cb0ef41Sopenharmony_ci  if (protected_store_pc) *protected_store_pc = pc_offset();
24551cb0ef41Sopenharmony_ci  MachineRepresentation rep = type.mem_rep();
24561cb0ef41Sopenharmony_ci  if (rep == MachineRepresentation::kWord8) {
24571cb0ef41Sopenharmony_ci    Pextrb(dst_op, src.fp(), lane);
24581cb0ef41Sopenharmony_ci  } else if (rep == MachineRepresentation::kWord16) {
24591cb0ef41Sopenharmony_ci    Pextrw(dst_op, src.fp(), lane);
24601cb0ef41Sopenharmony_ci  } else if (rep == MachineRepresentation::kWord32) {
24611cb0ef41Sopenharmony_ci    S128Store32Lane(dst_op, src.fp(), lane);
24621cb0ef41Sopenharmony_ci  } else {
24631cb0ef41Sopenharmony_ci    DCHECK_EQ(MachineRepresentation::kWord64, rep);
24641cb0ef41Sopenharmony_ci    S128Store64Lane(dst_op, src.fp(), lane);
24651cb0ef41Sopenharmony_ci  }
24661cb0ef41Sopenharmony_ci}
24671cb0ef41Sopenharmony_ci
24681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shuffle(LiftoffRegister dst,
24691cb0ef41Sopenharmony_ci                                          LiftoffRegister lhs,
24701cb0ef41Sopenharmony_ci                                          LiftoffRegister rhs,
24711cb0ef41Sopenharmony_ci                                          const uint8_t shuffle[16],
24721cb0ef41Sopenharmony_ci                                          bool is_swizzle) {
24731cb0ef41Sopenharmony_ci  if (is_swizzle) {
24741cb0ef41Sopenharmony_ci    uint32_t imms[4];
24751cb0ef41Sopenharmony_ci    // Shuffles that use just 1 operand are called swizzles, rhs can be ignored.
24761cb0ef41Sopenharmony_ci    wasm::SimdShuffle::Pack16Lanes(imms, shuffle);
24771cb0ef41Sopenharmony_ci    TurboAssembler::Move(kScratchDoubleReg, make_uint64(imms[3], imms[2]),
24781cb0ef41Sopenharmony_ci                         make_uint64(imms[1], imms[0]));
24791cb0ef41Sopenharmony_ci    Pshufb(dst.fp(), lhs.fp(), kScratchDoubleReg);
24801cb0ef41Sopenharmony_ci    return;
24811cb0ef41Sopenharmony_ci  }
24821cb0ef41Sopenharmony_ci
24831cb0ef41Sopenharmony_ci  uint64_t mask1[2] = {};
24841cb0ef41Sopenharmony_ci  for (int i = 15; i >= 0; i--) {
24851cb0ef41Sopenharmony_ci    uint8_t lane = shuffle[i];
24861cb0ef41Sopenharmony_ci    int j = i >> 3;
24871cb0ef41Sopenharmony_ci    mask1[j] <<= 8;
24881cb0ef41Sopenharmony_ci    mask1[j] |= lane < kSimd128Size ? lane : 0x80;
24891cb0ef41Sopenharmony_ci  }
24901cb0ef41Sopenharmony_ci  TurboAssembler::Move(liftoff::kScratchDoubleReg2, mask1[1], mask1[0]);
24911cb0ef41Sopenharmony_ci  Pshufb(kScratchDoubleReg, lhs.fp(), liftoff::kScratchDoubleReg2);
24921cb0ef41Sopenharmony_ci
24931cb0ef41Sopenharmony_ci  uint64_t mask2[2] = {};
24941cb0ef41Sopenharmony_ci  for (int i = 15; i >= 0; i--) {
24951cb0ef41Sopenharmony_ci    uint8_t lane = shuffle[i];
24961cb0ef41Sopenharmony_ci    int j = i >> 3;
24971cb0ef41Sopenharmony_ci    mask2[j] <<= 8;
24981cb0ef41Sopenharmony_ci    mask2[j] |= lane >= kSimd128Size ? (lane & 0x0F) : 0x80;
24991cb0ef41Sopenharmony_ci  }
25001cb0ef41Sopenharmony_ci  TurboAssembler::Move(liftoff::kScratchDoubleReg2, mask2[1], mask2[0]);
25011cb0ef41Sopenharmony_ci
25021cb0ef41Sopenharmony_ci  Pshufb(dst.fp(), rhs.fp(), liftoff::kScratchDoubleReg2);
25031cb0ef41Sopenharmony_ci  Por(dst.fp(), kScratchDoubleReg);
25041cb0ef41Sopenharmony_ci}
25051cb0ef41Sopenharmony_ci
25061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_swizzle(LiftoffRegister dst,
25071cb0ef41Sopenharmony_ci                                          LiftoffRegister lhs,
25081cb0ef41Sopenharmony_ci                                          LiftoffRegister rhs) {
25091cb0ef41Sopenharmony_ci  I8x16Swizzle(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg,
25101cb0ef41Sopenharmony_ci               kScratchRegister);
25111cb0ef41Sopenharmony_ci}
25121cb0ef41Sopenharmony_ci
25131cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_popcnt(LiftoffRegister dst,
25141cb0ef41Sopenharmony_ci                                         LiftoffRegister src) {
25151cb0ef41Sopenharmony_ci  I8x16Popcnt(dst.fp(), src.fp(), kScratchDoubleReg,
25161cb0ef41Sopenharmony_ci              liftoff::kScratchDoubleReg2, kScratchRegister);
25171cb0ef41Sopenharmony_ci}
25181cb0ef41Sopenharmony_ci
25191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_splat(LiftoffRegister dst,
25201cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25211cb0ef41Sopenharmony_ci  I8x16Splat(dst.fp(), src.gp(), kScratchDoubleReg);
25221cb0ef41Sopenharmony_ci}
25231cb0ef41Sopenharmony_ci
25241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_splat(LiftoffRegister dst,
25251cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25261cb0ef41Sopenharmony_ci  I16x8Splat(dst.fp(), src.gp());
25271cb0ef41Sopenharmony_ci}
25281cb0ef41Sopenharmony_ci
25291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_splat(LiftoffRegister dst,
25301cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25311cb0ef41Sopenharmony_ci  Movd(dst.fp(), src.gp());
25321cb0ef41Sopenharmony_ci  Pshufd(dst.fp(), dst.fp(), static_cast<uint8_t>(0));
25331cb0ef41Sopenharmony_ci}
25341cb0ef41Sopenharmony_ci
25351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_splat(LiftoffRegister dst,
25361cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25371cb0ef41Sopenharmony_ci  Movq(dst.fp(), src.gp());
25381cb0ef41Sopenharmony_ci  Movddup(dst.fp(), dst.fp());
25391cb0ef41Sopenharmony_ci}
25401cb0ef41Sopenharmony_ci
25411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_splat(LiftoffRegister dst,
25421cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25431cb0ef41Sopenharmony_ci  F32x4Splat(dst.fp(), src.fp());
25441cb0ef41Sopenharmony_ci}
25451cb0ef41Sopenharmony_ci
25461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_splat(LiftoffRegister dst,
25471cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
25481cb0ef41Sopenharmony_ci  Movddup(dst.fp(), src.fp());
25491cb0ef41Sopenharmony_ci}
25501cb0ef41Sopenharmony_ci
25511cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_eq(LiftoffRegister dst, LiftoffRegister lhs,
25521cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
25531cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqb, &Assembler::pcmpeqb>(
25541cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
25551cb0ef41Sopenharmony_ci}
25561cb0ef41Sopenharmony_ci
25571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ne(LiftoffRegister dst, LiftoffRegister lhs,
25581cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
25591cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqb, &Assembler::pcmpeqb>(
25601cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
25611cb0ef41Sopenharmony_ci  Pcmpeqb(kScratchDoubleReg, kScratchDoubleReg);
25621cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
25631cb0ef41Sopenharmony_ci}
25641cb0ef41Sopenharmony_ci
25651cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
25661cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
25671cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpcmpgtb,
25681cb0ef41Sopenharmony_ci                                       &Assembler::pcmpgtb>(this, dst, lhs,
25691cb0ef41Sopenharmony_ci                                                            rhs);
25701cb0ef41Sopenharmony_ci}
25711cb0ef41Sopenharmony_ci
25721cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
25731cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
25741cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
25751cb0ef41Sopenharmony_ci  if (dst == rhs) {
25761cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
25771cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
25781cb0ef41Sopenharmony_ci  }
25791cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxub, &Assembler::pmaxub>(
25801cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
25811cb0ef41Sopenharmony_ci  Pcmpeqb(dst.fp(), ref);
25821cb0ef41Sopenharmony_ci  Pcmpeqb(kScratchDoubleReg, kScratchDoubleReg);
25831cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
25841cb0ef41Sopenharmony_ci}
25851cb0ef41Sopenharmony_ci
25861cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
25871cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
25881cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
25891cb0ef41Sopenharmony_ci  if (dst == rhs) {
25901cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
25911cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
25921cb0ef41Sopenharmony_ci  }
25931cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsb, &Assembler::pminsb>(
25941cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
25951cb0ef41Sopenharmony_ci  Pcmpeqb(dst.fp(), ref);
25961cb0ef41Sopenharmony_ci}
25971cb0ef41Sopenharmony_ci
25981cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
25991cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26001cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
26011cb0ef41Sopenharmony_ci  if (dst == rhs) {
26021cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
26031cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
26041cb0ef41Sopenharmony_ci  }
26051cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminub, &Assembler::pminub>(
26061cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26071cb0ef41Sopenharmony_ci  Pcmpeqb(dst.fp(), ref);
26081cb0ef41Sopenharmony_ci}
26091cb0ef41Sopenharmony_ci
26101cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_eq(LiftoffRegister dst, LiftoffRegister lhs,
26111cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
26121cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqw, &Assembler::pcmpeqw>(
26131cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26141cb0ef41Sopenharmony_ci}
26151cb0ef41Sopenharmony_ci
26161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ne(LiftoffRegister dst, LiftoffRegister lhs,
26171cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
26181cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqw, &Assembler::pcmpeqw>(
26191cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26201cb0ef41Sopenharmony_ci  Pcmpeqw(kScratchDoubleReg, kScratchDoubleReg);
26211cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
26221cb0ef41Sopenharmony_ci}
26231cb0ef41Sopenharmony_ci
26241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
26251cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26261cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpcmpgtw,
26271cb0ef41Sopenharmony_ci                                       &Assembler::pcmpgtw>(this, dst, lhs,
26281cb0ef41Sopenharmony_ci                                                            rhs);
26291cb0ef41Sopenharmony_ci}
26301cb0ef41Sopenharmony_ci
26311cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
26321cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26331cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
26341cb0ef41Sopenharmony_ci  if (dst == rhs) {
26351cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
26361cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
26371cb0ef41Sopenharmony_ci  }
26381cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxuw, &Assembler::pmaxuw>(
26391cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26401cb0ef41Sopenharmony_ci  Pcmpeqw(dst.fp(), ref);
26411cb0ef41Sopenharmony_ci  Pcmpeqw(kScratchDoubleReg, kScratchDoubleReg);
26421cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
26431cb0ef41Sopenharmony_ci}
26441cb0ef41Sopenharmony_ci
26451cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
26461cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26471cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
26481cb0ef41Sopenharmony_ci  if (dst == rhs) {
26491cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
26501cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
26511cb0ef41Sopenharmony_ci  }
26521cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsw, &Assembler::pminsw>(
26531cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26541cb0ef41Sopenharmony_ci  Pcmpeqw(dst.fp(), ref);
26551cb0ef41Sopenharmony_ci}
26561cb0ef41Sopenharmony_ci
26571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
26581cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26591cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
26601cb0ef41Sopenharmony_ci  if (dst == rhs) {
26611cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
26621cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
26631cb0ef41Sopenharmony_ci  }
26641cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminuw, &Assembler::pminuw>(
26651cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
26661cb0ef41Sopenharmony_ci  Pcmpeqw(dst.fp(), ref);
26671cb0ef41Sopenharmony_ci}
26681cb0ef41Sopenharmony_ci
26691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_eq(LiftoffRegister dst, LiftoffRegister lhs,
26701cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
26711cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqd, &Assembler::pcmpeqd>(
26721cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26731cb0ef41Sopenharmony_ci}
26741cb0ef41Sopenharmony_ci
26751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ne(LiftoffRegister dst, LiftoffRegister lhs,
26761cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
26771cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqd, &Assembler::pcmpeqd>(
26781cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
26791cb0ef41Sopenharmony_ci  Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
26801cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
26811cb0ef41Sopenharmony_ci}
26821cb0ef41Sopenharmony_ci
26831cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
26841cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26851cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpcmpgtd,
26861cb0ef41Sopenharmony_ci                                       &Assembler::pcmpgtd>(this, dst, lhs,
26871cb0ef41Sopenharmony_ci                                                            rhs);
26881cb0ef41Sopenharmony_ci}
26891cb0ef41Sopenharmony_ci
26901cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_gt_u(LiftoffRegister dst, LiftoffRegister lhs,
26911cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
26921cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
26931cb0ef41Sopenharmony_ci  if (dst == rhs) {
26941cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
26951cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
26961cb0ef41Sopenharmony_ci  }
26971cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxud, &Assembler::pmaxud>(
26981cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
26991cb0ef41Sopenharmony_ci  Pcmpeqd(dst.fp(), ref);
27001cb0ef41Sopenharmony_ci  Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
27011cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
27021cb0ef41Sopenharmony_ci}
27031cb0ef41Sopenharmony_ci
27041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
27051cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27061cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
27071cb0ef41Sopenharmony_ci  if (dst == rhs) {
27081cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
27091cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
27101cb0ef41Sopenharmony_ci  }
27111cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsd, &Assembler::pminsd>(
27121cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
27131cb0ef41Sopenharmony_ci  Pcmpeqd(dst.fp(), ref);
27141cb0ef41Sopenharmony_ci}
27151cb0ef41Sopenharmony_ci
27161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_ge_u(LiftoffRegister dst, LiftoffRegister lhs,
27171cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27181cb0ef41Sopenharmony_ci  DoubleRegister ref = rhs.fp();
27191cb0ef41Sopenharmony_ci  if (dst == rhs) {
27201cb0ef41Sopenharmony_ci    Movaps(kScratchDoubleReg, rhs.fp());
27211cb0ef41Sopenharmony_ci    ref = kScratchDoubleReg;
27221cb0ef41Sopenharmony_ci  }
27231cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminud, &Assembler::pminud>(
27241cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
27251cb0ef41Sopenharmony_ci  Pcmpeqd(dst.fp(), ref);
27261cb0ef41Sopenharmony_ci}
27271cb0ef41Sopenharmony_ci
27281cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_eq(LiftoffRegister dst, LiftoffRegister lhs,
27291cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27301cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqq, &Assembler::pcmpeqq>(
27311cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
27321cb0ef41Sopenharmony_ci}
27331cb0ef41Sopenharmony_ci
27341cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_ne(LiftoffRegister dst, LiftoffRegister lhs,
27351cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27361cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpcmpeqq, &Assembler::pcmpeqq>(
27371cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, SSE4_1);
27381cb0ef41Sopenharmony_ci  Pcmpeqq(kScratchDoubleReg, kScratchDoubleReg);
27391cb0ef41Sopenharmony_ci  Pxor(dst.fp(), kScratchDoubleReg);
27401cb0ef41Sopenharmony_ci}
27411cb0ef41Sopenharmony_ci
27421cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_gt_s(LiftoffRegister dst, LiftoffRegister lhs,
27431cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27441cb0ef41Sopenharmony_ci  // Different register alias requirements depending on CpuFeatures supported:
27451cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX) || CpuFeatures::IsSupported(SSE4_2)) {
27461cb0ef41Sopenharmony_ci    // 1. AVX, or SSE4_2 no requirements (I64x2GtS takes care of aliasing).
27471cb0ef41Sopenharmony_ci    I64x2GtS(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
27481cb0ef41Sopenharmony_ci  } else {
27491cb0ef41Sopenharmony_ci    // 2. Else, dst != lhs && dst != rhs (lhs == rhs is ok).
27501cb0ef41Sopenharmony_ci    if (dst == lhs || dst == rhs) {
27511cb0ef41Sopenharmony_ci      I64x2GtS(liftoff::kScratchDoubleReg2, lhs.fp(), rhs.fp(),
27521cb0ef41Sopenharmony_ci               kScratchDoubleReg);
27531cb0ef41Sopenharmony_ci      movaps(dst.fp(), liftoff::kScratchDoubleReg2);
27541cb0ef41Sopenharmony_ci    } else {
27551cb0ef41Sopenharmony_ci      I64x2GtS(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
27561cb0ef41Sopenharmony_ci    }
27571cb0ef41Sopenharmony_ci  }
27581cb0ef41Sopenharmony_ci}
27591cb0ef41Sopenharmony_ci
27601cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_ge_s(LiftoffRegister dst, LiftoffRegister lhs,
27611cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
27621cb0ef41Sopenharmony_ci  // Different register alias requirements depending on CpuFeatures supported:
27631cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
27641cb0ef41Sopenharmony_ci    // 1. AVX, no requirements.
27651cb0ef41Sopenharmony_ci    I64x2GeS(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
27661cb0ef41Sopenharmony_ci  } else if (CpuFeatures::IsSupported(SSE4_2)) {
27671cb0ef41Sopenharmony_ci    // 2. SSE4_2, dst != lhs.
27681cb0ef41Sopenharmony_ci    if (dst == lhs) {
27691cb0ef41Sopenharmony_ci      I64x2GeS(liftoff::kScratchDoubleReg2, lhs.fp(), rhs.fp(),
27701cb0ef41Sopenharmony_ci               kScratchDoubleReg);
27711cb0ef41Sopenharmony_ci      movaps(dst.fp(), liftoff::kScratchDoubleReg2);
27721cb0ef41Sopenharmony_ci    } else {
27731cb0ef41Sopenharmony_ci      I64x2GeS(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
27741cb0ef41Sopenharmony_ci    }
27751cb0ef41Sopenharmony_ci  } else {
27761cb0ef41Sopenharmony_ci    // 3. Else, dst != lhs && dst != rhs (lhs == rhs is ok).
27771cb0ef41Sopenharmony_ci    if (dst == lhs || dst == rhs) {
27781cb0ef41Sopenharmony_ci      I64x2GeS(liftoff::kScratchDoubleReg2, lhs.fp(), rhs.fp(),
27791cb0ef41Sopenharmony_ci               kScratchDoubleReg);
27801cb0ef41Sopenharmony_ci      movaps(dst.fp(), liftoff::kScratchDoubleReg2);
27811cb0ef41Sopenharmony_ci    } else {
27821cb0ef41Sopenharmony_ci      I64x2GeS(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
27831cb0ef41Sopenharmony_ci    }
27841cb0ef41Sopenharmony_ci  }
27851cb0ef41Sopenharmony_ci}
27861cb0ef41Sopenharmony_ci
27871cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_eq(LiftoffRegister dst, LiftoffRegister lhs,
27881cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27891cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vcmpeqps, &Assembler::cmpeqps>(
27901cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
27911cb0ef41Sopenharmony_ci}
27921cb0ef41Sopenharmony_ci
27931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_ne(LiftoffRegister dst, LiftoffRegister lhs,
27941cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
27951cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vcmpneqps,
27961cb0ef41Sopenharmony_ci                                    &Assembler::cmpneqps>(this, dst, lhs, rhs);
27971cb0ef41Sopenharmony_ci}
27981cb0ef41Sopenharmony_ci
27991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_lt(LiftoffRegister dst, LiftoffRegister lhs,
28001cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28011cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vcmpltps,
28021cb0ef41Sopenharmony_ci                                       &Assembler::cmpltps>(this, dst, lhs,
28031cb0ef41Sopenharmony_ci                                                            rhs);
28041cb0ef41Sopenharmony_ci}
28051cb0ef41Sopenharmony_ci
28061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_le(LiftoffRegister dst, LiftoffRegister lhs,
28071cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28081cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vcmpleps,
28091cb0ef41Sopenharmony_ci                                       &Assembler::cmpleps>(this, dst, lhs,
28101cb0ef41Sopenharmony_ci                                                            rhs);
28111cb0ef41Sopenharmony_ci}
28121cb0ef41Sopenharmony_ci
28131cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_eq(LiftoffRegister dst, LiftoffRegister lhs,
28141cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28151cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vcmpeqpd, &Assembler::cmpeqpd>(
28161cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
28171cb0ef41Sopenharmony_ci}
28181cb0ef41Sopenharmony_ci
28191cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_ne(LiftoffRegister dst, LiftoffRegister lhs,
28201cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28211cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vcmpneqpd,
28221cb0ef41Sopenharmony_ci                                    &Assembler::cmpneqpd>(this, dst, lhs, rhs);
28231cb0ef41Sopenharmony_ci}
28241cb0ef41Sopenharmony_ci
28251cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_lt(LiftoffRegister dst, LiftoffRegister lhs,
28261cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28271cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vcmpltpd,
28281cb0ef41Sopenharmony_ci                                       &Assembler::cmpltpd>(this, dst, lhs,
28291cb0ef41Sopenharmony_ci                                                            rhs);
28301cb0ef41Sopenharmony_ci}
28311cb0ef41Sopenharmony_ci
28321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_le(LiftoffRegister dst, LiftoffRegister lhs,
28331cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28341cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vcmplepd,
28351cb0ef41Sopenharmony_ci                                       &Assembler::cmplepd>(this, dst, lhs,
28361cb0ef41Sopenharmony_ci                                                            rhs);
28371cb0ef41Sopenharmony_ci}
28381cb0ef41Sopenharmony_ci
28391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_const(LiftoffRegister dst,
28401cb0ef41Sopenharmony_ci                                       const uint8_t imms[16]) {
28411cb0ef41Sopenharmony_ci  uint64_t vals[2];
28421cb0ef41Sopenharmony_ci  memcpy(vals, imms, sizeof(vals));
28431cb0ef41Sopenharmony_ci  TurboAssembler::Move(dst.fp(), vals[1], vals[0]);
28441cb0ef41Sopenharmony_ci}
28451cb0ef41Sopenharmony_ci
28461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_not(LiftoffRegister dst, LiftoffRegister src) {
28471cb0ef41Sopenharmony_ci  S128Not(dst.fp(), src.fp(), kScratchDoubleReg);
28481cb0ef41Sopenharmony_ci}
28491cb0ef41Sopenharmony_ci
28501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_and(LiftoffRegister dst, LiftoffRegister lhs,
28511cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28521cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpand, &Assembler::pand>(
28531cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
28541cb0ef41Sopenharmony_ci}
28551cb0ef41Sopenharmony_ci
28561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_or(LiftoffRegister dst, LiftoffRegister lhs,
28571cb0ef41Sopenharmony_ci                                    LiftoffRegister rhs) {
28581cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpor, &Assembler::por>(
28591cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
28601cb0ef41Sopenharmony_ci}
28611cb0ef41Sopenharmony_ci
28621cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_xor(LiftoffRegister dst, LiftoffRegister lhs,
28631cb0ef41Sopenharmony_ci                                     LiftoffRegister rhs) {
28641cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpxor, &Assembler::pxor>(
28651cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
28661cb0ef41Sopenharmony_ci}
28671cb0ef41Sopenharmony_ci
28681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_select(LiftoffRegister dst,
28691cb0ef41Sopenharmony_ci                                        LiftoffRegister src1,
28701cb0ef41Sopenharmony_ci                                        LiftoffRegister src2,
28711cb0ef41Sopenharmony_ci                                        LiftoffRegister mask) {
28721cb0ef41Sopenharmony_ci  // Ensure that we don't overwrite any inputs with the movaps below.
28731cb0ef41Sopenharmony_ci  DCHECK_NE(dst, src1);
28741cb0ef41Sopenharmony_ci  DCHECK_NE(dst, src2);
28751cb0ef41Sopenharmony_ci  if (!CpuFeatures::IsSupported(AVX) && dst != mask) {
28761cb0ef41Sopenharmony_ci    movaps(dst.fp(), mask.fp());
28771cb0ef41Sopenharmony_ci    S128Select(dst.fp(), dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
28781cb0ef41Sopenharmony_ci  } else {
28791cb0ef41Sopenharmony_ci    S128Select(dst.fp(), mask.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
28801cb0ef41Sopenharmony_ci  }
28811cb0ef41Sopenharmony_ci}
28821cb0ef41Sopenharmony_ci
28831cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_neg(LiftoffRegister dst,
28841cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
28851cb0ef41Sopenharmony_ci  if (dst.fp() == src.fp()) {
28861cb0ef41Sopenharmony_ci    Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
28871cb0ef41Sopenharmony_ci    Psignb(dst.fp(), kScratchDoubleReg);
28881cb0ef41Sopenharmony_ci  } else {
28891cb0ef41Sopenharmony_ci    Pxor(dst.fp(), dst.fp());
28901cb0ef41Sopenharmony_ci    Psubb(dst.fp(), src.fp());
28911cb0ef41Sopenharmony_ci  }
28921cb0ef41Sopenharmony_ci}
28931cb0ef41Sopenharmony_ci
28941cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_v128_anytrue(LiftoffRegister dst,
28951cb0ef41Sopenharmony_ci                                         LiftoffRegister src) {
28961cb0ef41Sopenharmony_ci  liftoff::EmitAnyTrue(this, dst, src);
28971cb0ef41Sopenharmony_ci}
28981cb0ef41Sopenharmony_ci
28991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_alltrue(LiftoffRegister dst,
29001cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
29011cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue<&TurboAssembler::Pcmpeqb>(this, dst, src);
29021cb0ef41Sopenharmony_ci}
29031cb0ef41Sopenharmony_ci
29041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_bitmask(LiftoffRegister dst,
29051cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
29061cb0ef41Sopenharmony_ci  Pmovmskb(dst.gp(), src.fp());
29071cb0ef41Sopenharmony_ci}
29081cb0ef41Sopenharmony_ci
29091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shl(LiftoffRegister dst, LiftoffRegister lhs,
29101cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
29111cb0ef41Sopenharmony_ci  I8x16Shl(dst.fp(), lhs.fp(), rhs.gp(), kScratchRegister, kScratchDoubleReg,
29121cb0ef41Sopenharmony_ci           liftoff::kScratchDoubleReg2);
29131cb0ef41Sopenharmony_ci}
29141cb0ef41Sopenharmony_ci
29151cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shli(LiftoffRegister dst, LiftoffRegister lhs,
29161cb0ef41Sopenharmony_ci                                       int32_t rhs) {
29171cb0ef41Sopenharmony_ci  I8x16Shl(dst.fp(), lhs.fp(), rhs, kScratchRegister, kScratchDoubleReg);
29181cb0ef41Sopenharmony_ci}
29191cb0ef41Sopenharmony_ci
29201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shr_s(LiftoffRegister dst,
29211cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
29221cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
29231cb0ef41Sopenharmony_ci  I8x16ShrS(dst.fp(), lhs.fp(), rhs.gp(), kScratchRegister, kScratchDoubleReg,
29241cb0ef41Sopenharmony_ci            liftoff::kScratchDoubleReg2);
29251cb0ef41Sopenharmony_ci}
29261cb0ef41Sopenharmony_ci
29271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shri_s(LiftoffRegister dst,
29281cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
29291cb0ef41Sopenharmony_ci  I8x16ShrS(dst.fp(), lhs.fp(), rhs, kScratchDoubleReg);
29301cb0ef41Sopenharmony_ci}
29311cb0ef41Sopenharmony_ci
29321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shr_u(LiftoffRegister dst,
29331cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
29341cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
29351cb0ef41Sopenharmony_ci  I8x16ShrU(dst.fp(), lhs.fp(), rhs.gp(), kScratchRegister, kScratchDoubleReg,
29361cb0ef41Sopenharmony_ci            liftoff::kScratchDoubleReg2);
29371cb0ef41Sopenharmony_ci}
29381cb0ef41Sopenharmony_ci
29391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_shri_u(LiftoffRegister dst,
29401cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
29411cb0ef41Sopenharmony_ci  I8x16ShrU(dst.fp(), lhs.fp(), rhs, kScratchRegister, kScratchDoubleReg);
29421cb0ef41Sopenharmony_ci}
29431cb0ef41Sopenharmony_ci
29441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add(LiftoffRegister dst, LiftoffRegister lhs,
29451cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
29461cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddb, &Assembler::paddb>(
29471cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29481cb0ef41Sopenharmony_ci}
29491cb0ef41Sopenharmony_ci
29501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add_sat_s(LiftoffRegister dst,
29511cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
29521cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
29531cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddsb, &Assembler::paddsb>(
29541cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29551cb0ef41Sopenharmony_ci}
29561cb0ef41Sopenharmony_ci
29571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_add_sat_u(LiftoffRegister dst,
29581cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
29591cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
29601cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddusb, &Assembler::paddusb>(
29611cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29621cb0ef41Sopenharmony_ci}
29631cb0ef41Sopenharmony_ci
29641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub(LiftoffRegister dst, LiftoffRegister lhs,
29651cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
29661cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubb, &Assembler::psubb>(
29671cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29681cb0ef41Sopenharmony_ci}
29691cb0ef41Sopenharmony_ci
29701cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub_sat_s(LiftoffRegister dst,
29711cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
29721cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
29731cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubsb, &Assembler::psubsb>(
29741cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29751cb0ef41Sopenharmony_ci}
29761cb0ef41Sopenharmony_ci
29771cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sub_sat_u(LiftoffRegister dst,
29781cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
29791cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
29801cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubusb,
29811cb0ef41Sopenharmony_ci                                       &Assembler::psubusb>(this, dst, lhs,
29821cb0ef41Sopenharmony_ci                                                            rhs);
29831cb0ef41Sopenharmony_ci}
29841cb0ef41Sopenharmony_ci
29851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_min_s(LiftoffRegister dst,
29861cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
29871cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
29881cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsb, &Assembler::pminsb>(
29891cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
29901cb0ef41Sopenharmony_ci}
29911cb0ef41Sopenharmony_ci
29921cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_min_u(LiftoffRegister dst,
29931cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
29941cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
29951cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminub, &Assembler::pminub>(
29961cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
29971cb0ef41Sopenharmony_ci}
29981cb0ef41Sopenharmony_ci
29991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_max_s(LiftoffRegister dst,
30001cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
30011cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
30021cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxsb, &Assembler::pmaxsb>(
30031cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
30041cb0ef41Sopenharmony_ci}
30051cb0ef41Sopenharmony_ci
30061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_max_u(LiftoffRegister dst,
30071cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
30081cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
30091cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxub, &Assembler::pmaxub>(
30101cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30111cb0ef41Sopenharmony_ci}
30121cb0ef41Sopenharmony_ci
30131cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_neg(LiftoffRegister dst,
30141cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
30151cb0ef41Sopenharmony_ci  if (dst.fp() == src.fp()) {
30161cb0ef41Sopenharmony_ci    Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
30171cb0ef41Sopenharmony_ci    Psignw(dst.fp(), kScratchDoubleReg);
30181cb0ef41Sopenharmony_ci  } else {
30191cb0ef41Sopenharmony_ci    Pxor(dst.fp(), dst.fp());
30201cb0ef41Sopenharmony_ci    Psubw(dst.fp(), src.fp());
30211cb0ef41Sopenharmony_ci  }
30221cb0ef41Sopenharmony_ci}
30231cb0ef41Sopenharmony_ci
30241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_alltrue(LiftoffRegister dst,
30251cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
30261cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue<&TurboAssembler::Pcmpeqw>(this, dst, src);
30271cb0ef41Sopenharmony_ci}
30281cb0ef41Sopenharmony_ci
30291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_bitmask(LiftoffRegister dst,
30301cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
30311cb0ef41Sopenharmony_ci  XMMRegister tmp = kScratchDoubleReg;
30321cb0ef41Sopenharmony_ci  Packsswb(tmp, src.fp());
30331cb0ef41Sopenharmony_ci  Pmovmskb(dst.gp(), tmp);
30341cb0ef41Sopenharmony_ci  shrq(dst.gp(), Immediate(8));
30351cb0ef41Sopenharmony_ci}
30361cb0ef41Sopenharmony_ci
30371cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shl(LiftoffRegister dst, LiftoffRegister lhs,
30381cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
30391cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsllw, &Assembler::psllw, 4>(this, dst,
30401cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
30411cb0ef41Sopenharmony_ci}
30421cb0ef41Sopenharmony_ci
30431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shli(LiftoffRegister dst, LiftoffRegister lhs,
30441cb0ef41Sopenharmony_ci                                       int32_t rhs) {
30451cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsllw, &Assembler::psllw, 4>(
30461cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30471cb0ef41Sopenharmony_ci}
30481cb0ef41Sopenharmony_ci
30491cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shr_s(LiftoffRegister dst,
30501cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
30511cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
30521cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsraw, &Assembler::psraw, 4>(this, dst,
30531cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
30541cb0ef41Sopenharmony_ci}
30551cb0ef41Sopenharmony_ci
30561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shri_s(LiftoffRegister dst,
30571cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
30581cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsraw, &Assembler::psraw, 4>(
30591cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30601cb0ef41Sopenharmony_ci}
30611cb0ef41Sopenharmony_ci
30621cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shr_u(LiftoffRegister dst,
30631cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
30641cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
30651cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsrlw, &Assembler::psrlw, 4>(this, dst,
30661cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
30671cb0ef41Sopenharmony_ci}
30681cb0ef41Sopenharmony_ci
30691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_shri_u(LiftoffRegister dst,
30701cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
30711cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsrlw, &Assembler::psrlw, 4>(
30721cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30731cb0ef41Sopenharmony_ci}
30741cb0ef41Sopenharmony_ci
30751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add(LiftoffRegister dst, LiftoffRegister lhs,
30761cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
30771cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddw, &Assembler::paddw>(
30781cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30791cb0ef41Sopenharmony_ci}
30801cb0ef41Sopenharmony_ci
30811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add_sat_s(LiftoffRegister dst,
30821cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
30831cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
30841cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddsw, &Assembler::paddsw>(
30851cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30861cb0ef41Sopenharmony_ci}
30871cb0ef41Sopenharmony_ci
30881cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_add_sat_u(LiftoffRegister dst,
30891cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
30901cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
30911cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddusw, &Assembler::paddusw>(
30921cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30931cb0ef41Sopenharmony_ci}
30941cb0ef41Sopenharmony_ci
30951cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub(LiftoffRegister dst, LiftoffRegister lhs,
30961cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
30971cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubw, &Assembler::psubw>(
30981cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
30991cb0ef41Sopenharmony_ci}
31001cb0ef41Sopenharmony_ci
31011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub_sat_s(LiftoffRegister dst,
31021cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
31031cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
31041cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubsw, &Assembler::psubsw>(
31051cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
31061cb0ef41Sopenharmony_ci}
31071cb0ef41Sopenharmony_ci
31081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sub_sat_u(LiftoffRegister dst,
31091cb0ef41Sopenharmony_ci                                            LiftoffRegister lhs,
31101cb0ef41Sopenharmony_ci                                            LiftoffRegister rhs) {
31111cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubusw,
31121cb0ef41Sopenharmony_ci                                       &Assembler::psubusw>(this, dst, lhs,
31131cb0ef41Sopenharmony_ci                                                            rhs);
31141cb0ef41Sopenharmony_ci}
31151cb0ef41Sopenharmony_ci
31161cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_mul(LiftoffRegister dst, LiftoffRegister lhs,
31171cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
31181cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmullw, &Assembler::pmullw>(
31191cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
31201cb0ef41Sopenharmony_ci}
31211cb0ef41Sopenharmony_ci
31221cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_min_s(LiftoffRegister dst,
31231cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
31241cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
31251cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsw, &Assembler::pminsw>(
31261cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
31271cb0ef41Sopenharmony_ci}
31281cb0ef41Sopenharmony_ci
31291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_min_u(LiftoffRegister dst,
31301cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
31311cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
31321cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminuw, &Assembler::pminuw>(
31331cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
31341cb0ef41Sopenharmony_ci}
31351cb0ef41Sopenharmony_ci
31361cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_max_s(LiftoffRegister dst,
31371cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
31381cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
31391cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxsw, &Assembler::pmaxsw>(
31401cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
31411cb0ef41Sopenharmony_ci}
31421cb0ef41Sopenharmony_ci
31431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_max_u(LiftoffRegister dst,
31441cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
31451cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
31461cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxuw, &Assembler::pmaxuw>(
31471cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
31481cb0ef41Sopenharmony_ci}
31491cb0ef41Sopenharmony_ci
31501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_s(LiftoffRegister dst,
31511cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
31521cb0ef41Sopenharmony_ci  I16x8ExtAddPairwiseI8x16S(dst.fp(), src.fp(), kScratchDoubleReg,
31531cb0ef41Sopenharmony_ci                            kScratchRegister);
31541cb0ef41Sopenharmony_ci}
31551cb0ef41Sopenharmony_ci
31561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_u(LiftoffRegister dst,
31571cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
31581cb0ef41Sopenharmony_ci  I16x8ExtAddPairwiseI8x16U(dst.fp(), src.fp(), kScratchRegister);
31591cb0ef41Sopenharmony_ci}
31601cb0ef41Sopenharmony_ci
31611cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_low_i8x16_s(LiftoffRegister dst,
31621cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
31631cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
31641cb0ef41Sopenharmony_ci  I16x8ExtMulLow(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg,
31651cb0ef41Sopenharmony_ci                 /*is_signed=*/true);
31661cb0ef41Sopenharmony_ci}
31671cb0ef41Sopenharmony_ci
31681cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_low_i8x16_u(LiftoffRegister dst,
31691cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
31701cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
31711cb0ef41Sopenharmony_ci  I16x8ExtMulLow(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg,
31721cb0ef41Sopenharmony_ci                 /*is_signed=*/false);
31731cb0ef41Sopenharmony_ci}
31741cb0ef41Sopenharmony_ci
31751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_high_i8x16_s(LiftoffRegister dst,
31761cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
31771cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
31781cb0ef41Sopenharmony_ci  I16x8ExtMulHighS(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
31791cb0ef41Sopenharmony_ci}
31801cb0ef41Sopenharmony_ci
31811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extmul_high_i8x16_u(LiftoffRegister dst,
31821cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
31831cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
31841cb0ef41Sopenharmony_ci  I16x8ExtMulHighU(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
31851cb0ef41Sopenharmony_ci}
31861cb0ef41Sopenharmony_ci
31871cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_q15mulr_sat_s(LiftoffRegister dst,
31881cb0ef41Sopenharmony_ci                                                LiftoffRegister src1,
31891cb0ef41Sopenharmony_ci                                                LiftoffRegister src2) {
31901cb0ef41Sopenharmony_ci  I16x8Q15MulRSatS(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
31911cb0ef41Sopenharmony_ci}
31921cb0ef41Sopenharmony_ci
31931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst,
31941cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
31951cb0ef41Sopenharmony_ci  if (dst.fp() == src.fp()) {
31961cb0ef41Sopenharmony_ci    Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
31971cb0ef41Sopenharmony_ci    Psignd(dst.fp(), kScratchDoubleReg);
31981cb0ef41Sopenharmony_ci  } else {
31991cb0ef41Sopenharmony_ci    Pxor(dst.fp(), dst.fp());
32001cb0ef41Sopenharmony_ci    Psubd(dst.fp(), src.fp());
32011cb0ef41Sopenharmony_ci  }
32021cb0ef41Sopenharmony_ci}
32031cb0ef41Sopenharmony_ci
32041cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_alltrue(LiftoffRegister dst,
32051cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
32061cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue<&TurboAssembler::Pcmpeqd>(this, dst, src);
32071cb0ef41Sopenharmony_ci}
32081cb0ef41Sopenharmony_ci
32091cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_bitmask(LiftoffRegister dst,
32101cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
32111cb0ef41Sopenharmony_ci  Movmskps(dst.gp(), src.fp());
32121cb0ef41Sopenharmony_ci}
32131cb0ef41Sopenharmony_ci
32141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shl(LiftoffRegister dst, LiftoffRegister lhs,
32151cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
32161cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpslld, &Assembler::pslld, 5>(this, dst,
32171cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
32181cb0ef41Sopenharmony_ci}
32191cb0ef41Sopenharmony_ci
32201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shli(LiftoffRegister dst, LiftoffRegister lhs,
32211cb0ef41Sopenharmony_ci                                       int32_t rhs) {
32221cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpslld, &Assembler::pslld, 5>(
32231cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
32241cb0ef41Sopenharmony_ci}
32251cb0ef41Sopenharmony_ci
32261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shr_s(LiftoffRegister dst,
32271cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32281cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32291cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsrad, &Assembler::psrad, 5>(this, dst,
32301cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
32311cb0ef41Sopenharmony_ci}
32321cb0ef41Sopenharmony_ci
32331cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shri_s(LiftoffRegister dst,
32341cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
32351cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsrad, &Assembler::psrad, 5>(
32361cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
32371cb0ef41Sopenharmony_ci}
32381cb0ef41Sopenharmony_ci
32391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shr_u(LiftoffRegister dst,
32401cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32411cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32421cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsrld, &Assembler::psrld, 5>(this, dst,
32431cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
32441cb0ef41Sopenharmony_ci}
32451cb0ef41Sopenharmony_ci
32461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_shri_u(LiftoffRegister dst,
32471cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
32481cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsrld, &Assembler::psrld, 5>(
32491cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
32501cb0ef41Sopenharmony_ci}
32511cb0ef41Sopenharmony_ci
32521cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
32531cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
32541cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddd, &Assembler::paddd>(
32551cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
32561cb0ef41Sopenharmony_ci}
32571cb0ef41Sopenharmony_ci
32581cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sub(LiftoffRegister dst, LiftoffRegister lhs,
32591cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
32601cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubd, &Assembler::psubd>(
32611cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
32621cb0ef41Sopenharmony_ci}
32631cb0ef41Sopenharmony_ci
32641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_mul(LiftoffRegister dst, LiftoffRegister lhs,
32651cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
32661cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmulld, &Assembler::pmulld>(
32671cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
32681cb0ef41Sopenharmony_ci}
32691cb0ef41Sopenharmony_ci
32701cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_min_s(LiftoffRegister dst,
32711cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32721cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32731cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminsd, &Assembler::pminsd>(
32741cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
32751cb0ef41Sopenharmony_ci}
32761cb0ef41Sopenharmony_ci
32771cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_min_u(LiftoffRegister dst,
32781cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32791cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32801cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpminud, &Assembler::pminud>(
32811cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
32821cb0ef41Sopenharmony_ci}
32831cb0ef41Sopenharmony_ci
32841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_max_s(LiftoffRegister dst,
32851cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32861cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32871cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxsd, &Assembler::pmaxsd>(
32881cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
32891cb0ef41Sopenharmony_ci}
32901cb0ef41Sopenharmony_ci
32911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_max_u(LiftoffRegister dst,
32921cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
32931cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
32941cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaxud, &Assembler::pmaxud>(
32951cb0ef41Sopenharmony_ci      this, dst, lhs, rhs, base::Optional<CpuFeature>(SSE4_1));
32961cb0ef41Sopenharmony_ci}
32971cb0ef41Sopenharmony_ci
32981cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_dot_i16x8_s(LiftoffRegister dst,
32991cb0ef41Sopenharmony_ci                                              LiftoffRegister lhs,
33001cb0ef41Sopenharmony_ci                                              LiftoffRegister rhs) {
33011cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmaddwd, &Assembler::pmaddwd>(
33021cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
33031cb0ef41Sopenharmony_ci}
33041cb0ef41Sopenharmony_ci
33051cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extadd_pairwise_i16x8_s(LiftoffRegister dst,
33061cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
33071cb0ef41Sopenharmony_ci  I32x4ExtAddPairwiseI16x8S(dst.fp(), src.fp(), kScratchRegister);
33081cb0ef41Sopenharmony_ci}
33091cb0ef41Sopenharmony_ci
33101cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extadd_pairwise_i16x8_u(LiftoffRegister dst,
33111cb0ef41Sopenharmony_ci                                                          LiftoffRegister src) {
33121cb0ef41Sopenharmony_ci  I32x4ExtAddPairwiseI16x8U(dst.fp(), src.fp(), kScratchDoubleReg);
33131cb0ef41Sopenharmony_ci}
33141cb0ef41Sopenharmony_ci
33151cb0ef41Sopenharmony_cinamespace liftoff {
33161cb0ef41Sopenharmony_ci// Helper function to check for register aliasing, AVX support, and moves
33171cb0ef41Sopenharmony_ci// registers around before calling the actual macro-assembler function.
33181cb0ef41Sopenharmony_ciinline void I32x4ExtMulHelper(LiftoffAssembler* assm, XMMRegister dst,
33191cb0ef41Sopenharmony_ci                              XMMRegister src1, XMMRegister src2, bool low,
33201cb0ef41Sopenharmony_ci                              bool is_signed) {
33211cb0ef41Sopenharmony_ci  // I32x4ExtMul requires dst == src1 if AVX is not supported.
33221cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX) || dst == src1) {
33231cb0ef41Sopenharmony_ci    assm->I32x4ExtMul(dst, src1, src2, kScratchDoubleReg, low, is_signed);
33241cb0ef41Sopenharmony_ci  } else if (dst != src2) {
33251cb0ef41Sopenharmony_ci    // dst != src1 && dst != src2
33261cb0ef41Sopenharmony_ci    assm->movaps(dst, src1);
33271cb0ef41Sopenharmony_ci    assm->I32x4ExtMul(dst, dst, src2, kScratchDoubleReg, low, is_signed);
33281cb0ef41Sopenharmony_ci  } else {
33291cb0ef41Sopenharmony_ci    // dst == src2
33301cb0ef41Sopenharmony_ci    // Extended multiplication is commutative,
33311cb0ef41Sopenharmony_ci    assm->movaps(dst, src2);
33321cb0ef41Sopenharmony_ci    assm->I32x4ExtMul(dst, dst, src1, kScratchDoubleReg, low, is_signed);
33331cb0ef41Sopenharmony_ci  }
33341cb0ef41Sopenharmony_ci}
33351cb0ef41Sopenharmony_ci}  // namespace liftoff
33361cb0ef41Sopenharmony_ci
33371cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_low_i16x8_s(LiftoffRegister dst,
33381cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
33391cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
33401cb0ef41Sopenharmony_ci  liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
33411cb0ef41Sopenharmony_ci                             /*is_signed=*/true);
33421cb0ef41Sopenharmony_ci}
33431cb0ef41Sopenharmony_ci
33441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_low_i16x8_u(LiftoffRegister dst,
33451cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
33461cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
33471cb0ef41Sopenharmony_ci  liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(), /*low=*/true,
33481cb0ef41Sopenharmony_ci                             /*is_signed=*/false);
33491cb0ef41Sopenharmony_ci}
33501cb0ef41Sopenharmony_ci
33511cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_high_i16x8_s(LiftoffRegister dst,
33521cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
33531cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
33541cb0ef41Sopenharmony_ci  liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(),
33551cb0ef41Sopenharmony_ci                             /*low=*/false,
33561cb0ef41Sopenharmony_ci                             /*is_signed=*/true);
33571cb0ef41Sopenharmony_ci}
33581cb0ef41Sopenharmony_ci
33591cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extmul_high_i16x8_u(LiftoffRegister dst,
33601cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
33611cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
33621cb0ef41Sopenharmony_ci  liftoff::I32x4ExtMulHelper(this, dst.fp(), src1.fp(), src2.fp(),
33631cb0ef41Sopenharmony_ci                             /*low=*/false,
33641cb0ef41Sopenharmony_ci                             /*is_signed=*/false);
33651cb0ef41Sopenharmony_ci}
33661cb0ef41Sopenharmony_ci
33671cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst,
33681cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
33691cb0ef41Sopenharmony_ci  I64x2Neg(dst.fp(), src.fp(), kScratchDoubleReg);
33701cb0ef41Sopenharmony_ci}
33711cb0ef41Sopenharmony_ci
33721cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_alltrue(LiftoffRegister dst,
33731cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
33741cb0ef41Sopenharmony_ci  liftoff::EmitAllTrue<&TurboAssembler::Pcmpeqq>(this, dst, src, SSE4_1);
33751cb0ef41Sopenharmony_ci}
33761cb0ef41Sopenharmony_ci
33771cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shl(LiftoffRegister dst, LiftoffRegister lhs,
33781cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
33791cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsllq, &Assembler::psllq, 6>(this, dst,
33801cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
33811cb0ef41Sopenharmony_ci}
33821cb0ef41Sopenharmony_ci
33831cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
33841cb0ef41Sopenharmony_ci                                       int32_t rhs) {
33851cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsllq, &Assembler::psllq, 6>(
33861cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
33871cb0ef41Sopenharmony_ci}
33881cb0ef41Sopenharmony_ci
33891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
33901cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
33911cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
33921cb0ef41Sopenharmony_ci  I64x2ShrS(dst.fp(), lhs.fp(), rhs.gp(), kScratchDoubleReg,
33931cb0ef41Sopenharmony_ci            liftoff::kScratchDoubleReg2, kScratchRegister);
33941cb0ef41Sopenharmony_ci}
33951cb0ef41Sopenharmony_ci
33961cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
33971cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
33981cb0ef41Sopenharmony_ci  I64x2ShrS(dst.fp(), lhs.fp(), rhs & 0x3F, kScratchDoubleReg);
33991cb0ef41Sopenharmony_ci}
34001cb0ef41Sopenharmony_ci
34011cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
34021cb0ef41Sopenharmony_ci                                        LiftoffRegister lhs,
34031cb0ef41Sopenharmony_ci                                        LiftoffRegister rhs) {
34041cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOp<&Assembler::vpsrlq, &Assembler::psrlq, 6>(this, dst,
34051cb0ef41Sopenharmony_ci                                                                     lhs, rhs);
34061cb0ef41Sopenharmony_ci}
34071cb0ef41Sopenharmony_ci
34081cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
34091cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs, int32_t rhs) {
34101cb0ef41Sopenharmony_ci  liftoff::EmitSimdShiftOpImm<&Assembler::vpsrlq, &Assembler::psrlq, 6>(
34111cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
34121cb0ef41Sopenharmony_ci}
34131cb0ef41Sopenharmony_ci
34141cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
34151cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
34161cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpaddq, &Assembler::paddq>(
34171cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
34181cb0ef41Sopenharmony_ci}
34191cb0ef41Sopenharmony_ci
34201cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
34211cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
34221cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpsubq, &Assembler::psubq>(
34231cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
34241cb0ef41Sopenharmony_ci}
34251cb0ef41Sopenharmony_ci
34261cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
34271cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
34281cb0ef41Sopenharmony_ci  static constexpr RegClass tmp_rc = reg_class_for(kS128);
34291cb0ef41Sopenharmony_ci  LiftoffRegister tmp1 =
34301cb0ef41Sopenharmony_ci      GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs});
34311cb0ef41Sopenharmony_ci  LiftoffRegister tmp2 =
34321cb0ef41Sopenharmony_ci      GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs, tmp1});
34331cb0ef41Sopenharmony_ci  I64x2Mul(dst.fp(), lhs.fp(), rhs.fp(), tmp1.fp(), tmp2.fp());
34341cb0ef41Sopenharmony_ci}
34351cb0ef41Sopenharmony_ci
34361cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_low_i32x4_s(LiftoffRegister dst,
34371cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
34381cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
34391cb0ef41Sopenharmony_ci  I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg, /*low=*/true,
34401cb0ef41Sopenharmony_ci              /*is_signed=*/true);
34411cb0ef41Sopenharmony_ci}
34421cb0ef41Sopenharmony_ci
34431cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_low_i32x4_u(LiftoffRegister dst,
34441cb0ef41Sopenharmony_ci                                                     LiftoffRegister src1,
34451cb0ef41Sopenharmony_ci                                                     LiftoffRegister src2) {
34461cb0ef41Sopenharmony_ci  I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg, /*low=*/true,
34471cb0ef41Sopenharmony_ci              /*is_signed=*/false);
34481cb0ef41Sopenharmony_ci}
34491cb0ef41Sopenharmony_ci
34501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_high_i32x4_s(LiftoffRegister dst,
34511cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
34521cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
34531cb0ef41Sopenharmony_ci  I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg, /*low=*/false,
34541cb0ef41Sopenharmony_ci              /*is_signed=*/true);
34551cb0ef41Sopenharmony_ci}
34561cb0ef41Sopenharmony_ci
34571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extmul_high_i32x4_u(LiftoffRegister dst,
34581cb0ef41Sopenharmony_ci                                                      LiftoffRegister src1,
34591cb0ef41Sopenharmony_ci                                                      LiftoffRegister src2) {
34601cb0ef41Sopenharmony_ci  I64x2ExtMul(dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg, /*low=*/false,
34611cb0ef41Sopenharmony_ci              /*is_signed=*/false);
34621cb0ef41Sopenharmony_ci}
34631cb0ef41Sopenharmony_ci
34641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_bitmask(LiftoffRegister dst,
34651cb0ef41Sopenharmony_ci                                          LiftoffRegister src) {
34661cb0ef41Sopenharmony_ci  Movmskpd(dst.gp(), src.fp());
34671cb0ef41Sopenharmony_ci}
34681cb0ef41Sopenharmony_ci
34691cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sconvert_i32x4_low(LiftoffRegister dst,
34701cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
34711cb0ef41Sopenharmony_ci  Pmovsxdq(dst.fp(), src.fp());
34721cb0ef41Sopenharmony_ci}
34731cb0ef41Sopenharmony_ci
34741cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_sconvert_i32x4_high(LiftoffRegister dst,
34751cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
34761cb0ef41Sopenharmony_ci  I64x2SConvertI32x4High(dst.fp(), src.fp());
34771cb0ef41Sopenharmony_ci}
34781cb0ef41Sopenharmony_ci
34791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_uconvert_i32x4_low(LiftoffRegister dst,
34801cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
34811cb0ef41Sopenharmony_ci  Pmovzxdq(dst.fp(), src.fp());
34821cb0ef41Sopenharmony_ci}
34831cb0ef41Sopenharmony_ci
34841cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_uconvert_i32x4_high(LiftoffRegister dst,
34851cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
34861cb0ef41Sopenharmony_ci  I64x2UConvertI32x4High(dst.fp(), src.fp(), kScratchDoubleReg);
34871cb0ef41Sopenharmony_ci}
34881cb0ef41Sopenharmony_ci
34891cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_abs(LiftoffRegister dst,
34901cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
34911cb0ef41Sopenharmony_ci  Absps(dst.fp(), src.fp(), kScratchRegister);
34921cb0ef41Sopenharmony_ci}
34931cb0ef41Sopenharmony_ci
34941cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_neg(LiftoffRegister dst,
34951cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
34961cb0ef41Sopenharmony_ci  Negps(dst.fp(), src.fp(), kScratchRegister);
34971cb0ef41Sopenharmony_ci}
34981cb0ef41Sopenharmony_ci
34991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sqrt(LiftoffRegister dst,
35001cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
35011cb0ef41Sopenharmony_ci  Sqrtps(dst.fp(), src.fp());
35021cb0ef41Sopenharmony_ci}
35031cb0ef41Sopenharmony_ci
35041cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_ceil(LiftoffRegister dst,
35051cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
35061cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
35071cb0ef41Sopenharmony_ci  Roundps(dst.fp(), src.fp(), kRoundUp);
35081cb0ef41Sopenharmony_ci  return true;
35091cb0ef41Sopenharmony_ci}
35101cb0ef41Sopenharmony_ci
35111cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_floor(LiftoffRegister dst,
35121cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
35131cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
35141cb0ef41Sopenharmony_ci  Roundps(dst.fp(), src.fp(), kRoundDown);
35151cb0ef41Sopenharmony_ci  return true;
35161cb0ef41Sopenharmony_ci}
35171cb0ef41Sopenharmony_ci
35181cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_trunc(LiftoffRegister dst,
35191cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
35201cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
35211cb0ef41Sopenharmony_ci  Roundps(dst.fp(), src.fp(), kRoundToZero);
35221cb0ef41Sopenharmony_ci  return true;
35231cb0ef41Sopenharmony_ci}
35241cb0ef41Sopenharmony_ci
35251cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f32x4_nearest_int(LiftoffRegister dst,
35261cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
35271cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
35281cb0ef41Sopenharmony_ci  Roundps(dst.fp(), src.fp(), kRoundToNearest);
35291cb0ef41Sopenharmony_ci  return true;
35301cb0ef41Sopenharmony_ci}
35311cb0ef41Sopenharmony_ci
35321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
35331cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35341cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vaddps, &Assembler::addps>(
35351cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
35361cb0ef41Sopenharmony_ci}
35371cb0ef41Sopenharmony_ci
35381cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sub(LiftoffRegister dst, LiftoffRegister lhs,
35391cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35401cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vsubps, &Assembler::subps>(
35411cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
35421cb0ef41Sopenharmony_ci}
35431cb0ef41Sopenharmony_ci
35441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_mul(LiftoffRegister dst, LiftoffRegister lhs,
35451cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35461cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vmulps, &Assembler::mulps>(
35471cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
35481cb0ef41Sopenharmony_ci}
35491cb0ef41Sopenharmony_ci
35501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_div(LiftoffRegister dst, LiftoffRegister lhs,
35511cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35521cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vdivps, &Assembler::divps>(
35531cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
35541cb0ef41Sopenharmony_ci}
35551cb0ef41Sopenharmony_ci
35561cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_min(LiftoffRegister dst, LiftoffRegister lhs,
35571cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35581cb0ef41Sopenharmony_ci  F32x4Min(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
35591cb0ef41Sopenharmony_ci}
35601cb0ef41Sopenharmony_ci
35611cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_max(LiftoffRegister dst, LiftoffRegister lhs,
35621cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
35631cb0ef41Sopenharmony_ci  F32x4Max(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
35641cb0ef41Sopenharmony_ci}
35651cb0ef41Sopenharmony_ci
35661cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_pmin(LiftoffRegister dst, LiftoffRegister lhs,
35671cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
35681cb0ef41Sopenharmony_ci  // Due to the way minps works, pmin(a, b) = minps(b, a).
35691cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vminps, &Assembler::minps>(
35701cb0ef41Sopenharmony_ci      this, dst, rhs, lhs);
35711cb0ef41Sopenharmony_ci}
35721cb0ef41Sopenharmony_ci
35731cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_pmax(LiftoffRegister dst, LiftoffRegister lhs,
35741cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
35751cb0ef41Sopenharmony_ci  // Due to the way maxps works, pmax(a, b) = maxps(b, a).
35761cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vmaxps, &Assembler::maxps>(
35771cb0ef41Sopenharmony_ci      this, dst, rhs, lhs);
35781cb0ef41Sopenharmony_ci}
35791cb0ef41Sopenharmony_ci
35801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_abs(LiftoffRegister dst,
35811cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
35821cb0ef41Sopenharmony_ci  Abspd(dst.fp(), src.fp(), kScratchRegister);
35831cb0ef41Sopenharmony_ci}
35841cb0ef41Sopenharmony_ci
35851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_neg(LiftoffRegister dst,
35861cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
35871cb0ef41Sopenharmony_ci  Negpd(dst.fp(), src.fp(), kScratchRegister);
35881cb0ef41Sopenharmony_ci}
35891cb0ef41Sopenharmony_ci
35901cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_sqrt(LiftoffRegister dst,
35911cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
35921cb0ef41Sopenharmony_ci  Sqrtpd(dst.fp(), src.fp());
35931cb0ef41Sopenharmony_ci}
35941cb0ef41Sopenharmony_ci
35951cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_ceil(LiftoffRegister dst,
35961cb0ef41Sopenharmony_ci                                       LiftoffRegister src) {
35971cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
35981cb0ef41Sopenharmony_ci  Roundpd(dst.fp(), src.fp(), kRoundUp);
35991cb0ef41Sopenharmony_ci  return true;
36001cb0ef41Sopenharmony_ci}
36011cb0ef41Sopenharmony_ci
36021cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_floor(LiftoffRegister dst,
36031cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
36041cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
36051cb0ef41Sopenharmony_ci  Roundpd(dst.fp(), src.fp(), kRoundDown);
36061cb0ef41Sopenharmony_ci  return true;
36071cb0ef41Sopenharmony_ci}
36081cb0ef41Sopenharmony_ci
36091cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_trunc(LiftoffRegister dst,
36101cb0ef41Sopenharmony_ci                                        LiftoffRegister src) {
36111cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
36121cb0ef41Sopenharmony_ci  Roundpd(dst.fp(), src.fp(), kRoundToZero);
36131cb0ef41Sopenharmony_ci  return true;
36141cb0ef41Sopenharmony_ci}
36151cb0ef41Sopenharmony_ci
36161cb0ef41Sopenharmony_cibool LiftoffAssembler::emit_f64x2_nearest_int(LiftoffRegister dst,
36171cb0ef41Sopenharmony_ci                                              LiftoffRegister src) {
36181cb0ef41Sopenharmony_ci  DCHECK(CpuFeatures::IsSupported(SSE4_1));
36191cb0ef41Sopenharmony_ci  Roundpd(dst.fp(), src.fp(), kRoundToNearest);
36201cb0ef41Sopenharmony_ci  return true;
36211cb0ef41Sopenharmony_ci}
36221cb0ef41Sopenharmony_ci
36231cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
36241cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36251cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vaddpd, &Assembler::addpd>(
36261cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
36271cb0ef41Sopenharmony_ci}
36281cb0ef41Sopenharmony_ci
36291cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
36301cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36311cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vsubpd, &Assembler::subpd>(
36321cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
36331cb0ef41Sopenharmony_ci}
36341cb0ef41Sopenharmony_ci
36351cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
36361cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36371cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vmulpd, &Assembler::mulpd>(
36381cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
36391cb0ef41Sopenharmony_ci}
36401cb0ef41Sopenharmony_ci
36411cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_div(LiftoffRegister dst, LiftoffRegister lhs,
36421cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36431cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vdivpd, &Assembler::divpd>(
36441cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
36451cb0ef41Sopenharmony_ci}
36461cb0ef41Sopenharmony_ci
36471cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_min(LiftoffRegister dst, LiftoffRegister lhs,
36481cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36491cb0ef41Sopenharmony_ci  F64x2Min(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
36501cb0ef41Sopenharmony_ci}
36511cb0ef41Sopenharmony_ci
36521cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_max(LiftoffRegister dst, LiftoffRegister lhs,
36531cb0ef41Sopenharmony_ci                                      LiftoffRegister rhs) {
36541cb0ef41Sopenharmony_ci  F64x2Max(dst.fp(), lhs.fp(), rhs.fp(), kScratchDoubleReg);
36551cb0ef41Sopenharmony_ci}
36561cb0ef41Sopenharmony_ci
36571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_pmin(LiftoffRegister dst, LiftoffRegister lhs,
36581cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
36591cb0ef41Sopenharmony_ci  // Due to the way minpd works, pmin(a, b) = minpd(b, a).
36601cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vminpd, &Assembler::minpd>(
36611cb0ef41Sopenharmony_ci      this, dst, rhs, lhs);
36621cb0ef41Sopenharmony_ci}
36631cb0ef41Sopenharmony_ci
36641cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_pmax(LiftoffRegister dst, LiftoffRegister lhs,
36651cb0ef41Sopenharmony_ci                                       LiftoffRegister rhs) {
36661cb0ef41Sopenharmony_ci  // Due to the way maxpd works, pmax(a, b) = maxpd(b, a).
36671cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vmaxpd, &Assembler::maxpd>(
36681cb0ef41Sopenharmony_ci      this, dst, rhs, lhs);
36691cb0ef41Sopenharmony_ci}
36701cb0ef41Sopenharmony_ci
36711cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_convert_low_i32x4_s(LiftoffRegister dst,
36721cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
36731cb0ef41Sopenharmony_ci  Cvtdq2pd(dst.fp(), src.fp());
36741cb0ef41Sopenharmony_ci}
36751cb0ef41Sopenharmony_ci
36761cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_convert_low_i32x4_u(LiftoffRegister dst,
36771cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
36781cb0ef41Sopenharmony_ci  F64x2ConvertLowI32x4U(dst.fp(), src.fp(), kScratchRegister);
36791cb0ef41Sopenharmony_ci}
36801cb0ef41Sopenharmony_ci
36811cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_promote_low_f32x4(LiftoffRegister dst,
36821cb0ef41Sopenharmony_ci                                                    LiftoffRegister src) {
36831cb0ef41Sopenharmony_ci  Cvtps2pd(dst.fp(), src.fp());
36841cb0ef41Sopenharmony_ci}
36851cb0ef41Sopenharmony_ci
36861cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_f32x4(LiftoffRegister dst,
36871cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
36881cb0ef41Sopenharmony_ci  I32x4SConvertF32x4(dst.fp(), src.fp(), kScratchDoubleReg, kScratchRegister);
36891cb0ef41Sopenharmony_ci}
36901cb0ef41Sopenharmony_ci
36911cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_f32x4(LiftoffRegister dst,
36921cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
36931cb0ef41Sopenharmony_ci  // NAN->0, negative->0.
36941cb0ef41Sopenharmony_ci  Pxor(kScratchDoubleReg, kScratchDoubleReg);
36951cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
36961cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
36971cb0ef41Sopenharmony_ci    vmaxps(dst.fp(), src.fp(), kScratchDoubleReg);
36981cb0ef41Sopenharmony_ci  } else {
36991cb0ef41Sopenharmony_ci    if (dst.fp() != src.fp()) movaps(dst.fp(), src.fp());
37001cb0ef41Sopenharmony_ci    maxps(dst.fp(), kScratchDoubleReg);
37011cb0ef41Sopenharmony_ci  }
37021cb0ef41Sopenharmony_ci  // scratch: float representation of max_signed.
37031cb0ef41Sopenharmony_ci  Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
37041cb0ef41Sopenharmony_ci  Psrld(kScratchDoubleReg, uint8_t{1});            // 0x7fffffff
37051cb0ef41Sopenharmony_ci  Cvtdq2ps(kScratchDoubleReg, kScratchDoubleReg);  // 0x4f000000
37061cb0ef41Sopenharmony_ci  // scratch2: convert (src-max_signed).
37071cb0ef41Sopenharmony_ci  // Set positive overflow lanes to 0x7FFFFFFF.
37081cb0ef41Sopenharmony_ci  // Set negative lanes to 0.
37091cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
37101cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
37111cb0ef41Sopenharmony_ci    vsubps(liftoff::kScratchDoubleReg2, dst.fp(), kScratchDoubleReg);
37121cb0ef41Sopenharmony_ci  } else {
37131cb0ef41Sopenharmony_ci    movaps(liftoff::kScratchDoubleReg2, dst.fp());
37141cb0ef41Sopenharmony_ci    subps(liftoff::kScratchDoubleReg2, kScratchDoubleReg);
37151cb0ef41Sopenharmony_ci  }
37161cb0ef41Sopenharmony_ci  Cmpleps(kScratchDoubleReg, liftoff::kScratchDoubleReg2);
37171cb0ef41Sopenharmony_ci  Cvttps2dq(liftoff::kScratchDoubleReg2, liftoff::kScratchDoubleReg2);
37181cb0ef41Sopenharmony_ci  Pxor(liftoff::kScratchDoubleReg2, kScratchDoubleReg);
37191cb0ef41Sopenharmony_ci  Pxor(kScratchDoubleReg, kScratchDoubleReg);
37201cb0ef41Sopenharmony_ci  Pmaxsd(liftoff::kScratchDoubleReg2, kScratchDoubleReg);
37211cb0ef41Sopenharmony_ci  // Convert to int. Overflow lanes above max_signed will be 0x80000000.
37221cb0ef41Sopenharmony_ci  Cvttps2dq(dst.fp(), dst.fp());
37231cb0ef41Sopenharmony_ci  // Add (src-max_signed) for overflow lanes.
37241cb0ef41Sopenharmony_ci  Paddd(dst.fp(), liftoff::kScratchDoubleReg2);
37251cb0ef41Sopenharmony_ci}
37261cb0ef41Sopenharmony_ci
37271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_sconvert_i32x4(LiftoffRegister dst,
37281cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
37291cb0ef41Sopenharmony_ci  Cvtdq2ps(dst.fp(), src.fp());
37301cb0ef41Sopenharmony_ci}
37311cb0ef41Sopenharmony_ci
37321cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_uconvert_i32x4(LiftoffRegister dst,
37331cb0ef41Sopenharmony_ci                                                 LiftoffRegister src) {
37341cb0ef41Sopenharmony_ci  Pxor(kScratchDoubleReg, kScratchDoubleReg);           // Zeros.
37351cb0ef41Sopenharmony_ci  Pblendw(kScratchDoubleReg, src.fp(), uint8_t{0x55});  // Get lo 16 bits.
37361cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
37371cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
37381cb0ef41Sopenharmony_ci    vpsubd(dst.fp(), src.fp(), kScratchDoubleReg);  // Get hi 16 bits.
37391cb0ef41Sopenharmony_ci  } else {
37401cb0ef41Sopenharmony_ci    if (dst.fp() != src.fp()) movaps(dst.fp(), src.fp());
37411cb0ef41Sopenharmony_ci    psubd(dst.fp(), kScratchDoubleReg);
37421cb0ef41Sopenharmony_ci  }
37431cb0ef41Sopenharmony_ci  Cvtdq2ps(kScratchDoubleReg, kScratchDoubleReg);  // Convert lo exactly.
37441cb0ef41Sopenharmony_ci  Psrld(dst.fp(), byte{1});            // Divide by 2 to get in unsigned range.
37451cb0ef41Sopenharmony_ci  Cvtdq2ps(dst.fp(), dst.fp());        // Convert hi, exactly.
37461cb0ef41Sopenharmony_ci  Addps(dst.fp(), dst.fp());           // Double hi, exactly.
37471cb0ef41Sopenharmony_ci  Addps(dst.fp(), kScratchDoubleReg);  // Add hi and lo, may round.
37481cb0ef41Sopenharmony_ci}
37491cb0ef41Sopenharmony_ci
37501cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_demote_f64x2_zero(LiftoffRegister dst,
37511cb0ef41Sopenharmony_ci                                                    LiftoffRegister src) {
37521cb0ef41Sopenharmony_ci  Cvtpd2ps(dst.fp(), src.fp());
37531cb0ef41Sopenharmony_ci}
37541cb0ef41Sopenharmony_ci
37551cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_sconvert_i16x8(LiftoffRegister dst,
37561cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
37571cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
37581cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpacksswb,
37591cb0ef41Sopenharmony_ci                                       &Assembler::packsswb>(this, dst, lhs,
37601cb0ef41Sopenharmony_ci                                                             rhs);
37611cb0ef41Sopenharmony_ci}
37621cb0ef41Sopenharmony_ci
37631cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_uconvert_i16x8(LiftoffRegister dst,
37641cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
37651cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
37661cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpackuswb,
37671cb0ef41Sopenharmony_ci                                       &Assembler::packuswb>(this, dst, lhs,
37681cb0ef41Sopenharmony_ci                                                             rhs);
37691cb0ef41Sopenharmony_ci}
37701cb0ef41Sopenharmony_ci
37711cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i32x4(LiftoffRegister dst,
37721cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
37731cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
37741cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpackssdw,
37751cb0ef41Sopenharmony_ci                                       &Assembler::packssdw>(this, dst, lhs,
37761cb0ef41Sopenharmony_ci                                                             rhs);
37771cb0ef41Sopenharmony_ci}
37781cb0ef41Sopenharmony_ci
37791cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i32x4(LiftoffRegister dst,
37801cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
37811cb0ef41Sopenharmony_ci                                                 LiftoffRegister rhs) {
37821cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vpackusdw,
37831cb0ef41Sopenharmony_ci                                       &Assembler::packusdw>(this, dst, lhs,
37841cb0ef41Sopenharmony_ci                                                             rhs, SSE4_1);
37851cb0ef41Sopenharmony_ci}
37861cb0ef41Sopenharmony_ci
37871cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i8x16_low(LiftoffRegister dst,
37881cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
37891cb0ef41Sopenharmony_ci  Pmovsxbw(dst.fp(), src.fp());
37901cb0ef41Sopenharmony_ci}
37911cb0ef41Sopenharmony_ci
37921cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_sconvert_i8x16_high(LiftoffRegister dst,
37931cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
37941cb0ef41Sopenharmony_ci  I16x8SConvertI8x16High(dst.fp(), src.fp());
37951cb0ef41Sopenharmony_ci}
37961cb0ef41Sopenharmony_ci
37971cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i8x16_low(LiftoffRegister dst,
37981cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
37991cb0ef41Sopenharmony_ci  Pmovzxbw(dst.fp(), src.fp());
38001cb0ef41Sopenharmony_ci}
38011cb0ef41Sopenharmony_ci
38021cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_uconvert_i8x16_high(LiftoffRegister dst,
38031cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
38041cb0ef41Sopenharmony_ci  I16x8UConvertI8x16High(dst.fp(), src.fp(), kScratchDoubleReg);
38051cb0ef41Sopenharmony_ci}
38061cb0ef41Sopenharmony_ci
38071cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_i16x8_low(LiftoffRegister dst,
38081cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
38091cb0ef41Sopenharmony_ci  Pmovsxwd(dst.fp(), src.fp());
38101cb0ef41Sopenharmony_ci}
38111cb0ef41Sopenharmony_ci
38121cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_sconvert_i16x8_high(LiftoffRegister dst,
38131cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
38141cb0ef41Sopenharmony_ci  I32x4SConvertI16x8High(dst.fp(), src.fp());
38151cb0ef41Sopenharmony_ci}
38161cb0ef41Sopenharmony_ci
38171cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_i16x8_low(LiftoffRegister dst,
38181cb0ef41Sopenharmony_ci                                                     LiftoffRegister src) {
38191cb0ef41Sopenharmony_ci  Pmovzxwd(dst.fp(), src.fp());
38201cb0ef41Sopenharmony_ci}
38211cb0ef41Sopenharmony_ci
38221cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_uconvert_i16x8_high(LiftoffRegister dst,
38231cb0ef41Sopenharmony_ci                                                      LiftoffRegister src) {
38241cb0ef41Sopenharmony_ci  I32x4UConvertI16x8High(dst.fp(), src.fp(), kScratchDoubleReg);
38251cb0ef41Sopenharmony_ci}
38261cb0ef41Sopenharmony_ci
38271cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_trunc_sat_f64x2_s_zero(LiftoffRegister dst,
38281cb0ef41Sopenharmony_ci                                                         LiftoffRegister src) {
38291cb0ef41Sopenharmony_ci  I32x4TruncSatF64x2SZero(dst.fp(), src.fp(), kScratchDoubleReg,
38301cb0ef41Sopenharmony_ci                          kScratchRegister);
38311cb0ef41Sopenharmony_ci}
38321cb0ef41Sopenharmony_ci
38331cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_trunc_sat_f64x2_u_zero(LiftoffRegister dst,
38341cb0ef41Sopenharmony_ci                                                         LiftoffRegister src) {
38351cb0ef41Sopenharmony_ci  I32x4TruncSatF64x2UZero(dst.fp(), src.fp(), kScratchDoubleReg,
38361cb0ef41Sopenharmony_ci                          kScratchRegister);
38371cb0ef41Sopenharmony_ci}
38381cb0ef41Sopenharmony_ci
38391cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_and_not(LiftoffRegister dst,
38401cb0ef41Sopenharmony_ci                                         LiftoffRegister lhs,
38411cb0ef41Sopenharmony_ci                                         LiftoffRegister rhs) {
38421cb0ef41Sopenharmony_ci  liftoff::EmitSimdNonCommutativeBinOp<&Assembler::vandnps, &Assembler::andnps>(
38431cb0ef41Sopenharmony_ci      this, dst, rhs, lhs);
38441cb0ef41Sopenharmony_ci}
38451cb0ef41Sopenharmony_ci
38461cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_rounding_average_u(LiftoffRegister dst,
38471cb0ef41Sopenharmony_ci                                                     LiftoffRegister lhs,
38481cb0ef41Sopenharmony_ci                                                     LiftoffRegister rhs) {
38491cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpavgb, &Assembler::pavgb>(
38501cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
38511cb0ef41Sopenharmony_ci}
38521cb0ef41Sopenharmony_ci
38531cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_rounding_average_u(LiftoffRegister dst,
38541cb0ef41Sopenharmony_ci                                                     LiftoffRegister lhs,
38551cb0ef41Sopenharmony_ci                                                     LiftoffRegister rhs) {
38561cb0ef41Sopenharmony_ci  liftoff::EmitSimdCommutativeBinOp<&Assembler::vpavgw, &Assembler::pavgw>(
38571cb0ef41Sopenharmony_ci      this, dst, lhs, rhs);
38581cb0ef41Sopenharmony_ci}
38591cb0ef41Sopenharmony_ci
38601cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_abs(LiftoffRegister dst,
38611cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
38621cb0ef41Sopenharmony_ci  Pabsb(dst.fp(), src.fp());
38631cb0ef41Sopenharmony_ci}
38641cb0ef41Sopenharmony_ci
38651cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_abs(LiftoffRegister dst,
38661cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
38671cb0ef41Sopenharmony_ci  Pabsw(dst.fp(), src.fp());
38681cb0ef41Sopenharmony_ci}
38691cb0ef41Sopenharmony_ci
38701cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_abs(LiftoffRegister dst,
38711cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
38721cb0ef41Sopenharmony_ci  Pabsd(dst.fp(), src.fp());
38731cb0ef41Sopenharmony_ci}
38741cb0ef41Sopenharmony_ci
38751cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_abs(LiftoffRegister dst,
38761cb0ef41Sopenharmony_ci                                      LiftoffRegister src) {
38771cb0ef41Sopenharmony_ci  I64x2Abs(dst.fp(), src.fp(), kScratchDoubleReg);
38781cb0ef41Sopenharmony_ci}
38791cb0ef41Sopenharmony_ci
38801cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_extract_lane_s(LiftoffRegister dst,
38811cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
38821cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
38831cb0ef41Sopenharmony_ci  Pextrb(dst.gp(), lhs.fp(), imm_lane_idx);
38841cb0ef41Sopenharmony_ci  movsxbl(dst.gp(), dst.gp());
38851cb0ef41Sopenharmony_ci}
38861cb0ef41Sopenharmony_ci
38871cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_extract_lane_u(LiftoffRegister dst,
38881cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
38891cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
38901cb0ef41Sopenharmony_ci  Pextrb(dst.gp(), lhs.fp(), imm_lane_idx);
38911cb0ef41Sopenharmony_ci}
38921cb0ef41Sopenharmony_ci
38931cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extract_lane_s(LiftoffRegister dst,
38941cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
38951cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
38961cb0ef41Sopenharmony_ci  Pextrw(dst.gp(), lhs.fp(), imm_lane_idx);
38971cb0ef41Sopenharmony_ci  movsxwl(dst.gp(), dst.gp());
38981cb0ef41Sopenharmony_ci}
38991cb0ef41Sopenharmony_ci
39001cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_extract_lane_u(LiftoffRegister dst,
39011cb0ef41Sopenharmony_ci                                                 LiftoffRegister lhs,
39021cb0ef41Sopenharmony_ci                                                 uint8_t imm_lane_idx) {
39031cb0ef41Sopenharmony_ci  Pextrw(dst.gp(), lhs.fp(), imm_lane_idx);
39041cb0ef41Sopenharmony_ci}
39051cb0ef41Sopenharmony_ci
39061cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_extract_lane(LiftoffRegister dst,
39071cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
39081cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39091cb0ef41Sopenharmony_ci  Pextrd(dst.gp(), lhs.fp(), imm_lane_idx);
39101cb0ef41Sopenharmony_ci}
39111cb0ef41Sopenharmony_ci
39121cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_extract_lane(LiftoffRegister dst,
39131cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
39141cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39151cb0ef41Sopenharmony_ci  Pextrq(dst.gp(), lhs.fp(), static_cast<int8_t>(imm_lane_idx));
39161cb0ef41Sopenharmony_ci}
39171cb0ef41Sopenharmony_ci
39181cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_extract_lane(LiftoffRegister dst,
39191cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
39201cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39211cb0ef41Sopenharmony_ci  F32x4ExtractLane(dst.fp(), lhs.fp(), imm_lane_idx);
39221cb0ef41Sopenharmony_ci}
39231cb0ef41Sopenharmony_ci
39241cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_extract_lane(LiftoffRegister dst,
39251cb0ef41Sopenharmony_ci                                               LiftoffRegister lhs,
39261cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39271cb0ef41Sopenharmony_ci  F64x2ExtractLane(dst.fp(), lhs.fp(), imm_lane_idx);
39281cb0ef41Sopenharmony_ci}
39291cb0ef41Sopenharmony_ci
39301cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i8x16_replace_lane(LiftoffRegister dst,
39311cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
39321cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
39331cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39341cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
39351cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
39361cb0ef41Sopenharmony_ci    vpinsrb(dst.fp(), src1.fp(), src2.gp(), imm_lane_idx);
39371cb0ef41Sopenharmony_ci  } else {
39381cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, SSE4_1);
39391cb0ef41Sopenharmony_ci    if (dst.fp() != src1.fp()) movaps(dst.fp(), src1.fp());
39401cb0ef41Sopenharmony_ci    pinsrb(dst.fp(), src2.gp(), imm_lane_idx);
39411cb0ef41Sopenharmony_ci  }
39421cb0ef41Sopenharmony_ci}
39431cb0ef41Sopenharmony_ci
39441cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i16x8_replace_lane(LiftoffRegister dst,
39451cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
39461cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
39471cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39481cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
39491cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
39501cb0ef41Sopenharmony_ci    vpinsrw(dst.fp(), src1.fp(), src2.gp(), imm_lane_idx);
39511cb0ef41Sopenharmony_ci  } else {
39521cb0ef41Sopenharmony_ci    if (dst.fp() != src1.fp()) movaps(dst.fp(), src1.fp());
39531cb0ef41Sopenharmony_ci    pinsrw(dst.fp(), src2.gp(), imm_lane_idx);
39541cb0ef41Sopenharmony_ci  }
39551cb0ef41Sopenharmony_ci}
39561cb0ef41Sopenharmony_ci
39571cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i32x4_replace_lane(LiftoffRegister dst,
39581cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
39591cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
39601cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39611cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
39621cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
39631cb0ef41Sopenharmony_ci    vpinsrd(dst.fp(), src1.fp(), src2.gp(), imm_lane_idx);
39641cb0ef41Sopenharmony_ci  } else {
39651cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, SSE4_1);
39661cb0ef41Sopenharmony_ci    if (dst.fp() != src1.fp()) movaps(dst.fp(), src1.fp());
39671cb0ef41Sopenharmony_ci    pinsrd(dst.fp(), src2.gp(), imm_lane_idx);
39681cb0ef41Sopenharmony_ci  }
39691cb0ef41Sopenharmony_ci}
39701cb0ef41Sopenharmony_ci
39711cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_i64x2_replace_lane(LiftoffRegister dst,
39721cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
39731cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
39741cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39751cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
39761cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
39771cb0ef41Sopenharmony_ci    vpinsrq(dst.fp(), src1.fp(), src2.gp(), imm_lane_idx);
39781cb0ef41Sopenharmony_ci  } else {
39791cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, SSE4_1);
39801cb0ef41Sopenharmony_ci    if (dst.fp() != src1.fp()) movaps(dst.fp(), src1.fp());
39811cb0ef41Sopenharmony_ci    pinsrq(dst.fp(), src2.gp(), imm_lane_idx);
39821cb0ef41Sopenharmony_ci  }
39831cb0ef41Sopenharmony_ci}
39841cb0ef41Sopenharmony_ci
39851cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f32x4_replace_lane(LiftoffRegister dst,
39861cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
39871cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
39881cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
39891cb0ef41Sopenharmony_ci  if (CpuFeatures::IsSupported(AVX)) {
39901cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, AVX);
39911cb0ef41Sopenharmony_ci    vinsertps(dst.fp(), src1.fp(), src2.fp(), (imm_lane_idx << 4) & 0x30);
39921cb0ef41Sopenharmony_ci  } else {
39931cb0ef41Sopenharmony_ci    CpuFeatureScope scope(this, SSE4_1);
39941cb0ef41Sopenharmony_ci    if (dst.fp() != src1.fp()) movaps(dst.fp(), src1.fp());
39951cb0ef41Sopenharmony_ci    insertps(dst.fp(), src2.fp(), (imm_lane_idx << 4) & 0x30);
39961cb0ef41Sopenharmony_ci  }
39971cb0ef41Sopenharmony_ci}
39981cb0ef41Sopenharmony_ci
39991cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_f64x2_replace_lane(LiftoffRegister dst,
40001cb0ef41Sopenharmony_ci                                               LiftoffRegister src1,
40011cb0ef41Sopenharmony_ci                                               LiftoffRegister src2,
40021cb0ef41Sopenharmony_ci                                               uint8_t imm_lane_idx) {
40031cb0ef41Sopenharmony_ci  F64x2ReplaceLane(dst.fp(), src1.fp(), src2.fp(), imm_lane_idx);
40041cb0ef41Sopenharmony_ci}
40051cb0ef41Sopenharmony_ci
40061cb0ef41Sopenharmony_civoid LiftoffAssembler::StackCheck(Label* ool_code, Register limit_address) {
40071cb0ef41Sopenharmony_ci  cmpq(rsp, Operand(limit_address, 0));
40081cb0ef41Sopenharmony_ci  j(below_equal, ool_code);
40091cb0ef41Sopenharmony_ci}
40101cb0ef41Sopenharmony_ci
40111cb0ef41Sopenharmony_civoid LiftoffAssembler::CallTrapCallbackForTesting() {
40121cb0ef41Sopenharmony_ci  PrepareCallCFunction(0);
40131cb0ef41Sopenharmony_ci  CallCFunction(ExternalReference::wasm_call_trap_callback_for_testing(), 0);
40141cb0ef41Sopenharmony_ci}
40151cb0ef41Sopenharmony_ci
40161cb0ef41Sopenharmony_civoid LiftoffAssembler::AssertUnreachable(AbortReason reason) {
40171cb0ef41Sopenharmony_ci  TurboAssembler::AssertUnreachable(reason);
40181cb0ef41Sopenharmony_ci}
40191cb0ef41Sopenharmony_ci
40201cb0ef41Sopenharmony_civoid LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
40211cb0ef41Sopenharmony_ci  LiftoffRegList gp_regs = regs & kGpCacheRegList;
40221cb0ef41Sopenharmony_ci  while (!gp_regs.is_empty()) {
40231cb0ef41Sopenharmony_ci    LiftoffRegister reg = gp_regs.GetFirstRegSet();
40241cb0ef41Sopenharmony_ci    pushq(reg.gp());
40251cb0ef41Sopenharmony_ci    gp_regs.clear(reg);
40261cb0ef41Sopenharmony_ci  }
40271cb0ef41Sopenharmony_ci  LiftoffRegList fp_regs = regs & kFpCacheRegList;
40281cb0ef41Sopenharmony_ci  unsigned num_fp_regs = fp_regs.GetNumRegsSet();
40291cb0ef41Sopenharmony_ci  if (num_fp_regs) {
40301cb0ef41Sopenharmony_ci    AllocateStackSpace(num_fp_regs * kSimd128Size);
40311cb0ef41Sopenharmony_ci    unsigned offset = 0;
40321cb0ef41Sopenharmony_ci    while (!fp_regs.is_empty()) {
40331cb0ef41Sopenharmony_ci      LiftoffRegister reg = fp_regs.GetFirstRegSet();
40341cb0ef41Sopenharmony_ci      Movdqu(Operand(rsp, offset), reg.fp());
40351cb0ef41Sopenharmony_ci      fp_regs.clear(reg);
40361cb0ef41Sopenharmony_ci      offset += kSimd128Size;
40371cb0ef41Sopenharmony_ci    }
40381cb0ef41Sopenharmony_ci    DCHECK_EQ(offset, num_fp_regs * kSimd128Size);
40391cb0ef41Sopenharmony_ci  }
40401cb0ef41Sopenharmony_ci}
40411cb0ef41Sopenharmony_ci
40421cb0ef41Sopenharmony_civoid LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
40431cb0ef41Sopenharmony_ci  LiftoffRegList fp_regs = regs & kFpCacheRegList;
40441cb0ef41Sopenharmony_ci  unsigned fp_offset = 0;
40451cb0ef41Sopenharmony_ci  while (!fp_regs.is_empty()) {
40461cb0ef41Sopenharmony_ci    LiftoffRegister reg = fp_regs.GetFirstRegSet();
40471cb0ef41Sopenharmony_ci    Movdqu(reg.fp(), Operand(rsp, fp_offset));
40481cb0ef41Sopenharmony_ci    fp_regs.clear(reg);
40491cb0ef41Sopenharmony_ci    fp_offset += kSimd128Size;
40501cb0ef41Sopenharmony_ci  }
40511cb0ef41Sopenharmony_ci  if (fp_offset) addq(rsp, Immediate(fp_offset));
40521cb0ef41Sopenharmony_ci  LiftoffRegList gp_regs = regs & kGpCacheRegList;
40531cb0ef41Sopenharmony_ci  while (!gp_regs.is_empty()) {
40541cb0ef41Sopenharmony_ci    LiftoffRegister reg = gp_regs.GetLastRegSet();
40551cb0ef41Sopenharmony_ci    popq(reg.gp());
40561cb0ef41Sopenharmony_ci    gp_regs.clear(reg);
40571cb0ef41Sopenharmony_ci  }
40581cb0ef41Sopenharmony_ci}
40591cb0ef41Sopenharmony_ci
40601cb0ef41Sopenharmony_civoid LiftoffAssembler::RecordSpillsInSafepoint(
40611cb0ef41Sopenharmony_ci    SafepointTableBuilder::Safepoint& safepoint, LiftoffRegList all_spills,
40621cb0ef41Sopenharmony_ci    LiftoffRegList ref_spills, int spill_offset) {
40631cb0ef41Sopenharmony_ci  int spill_space_size = 0;
40641cb0ef41Sopenharmony_ci  while (!all_spills.is_empty()) {
40651cb0ef41Sopenharmony_ci    LiftoffRegister reg = all_spills.GetFirstRegSet();
40661cb0ef41Sopenharmony_ci    if (ref_spills.has(reg)) {
40671cb0ef41Sopenharmony_ci      safepoint.DefineTaggedStackSlot(spill_offset);
40681cb0ef41Sopenharmony_ci    }
40691cb0ef41Sopenharmony_ci    all_spills.clear(reg);
40701cb0ef41Sopenharmony_ci    ++spill_offset;
40711cb0ef41Sopenharmony_ci    spill_space_size += kSystemPointerSize;
40721cb0ef41Sopenharmony_ci  }
40731cb0ef41Sopenharmony_ci  // Record the number of additional spill slots.
40741cb0ef41Sopenharmony_ci  RecordOolSpillSpaceSize(spill_space_size);
40751cb0ef41Sopenharmony_ci}
40761cb0ef41Sopenharmony_ci
40771cb0ef41Sopenharmony_civoid LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
40781cb0ef41Sopenharmony_ci  DCHECK_LT(num_stack_slots,
40791cb0ef41Sopenharmony_ci            (1 << 16) / kSystemPointerSize);  // 16 bit immediate
40801cb0ef41Sopenharmony_ci  ret(static_cast<int>(num_stack_slots * kSystemPointerSize));
40811cb0ef41Sopenharmony_ci}
40821cb0ef41Sopenharmony_ci
40831cb0ef41Sopenharmony_civoid LiftoffAssembler::CallC(const ValueKindSig* sig,
40841cb0ef41Sopenharmony_ci                             const LiftoffRegister* args,
40851cb0ef41Sopenharmony_ci                             const LiftoffRegister* rets,
40861cb0ef41Sopenharmony_ci                             ValueKind out_argument_kind, int stack_bytes,
40871cb0ef41Sopenharmony_ci                             ExternalReference ext_ref) {
40881cb0ef41Sopenharmony_ci  AllocateStackSpace(stack_bytes);
40891cb0ef41Sopenharmony_ci
40901cb0ef41Sopenharmony_ci  int arg_bytes = 0;
40911cb0ef41Sopenharmony_ci  for (ValueKind param_kind : sig->parameters()) {
40921cb0ef41Sopenharmony_ci    liftoff::Store(this, Operand(rsp, arg_bytes), *args++, param_kind);
40931cb0ef41Sopenharmony_ci    arg_bytes += value_kind_size(param_kind);
40941cb0ef41Sopenharmony_ci  }
40951cb0ef41Sopenharmony_ci  DCHECK_LE(arg_bytes, stack_bytes);
40961cb0ef41Sopenharmony_ci
40971cb0ef41Sopenharmony_ci  // Pass a pointer to the buffer with the arguments to the C function.
40981cb0ef41Sopenharmony_ci  movq(arg_reg_1, rsp);
40991cb0ef41Sopenharmony_ci
41001cb0ef41Sopenharmony_ci  constexpr int kNumCCallArgs = 1;
41011cb0ef41Sopenharmony_ci
41021cb0ef41Sopenharmony_ci  // Now call the C function.
41031cb0ef41Sopenharmony_ci  PrepareCallCFunction(kNumCCallArgs);
41041cb0ef41Sopenharmony_ci  CallCFunction(ext_ref, kNumCCallArgs);
41051cb0ef41Sopenharmony_ci
41061cb0ef41Sopenharmony_ci  // Move return value to the right register.
41071cb0ef41Sopenharmony_ci  const LiftoffRegister* next_result_reg = rets;
41081cb0ef41Sopenharmony_ci  if (sig->return_count() > 0) {
41091cb0ef41Sopenharmony_ci    DCHECK_EQ(1, sig->return_count());
41101cb0ef41Sopenharmony_ci    constexpr Register kReturnReg = rax;
41111cb0ef41Sopenharmony_ci    if (kReturnReg != next_result_reg->gp()) {
41121cb0ef41Sopenharmony_ci      Move(*next_result_reg, LiftoffRegister(kReturnReg), sig->GetReturn(0));
41131cb0ef41Sopenharmony_ci    }
41141cb0ef41Sopenharmony_ci    ++next_result_reg;
41151cb0ef41Sopenharmony_ci  }
41161cb0ef41Sopenharmony_ci
41171cb0ef41Sopenharmony_ci  // Load potential output value from the buffer on the stack.
41181cb0ef41Sopenharmony_ci  if (out_argument_kind != kVoid) {
41191cb0ef41Sopenharmony_ci    liftoff::Load(this, *next_result_reg, Operand(rsp, 0), out_argument_kind);
41201cb0ef41Sopenharmony_ci  }
41211cb0ef41Sopenharmony_ci
41221cb0ef41Sopenharmony_ci  addq(rsp, Immediate(stack_bytes));
41231cb0ef41Sopenharmony_ci}
41241cb0ef41Sopenharmony_ci
41251cb0ef41Sopenharmony_civoid LiftoffAssembler::CallNativeWasmCode(Address addr) {
41261cb0ef41Sopenharmony_ci  near_call(addr, RelocInfo::WASM_CALL);
41271cb0ef41Sopenharmony_ci}
41281cb0ef41Sopenharmony_ci
41291cb0ef41Sopenharmony_civoid LiftoffAssembler::TailCallNativeWasmCode(Address addr) {
41301cb0ef41Sopenharmony_ci  near_jmp(addr, RelocInfo::WASM_CALL);
41311cb0ef41Sopenharmony_ci}
41321cb0ef41Sopenharmony_ci
41331cb0ef41Sopenharmony_civoid LiftoffAssembler::CallIndirect(const ValueKindSig* sig,
41341cb0ef41Sopenharmony_ci                                    compiler::CallDescriptor* call_descriptor,
41351cb0ef41Sopenharmony_ci                                    Register target) {
41361cb0ef41Sopenharmony_ci  if (target == no_reg) {
41371cb0ef41Sopenharmony_ci    popq(kScratchRegister);
41381cb0ef41Sopenharmony_ci    target = kScratchRegister;
41391cb0ef41Sopenharmony_ci  }
41401cb0ef41Sopenharmony_ci  call(target);
41411cb0ef41Sopenharmony_ci}
41421cb0ef41Sopenharmony_ci
41431cb0ef41Sopenharmony_civoid LiftoffAssembler::TailCallIndirect(Register target) {
41441cb0ef41Sopenharmony_ci  if (target == no_reg) {
41451cb0ef41Sopenharmony_ci    popq(kScratchRegister);
41461cb0ef41Sopenharmony_ci    target = kScratchRegister;
41471cb0ef41Sopenharmony_ci  }
41481cb0ef41Sopenharmony_ci  jmp(target);
41491cb0ef41Sopenharmony_ci}
41501cb0ef41Sopenharmony_ci
41511cb0ef41Sopenharmony_civoid LiftoffAssembler::CallRuntimeStub(WasmCode::RuntimeStubId sid) {
41521cb0ef41Sopenharmony_ci  // A direct call to a wasm runtime stub defined in this module.
41531cb0ef41Sopenharmony_ci  // Just encode the stub index. This will be patched at relocation.
41541cb0ef41Sopenharmony_ci  near_call(static_cast<Address>(sid), RelocInfo::WASM_STUB_CALL);
41551cb0ef41Sopenharmony_ci}
41561cb0ef41Sopenharmony_ci
41571cb0ef41Sopenharmony_civoid LiftoffAssembler::AllocateStackSlot(Register addr, uint32_t size) {
41581cb0ef41Sopenharmony_ci  AllocateStackSpace(size);
41591cb0ef41Sopenharmony_ci  movq(addr, rsp);
41601cb0ef41Sopenharmony_ci}
41611cb0ef41Sopenharmony_ci
41621cb0ef41Sopenharmony_civoid LiftoffAssembler::DeallocateStackSlot(uint32_t size) {
41631cb0ef41Sopenharmony_ci  addq(rsp, Immediate(size));
41641cb0ef41Sopenharmony_ci}
41651cb0ef41Sopenharmony_ci
41661cb0ef41Sopenharmony_civoid LiftoffAssembler::MaybeOSR() {
41671cb0ef41Sopenharmony_ci  cmpq(liftoff::GetOSRTargetSlot(), Immediate(0));
41681cb0ef41Sopenharmony_ci  j(not_equal, static_cast<Address>(WasmCode::kWasmOnStackReplace),
41691cb0ef41Sopenharmony_ci    RelocInfo::WASM_STUB_CALL);
41701cb0ef41Sopenharmony_ci}
41711cb0ef41Sopenharmony_ci
41721cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_set_if_nan(Register dst, DoubleRegister src,
41731cb0ef41Sopenharmony_ci                                       ValueKind kind) {
41741cb0ef41Sopenharmony_ci  if (kind == kF32) {
41751cb0ef41Sopenharmony_ci    Ucomiss(src, src);
41761cb0ef41Sopenharmony_ci  } else {
41771cb0ef41Sopenharmony_ci    DCHECK_EQ(kind, kF64);
41781cb0ef41Sopenharmony_ci    Ucomisd(src, src);
41791cb0ef41Sopenharmony_ci  }
41801cb0ef41Sopenharmony_ci  Label ret;
41811cb0ef41Sopenharmony_ci  j(parity_odd, &ret);
41821cb0ef41Sopenharmony_ci  movl(Operand(dst, 0), Immediate(1));
41831cb0ef41Sopenharmony_ci  bind(&ret);
41841cb0ef41Sopenharmony_ci}
41851cb0ef41Sopenharmony_ci
41861cb0ef41Sopenharmony_civoid LiftoffAssembler::emit_s128_set_if_nan(Register dst, LiftoffRegister src,
41871cb0ef41Sopenharmony_ci                                            Register tmp_gp,
41881cb0ef41Sopenharmony_ci                                            LiftoffRegister tmp_s128,
41891cb0ef41Sopenharmony_ci                                            ValueKind lane_kind) {
41901cb0ef41Sopenharmony_ci  if (lane_kind == kF32) {
41911cb0ef41Sopenharmony_ci    movaps(tmp_s128.fp(), src.fp());
41921cb0ef41Sopenharmony_ci    cmpunordps(tmp_s128.fp(), tmp_s128.fp());
41931cb0ef41Sopenharmony_ci  } else {
41941cb0ef41Sopenharmony_ci    DCHECK_EQ(lane_kind, kF64);
41951cb0ef41Sopenharmony_ci    movapd(tmp_s128.fp(), src.fp());
41961cb0ef41Sopenharmony_ci    cmpunordpd(tmp_s128.fp(), tmp_s128.fp());
41971cb0ef41Sopenharmony_ci  }
41981cb0ef41Sopenharmony_ci  pmovmskb(tmp_gp, tmp_s128.fp());
41991cb0ef41Sopenharmony_ci  orl(Operand(dst, 0), tmp_gp);
42001cb0ef41Sopenharmony_ci}
42011cb0ef41Sopenharmony_ci
42021cb0ef41Sopenharmony_civoid LiftoffStackSlots::Construct(int param_slots) {
42031cb0ef41Sopenharmony_ci  DCHECK_LT(0, slots_.size());
42041cb0ef41Sopenharmony_ci  SortInPushOrder();
42051cb0ef41Sopenharmony_ci  int last_stack_slot = param_slots;
42061cb0ef41Sopenharmony_ci  for (auto& slot : slots_) {
42071cb0ef41Sopenharmony_ci    const int stack_slot = slot.dst_slot_;
42081cb0ef41Sopenharmony_ci    int stack_decrement = (last_stack_slot - stack_slot) * kSystemPointerSize;
42091cb0ef41Sopenharmony_ci    last_stack_slot = stack_slot;
42101cb0ef41Sopenharmony_ci    const LiftoffAssembler::VarState& src = slot.src_;
42111cb0ef41Sopenharmony_ci    DCHECK_LT(0, stack_decrement);
42121cb0ef41Sopenharmony_ci    switch (src.loc()) {
42131cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kStack:
42141cb0ef41Sopenharmony_ci        if (src.kind() == kI32) {
42151cb0ef41Sopenharmony_ci          asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize);
42161cb0ef41Sopenharmony_ci          // Load i32 values to a register first to ensure they are zero
42171cb0ef41Sopenharmony_ci          // extended.
42181cb0ef41Sopenharmony_ci          asm_->movl(kScratchRegister, liftoff::GetStackSlot(slot.src_offset_));
42191cb0ef41Sopenharmony_ci          asm_->pushq(kScratchRegister);
42201cb0ef41Sopenharmony_ci        } else if (src.kind() == kS128) {
42211cb0ef41Sopenharmony_ci          asm_->AllocateStackSpace(stack_decrement - kSimd128Size);
42221cb0ef41Sopenharmony_ci          // Since offsets are subtracted from sp, we need a smaller offset to
42231cb0ef41Sopenharmony_ci          // push the top of a s128 value.
42241cb0ef41Sopenharmony_ci          asm_->pushq(liftoff::GetStackSlot(slot.src_offset_ - 8));
42251cb0ef41Sopenharmony_ci          asm_->pushq(liftoff::GetStackSlot(slot.src_offset_));
42261cb0ef41Sopenharmony_ci        } else {
42271cb0ef41Sopenharmony_ci          asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize);
42281cb0ef41Sopenharmony_ci          // For all other types, just push the whole (8-byte) stack slot.
42291cb0ef41Sopenharmony_ci          // This is also ok for f32 values (even though we copy 4 uninitialized
42301cb0ef41Sopenharmony_ci          // bytes), because f32 and f64 values are clearly distinguished in
42311cb0ef41Sopenharmony_ci          // Turbofan, so the uninitialized bytes are never accessed.
42321cb0ef41Sopenharmony_ci          asm_->pushq(liftoff::GetStackSlot(slot.src_offset_));
42331cb0ef41Sopenharmony_ci        }
42341cb0ef41Sopenharmony_ci        break;
42351cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kRegister: {
42361cb0ef41Sopenharmony_ci        int pushed = src.kind() == kS128 ? kSimd128Size : kSystemPointerSize;
42371cb0ef41Sopenharmony_ci        liftoff::push(asm_, src.reg(), src.kind(), stack_decrement - pushed);
42381cb0ef41Sopenharmony_ci        break;
42391cb0ef41Sopenharmony_ci      }
42401cb0ef41Sopenharmony_ci      case LiftoffAssembler::VarState::kIntConst:
42411cb0ef41Sopenharmony_ci        asm_->AllocateStackSpace(stack_decrement - kSystemPointerSize);
42421cb0ef41Sopenharmony_ci        asm_->pushq(Immediate(src.i32_const()));
42431cb0ef41Sopenharmony_ci        break;
42441cb0ef41Sopenharmony_ci    }
42451cb0ef41Sopenharmony_ci  }
42461cb0ef41Sopenharmony_ci}
42471cb0ef41Sopenharmony_ci
42481cb0ef41Sopenharmony_ci#undef RETURN_FALSE_IF_MISSING_CPU_FEATURE
42491cb0ef41Sopenharmony_ci
42501cb0ef41Sopenharmony_ci}  // namespace wasm
42511cb0ef41Sopenharmony_ci}  // namespace internal
42521cb0ef41Sopenharmony_ci}  // namespace v8
42531cb0ef41Sopenharmony_ci
42541cb0ef41Sopenharmony_ci#endif  // V8_WASM_BASELINE_X64_LIFTOFF_ASSEMBLER_X64_H_
4255